다음을 통해 공유


컨테이너용 Application Gateway를 사용한 Cert-manager 및 Let's Encrypt - 게이트웨이 API

이 가이드에서는 cert-manager를 사용하여 컨테이너 배포용 Azure Application Gateway의 하나 이상의 프런트 엔드에 SSL/TLS 인증서를 자동으로 발급하고 갱신하는 방법을 보여 줍니다. 게이트웨이 API를 사용하여 필요한 리소스를 구성합니다.

이 예제의 목적을 위해 컨테이너용 Application Gateway에서 TLS 오프로드를 제공하는 엔드투엔드 배포를 보여 주도록 Let's Encrypt에서 발급된 인증서를 cert-manager가 구성했습니다.

Let's Encrypt에서 인증서를 검색하고 컨테이너용 Application Gateway를 사용하여 TLS용 Kubernetes의 비밀 저장소에 저장하는 인증서 관리자를 보여 주는 다이어그램.

Let's Encrypt에서 인증서를 발급하려면 기관에서 도메인 소유권의 유효성을 검사해야 합니다. 이 유효성 검사는 인증서 관리자가 인증서 발급 중에 엔드포인트를 노출하는 Pod 및 HTTPRoute 리소스를 만들어 도메인 이름의 소유권을 증명하도록 허용하여 발생합니다.

cert-manager 및 Let's Encrypt with AKS에 대한 자세한 내용은 여기에서 확인할수 있습니다.

필수 구성 요소

  1. BYO 배포 전략을 따르는 경우 컨테이너용 Application Gateway 리소스 및 ALB 컨트롤러를 설정했는지 확인합니다.

  2. ALB 관리된 배포 전략을 따르는 경우 ALB 컨트롤러를 프로비전하고 ApplicationLoadBalancer 사용자 지정 리소스를 통해 컨테이너용 Application Gateway 리소스를 프로비전했는지 확인합니다.

  3. 샘플 HTTP 애플리케이션 배포 클러스터에 다음 deployment.yaml 파일을 적용하여 헤더 다시 쓰기를 보여 주는 샘플 웹 애플리케이션을 만듭니다.

    kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/traffic-split-scenario/deployment.yaml
    

    이 명령은 클러스터에 다음을 만듭니다.

    • test-infra라는 네임스페이스
    • backend-v1 네임스페이스에 있는 backend-v2test-infra라는 두 서비스
    • backend-v1 네임스페이스에 있는 backend-v2test-infra라는 두 배포

게이트웨이 리소스 만들기

챌린지 프로세스 중에 Let's Encrypt의 HTTP 요청을 수신 대기하는 새 Gateway 리소스를 만듭니다.

게이트웨이 만들기:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-namespace: alb-test-infra
    alb.networking.azure.io/alb-name: alb-test
    cert-manager.io/issuer: letsencrypt-cert
spec:
  gatewayClassName: azure-alb-external
  listeners:
  - name: http-listener
    protocol: HTTP
    port: 80
    allowedRoutes:
        namespaces:
          from: Same
EOF

참고

ALB 컨트롤러는 Azure Resource Manager에서 컨테이너용 Application Gateway 리소스를 만들 때 프런트 엔드 리소스 fe-<eight randomly generated characters>에 대해 다음 명명 규칙을 사용합니다.

Azure에서 만든 프런트 엔드 리소스의 이름을 변경하려면 사용자 고유의 배포 전략을 따르는 것이 좋습니다.

게이트웨이 리소스가 만들어지면 상태가 유효한지, 수신기가 프로그래밍되어 있는지, 주소가 게이트웨이에 할당되어 있는지 확인합니다.

kubectl get gateway gateway-01 -n test-infra -o yaml

게이트웨이가 성공적으로 만들어진 경우의 출력 예제입니다.

status:
  addresses:
  - type: IPAddress
    value: xxxx.yyyy.alb.azure.com
  conditions:
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Valid Gateway
    observedGeneration: 1
    reason: Accepted
    status: "True"
    type: Accepted
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Application Gateway For Containers resource has been successfully updated.
    observedGeneration: 1
    reason: Programmed
    status: "True"
    type: Programmed
  listeners:
  - attachedRoutes: 0
    conditions:
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Listener is accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    name: https-listener
    supportedKinds:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute

Cert-Manager 설치

Helm을 사용하여 cert-manager를 설치합니다.

helm install \
  cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.19.1 \
  --namespace cert-manager \
  --create-namespace \
  --set config.enableGatewayAPI=true \
  --set crds.enabled=true

Helm 설치는 cert-manager라는 새 네임스페이스에 세 개의 배포와 일부 서비스 및 Pod를 만듭니다. 또한 RBAC 역할 및 사용자 지정 리소스 정의와 같은 클러스터 범위 지원 리소스를 설치합니다.

ClusterIssuer 만들기

ClusterIssuer 리소스를 만들어 cert-manager가 Let's Encrypt와 통신하는 방법을 정의합니다. 이 예제에서는 HTTP 챌린지가 사용됩니다. 챌린지 중에 cert-manager는 HTTPRoute 리소스와 해당 Pod를 생성하여 도메인의 소유권을 증명하기 위한 유효성 검사 엔드포인트를 제공합니다.

Let's Encrypt에서 지원하는 다른 과제는 letsencrypt.org - 챌린지 형식에 설명되어 있습니다.

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: test-infra
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory # production endpoint
    #server: https://acme-staging-v02.api.letsencrypt.org/directory # staging endpoint
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-private-key
    solvers:
      - http01:
          gatewayHTTPRoute:
            parentRefs:
              - name: gateway-01
                namespace: test-infra
                kind: Gateway
EOF

리소스가 만들어졌는지 확인

kubectl get ClusterIssuer -A -o yaml

상태는 True를 표시하고 Ready를 입력해야 합니다.

  status:
    acme:
      lastPrivateKeyHash: x+xxxxxxxxxxxxxxxxxxxxxxx+MY4PAEeotr9XH3V7I=
      lastRegisteredEmail: your-email@example.com
      uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/165888253
    conditions:
    - lastTransitionTime: "2024-10-04T21:22:40Z"
      message: The ACME account was registered with the ACME server
      observedGeneration: 1
      reason: ACMEAccountRegistered
      status: "True"
      type: Ready

인증서 만들기

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: letsencrypt-cert
  namespace: test-infra
spec:
  secretName: letsencrypt-secret # name published to secret store
  issuerRef:
    name: letsencrypt-prod # ClusterIssuer resource name
    kind: ClusterIssuer
  dnsNames:
    - contoso.com # domain name to be used
EOF

다음 명령을 실행하여 인증서 발급의 유효성을 검사합니다. 인증서가 발급된 경우 READY 열 값은 True이어야 합니다.

kubectl get certificate letsencrypt-cert -n test-infra

인증서가 발급되지 않은 경우 다음 명령을 실행하여 챌린지의 상태를 확인할 수 있습니다.

참고

인증서가 성공적으로 발급된 경우 챌린지가 더 이상 나열되지 않습니다.

kubectl get challenges -n test-infra -o yaml

게이트웨이 리소스에서 HTTPS 사용

발급된 Let's Encrypt 인증서를 사용하여 HTTPS 요청을 종료하는 두 번째 수신기를 추가하도록 게이트웨이를 수정합니다.

게이트웨이 만들기:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-namespace: alb-test-infra
    alb.networking.azure.io/alb-name: alb-test
    cert-manager.io/issuer: letsencrypt-cert
spec:
  gatewayClassName: azure-alb-external
  listeners:
  - name: http-listener
    protocol: HTTP
    port: 80
    allowedRoutes:
        namespaces:
          from: Same
  - name: https-listener
    port: 443
    protocol: HTTPS
    tls:
      certificateRefs:
      - name: letsencrypt-secret
    allowedRoutes:
      namespaces:
        from: Same
EOF

참고

ALB 컨트롤러는 Azure Resource Manager에서 컨테이너용 Application Gateway 리소스를 만들 때 프런트 엔드 리소스 fe-<eight randomly generated characters>에 대해 다음 명명 규칙을 사용합니다.

Azure에서 만든 프런트 엔드 리소스의 이름을 변경하려면 사용자 고유의 배포 전략을 따르는 것이 좋습니다.

호스트 이름을 수신 대기하는 HTTPRoute 만들기

수신기에서 받은 요청을 처리하는 HTTPRoute를 https-listener 만듭니다.

중요

contoso.com을(를) 인증서가 발급될 것으로 예상되는 도메인 이름으로 바꿔야 합니다.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-example
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
  hostnames:
  - "contoso.com"
  rules:
  - backendRefs:
    - name: backend-v1
      port: 8080
EOF

HTTPRoute 리소스가 만들어지면 경로가 수락됨 상태이고 컨테이너용 Application Gateway 리소스가 프로그래밍됨 상태인지 확인합니다.

kubectl get httproute cert-manager-route -n test-infra -o yaml

컨테이너용 Application Gateway 리소스의 상태가 성공적으로 업데이트되었는지 확인합니다.

status:
  parents:
  - conditions:
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Route is Accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    controllerName: alb.networking.azure.io/alb-controller
    parentRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: gateway-01
      namespace: test-infra

애플리케이션에 대한 액세스 테스트

이제 인증서에 사용되는 호스트 이름을 통해 샘플 애플리케이션에 일부 트래픽을 보낼 준비가 되었습니다.

중요

인증서가 발급될 것으로 예상되는 도메인 이름으로 contoso.com 를 바꾸세요.

curl https://contoso.com/ -v 2>&1 | grep issuer

다음과 같은 출력이 표시됩니다.

* issuer: C=US; O=Let's Encrypt; CN=R10

축하합니다. ALB 컨트롤러를 설치하고, 백 엔드 애플리케이션을 배포하고, 인증서 관리자를 사용하여 Let's Encrypt에서 인증서를 발급했으며, 컨테이너용 Application Gateway를 통해 애플리케이션으로 트래픽을 라우팅했습니다.