次の方法で共有


Application Gateway for Containers での cert-manager と Let's Encrypt - Gateway API

このガイドでは、Azure Application Gateway for Containers デプロイの 1 つ以上のフロントエンドに対して、cert-manager を使用して SSL/TLS 証明書の発行と更新を自動的に行う方法について説明します。 Gateway API を使用して、必要なリソースを構成します。

この例では、Application Gateway for Containers が TLS オフロードを提供しているエンドツーエンドのデプロイを示すために、Let's Encrypt から発行された証明書を cert-manager で構成しています。

Let's Encrypt から証明書を取得し、Application Gateway for Containers を使用して TLS 用 Kubernetes のシークレット ストアに格納する cert-manager を示す図。

Let's Encrypt によって発行される証明書の場合、ドメインの所有権を検証するために、証明機関によってチャレンジが要求されます。 この検証は、証明書の発行時にエンドポイントを公開するポッドと HTTPRoute リソースを cert-manager が作成できるようにすることで行われ、ドメイン名の所有権が証明されます。

AKS での cert-manager と Let's Encrypt 全般の詳細については、こちらを参照してください。

前提条件

  1. BYO デプロイ戦略に従う場合は、Application Gateway for Containers リソースと ALB コントローラーを設定していることを確かめます

  2. ALB マネージド デプロイ戦略に従う場合は、ALB コントローラーと、ApplicationLoadBalancer カスタム リソースを介した Application Gateway for Containers リソースのプロビジョニングが完了していることを確かめます。

  3. サンプル HTTP アプリケーションをデプロイします。クラスターに次の deployment.yaml ファイルを適用して、ヘッダーの書き換えのデモンストレーションを行うためのサンプル Web アプリケーションを作成します。

    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 と呼ばれる名前空間
    • test-infra 名前空間の backend-v1 および backend-v2 と呼ばれる 2 つのサービス
    • test-infra 名前空間の backend-v1 および backend-v2 と呼ばれる 2 つのデプロイ

ゲートウェイ リソースを作成する

チャレンジ プロセス中に 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 コントローラーでは、ARM で Application Gateway for Containers リソースを作成するときに、フロントエンド リソースに対して次の名前付け規則を使用します。fe-<ランダムに生成された 8 文字>

Azure で作成されたフロントエンドの名前を変更したい場合は、BYO デプロイ戦略に従うことを検討してください。

ゲートウェイ リソースが作成されたら、状態が有効であること、リスナーが [プログラム済み] であること、ゲートウェイにアドレスが割り当てられていることを確かめます。

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 repo add jetstack https://charts.jetstack.io --force-update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.17.1 \
  --set config.enableGatewayAPI=true \
  --set crds.enabled=true

Helm によるインストールでは、cert-manager という新しい名前空間に 3 つのデプロイと、いくつかのサービスとポッドが作成されます。 また、RBAC ロールやカスタム リソース定義など、クラスター スコープのサポート リソースもインストールされます。

ClusterIssuer を作成する

ClusterIssuer リソースを作成して、cert-manager が Let's Encrypt と通信する方法を定義します。 この例では、HTTP チャレンジが使用されます。 チャレンジ中に、cert-manager では、ドメインの所有権を証明するための検証エンドポイントを提示する HTTPRoute リソースおよび対応するポッドが作成されます。

ヒント

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 要求を終了するために 2 番目のリスナーを追加します。

ゲートウェイの作成:

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 コントローラーでは、ARM で Application Gateway for Containers リソースを作成するときに、フロントエンド リソースに対して次の名前付け規則を使用します。fe-<ランダムに生成された 8 文字>

Azure で作成されたフロントエンドの名前を変更したい場合は、BYO デプロイ戦略に従うことを検討してください。

ホスト名をリッスンする HTTPRoute を作成する

https-listener リスナーが受信した要求を処理する HTTPRoute を作成します。

重要

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 for Containers リソースが [プログラム済み] になっていることを確かめます。

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

Application Gateway for Containers リソースの状態が正常に更新されたことを確認します。

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 コントローラーをインストールしてバックエンド アプリケーションをデプロイし、cert-manager で Let's Encrypt から証明書を発行し、Application Gateway for Containers 経由でアプリケーションにトラフィックをルーティングしました。