다음을 통해 공유


컨테이너용 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 및 수신 리소스를 만들어 도메인 이름의 소유권을 증명하도록 허용하여 발생합니다.

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라는 두 배포

Cert-Manager 설치

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

helm repo add jetstack https://charts.jetstack.io --force-update
helm upgrade -i \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.17.1 \
  --set installCRDs=true

ClusterIssuer 만들기

cert-manager가 Let's Encrypt와 통신하는 방법을 정의하기 위해 ClusterIssuer 리소스를 만듭니다. 이 예제에서는 HTTP 챌린지가 사용됩니다. 챌린지 중에 cert-manager는 Ingress 리소스와 해당 Pod를 생성하여 도메인의 소유권을 증명하기 위한 유효성 검사 엔드포인트를 제공합니다. 이 작업은 http01 챌린지 유형으로 임시 수신 리소스를 만들어 수행됩니다. cert-manager가 만든 이 수신 리소스와 해당 Pod는 챌린지가 완료된 후 삭제됩니다.

팁 (조언)

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

ClusterIssuer 리소스 만들기

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
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:
            ingress:
              ingressClassName: azure-alb-external
              # This section is required for the Ingress resource created by cert-manager during the challenge
              ingressTemplate:
                metadata:
                  annotations:
                    alb.networking.azure.io/alb-name: alb-test
                    alb.networking.azure.io/alb-namespace: alb-test-infra
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/190567584
    conditions:
    - lastTransitionTime: "2025-03-20T16:00:21Z"
      message: The ACME account was registered with the ACME server
      observedGeneration: 1
      reason: ACMEAccountRegistered
      status: "True"
      type: Ready

필수 수신 리소스 배포

수신 만들기

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-name: alb-test
    alb.networking.azure.io/alb-namespace: alb-test-infra
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: azure-alb-external
  tls:
  - hosts:
    - backend-v1.contoso.com
    # - backend-v2.contoso.com # You can uncomment this and the host line to add an additional subject alternate name (SAN) to the certificate
    secretName: tls-backend
  rules:
    - host: backend-v1.contoso.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: backend-v1
                port:
                  number: 8080
    # - host: backend-v2.contoso.com
    #   http:
    #     paths:
    #       - path: /
    #         pathType: Prefix
    #         backend:
    #           service:
    #             name: backend-v2
    #             port:
    #               number: 8080
EOF

수신 리소스가 만들어지면 상태에 부하 분산 장치의 호스트 이름이 표시되는지 확인합니다.

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

수신이 성공적으로 만들어진 출력의 예제입니다.

status:
  loadBalancer:
    ingress:
    - hostname: xxxxxxxxxxxxxxxx.fz13.alb.azure.com
      ports:
      - port: 443
        protocol: TCP

이전에 언급했듯이 cert-manager는 임시 수신 리소스와 Pod를 만들어 챌린지를 수행합니다.

kubectl get pods -n test-infra
NAME                          READY   STATUS    RESTARTS   AGE
backend-v1-56d99ddb49-mwmcc   1/1     Running   0          10m
backend-v2-8b5d4679b-rsfrg    1/1     Running   0          10m
cm-acme-http-solver-5lmmv     1/1     Running   0          2s

kubectl get ingress -n test-infra
NAME                        CLASS                HOSTS                         ADDRESS                               PORTS     AGE
cm-acme-http-solver-zrp47   azure-alb-external   backend-v1.contoso.com        xxxxxxxxxxxxxxxx.fz13.alb.azure.com   80        8s
ingress-01                  azure-alb-external   backend-v1.contoso.com        xxxxxxxxxxxxxxxx.fz13.alb.azure.com   80, 443   10s

다음을 실행하여 챌린지 상태를 확인할 수 있습니다.

kubectl get challenges.acme.cert-manager.io -n test-infra
NAME                                   STATE     DOMAIN                        AGE
cert-backend-1-2982214480-3407407859   pending   backend-v1.contoso.com        16s

kubectl get certificaterequests.cert-manager.io -n test-infra
NAME             APPROVED   DENIED   READY   ISSUER              REQUESTER                                         AGE
cert-backend-1   True                False   letsencrypt-prod    system:serviceaccount:cert-manager:cert-manager   34s

챌린지가 성공하면 상태가 READY=True로 변경되고 인증서가 발급됩니다.

kubectl get certificate -n test-infra
NAME           READY   SECRET         AGE
cert-backend   True    cert-backend   1m

팁 (조언)

외부 DNS워크로드 ID를 활용하여 AKS에서 만들어진 수신 리소스의 호스트 이름을 Azure DNS 영역과 자동으로 동기화할 수 있습니다.

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

이제 인증서와 연결된 호스트 이름을 사용하여 샘플 애플리케이션으로 트래픽을 라우팅하도록 환경이 구성되었습니다.

중요합니다

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

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

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

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

ALB 컨트롤러를 성공적으로 설치하고, 백 엔드 애플리케이션을 배포하고, cert-manager를 사용하여 Let's Encrypt에서 인증서를 가져왔으며, 컨테이너용 Application Gateway를 통해 애플리케이션으로의 트래픽 라우팅을 구성했습니다.