Condividi tramite


Cert-manager e Let's Encrypt with gateway applicazione for Containers - API Gateway

Questa guida illustra come usare cert-manager per rilasciare e rinnovare automaticamente i certificati SSL/TLS a uno o più front-end del gateway di app Azure lication per la distribuzione dei contenitori. L'API gateway viene usata per configurare le risorse necessarie.

Ai fini di questo esempio, sono disponibili certificati cert-manager configurati da Let's Encrypt per illustrare una distribuzione end-to-end, in cui gateway applicazione per i contenitori fornisce l'offload TLS.

Figura che mostra il recupero di un certificato da Let's Encrypt e l'archiviazione nell'archivio dei segreti di Kubernetes per TLS con gateway applicazione per contenitori.

Affinché i certificati vengano rilasciati da Let's Encrypt, è richiesta una richiesta dall'autorità per convalidare la proprietà del dominio. Questa convalida avviene consentendo a cert-manager di creare un pod e una risorsa HTTPRoute che espone un endpoint durante il rilascio del certificato, dimostrando la proprietà del nome di dominio.

Altre informazioni su cert-manager e Let's Encrypt with AKS in generale sono disponibili qui.

Prerequisiti

  1. Se si segue la strategia di distribuzione personalizzata (Bring Your Own Deployment), assicurarsi di aver configurato le risorse Gateway applicativo per contenitori e il controller ALB

  2. Se si segue la strategia di distribuzione gestita di ALB, assicurarsi di aver effettuato il provisioning del controller ALB e delle risorse Gateway applicativo per contenitori tramite la risorsa personalizzata ApplicationLoadBalancer.

  3. Distribuire l'applicazione HTTP di esempio Applicare il file deployment.yaml seguente nel cluster per creare un'applicazione Web di esempio per illustrare la riscrittura delle intestazioni.

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

    Questo comando crea gli elementi seguenti nel cluster:

    • uno spazio dei nomi denominato test-infra
    • due servizi denominati backend-v1 e backend-v2 nello spazio dei nomi test-infra
    • due distribuzioni denominate backend-v1 e backend-v2 nello spazio dei nomi test-infra

Creare una risorsa gateway

Creare una nuova Gateway risorsa in ascolto delle richieste HTTP da Let's Encrypt durante il processo di verifica.

Creare un 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

Nota

Quando il Controller ALB crea le risorse Gateway applicativo per contenitori in ARM, userà la convenzione di denominazione seguente per una risorsa front-end: fe-<8 caratteri generati in modo casuale>

Se si vuole modificare il nome del front-end creato in Azure, valutare la possibilità di seguire la strategia di distribuzione personalizzata (Bring Your Own Deployment).

Dopo aver creato la risorsa gateway, verificare che lo stato sia valido, che il listener sia programmato e che al gateway sia assegnato un indirizzo.

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

Output di esempio della corretta creazione del gateway.

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

Installare Cert-Manager

Installare cert-manager con Helm:

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

L'installazione helm crea tre distribuzioni e alcuni servizi e pod in un nuovo spazio dei nomi denominato cert-manager. Vengono installate anche risorse di supporto con ambito cluster, ad esempio ruoli controllo degli accessi in base al ruolo e definizioni di risorse personalizzate.

Creare un clusterIssuer

Creare una risorsa ClusterIssuer per definire il modo in cui cert-manager comunicherà con Let's Encrypt. Per questo esempio viene usata una richiesta HTTP. Durante la verifica, cert-manager crea una HTTPRoute risorsa e un pod corrispondente che presenta un endpoint di convalida per dimostrare la proprietà del dominio.

Suggerimento

Altre sfide supportate da Let's Encrypt sono documentate in letsencrypt.org - Tipi di verifica

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

Verificare che la risorsa sia stata creata

kubectl get ClusterIssuer -A -o yaml

Lo stato deve visualizzare True e digitare 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

Creare un certificato

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

Eseguire il comando seguente per convalidare il rilascio del certificato. Se il certificato è stato emesso, il valore della READY colonna deve essere True.

kubectl get certificate letsencrypt-cert -n test-infra

Se il certificato non è stato emesso, è possibile eseguire il comando seguente per convalidare lo stato di una richiesta di verifica.

Nota

Se il certificato è stato emesso correttamente, la richiesta di verifica non verrà più elencata.

kubectl get challenges -n test-infra -o yaml

Abilitare HTTPS nella risorsa gateway

Modificare il gateway per aggiungere un secondo listener per terminare le richieste HTTPS con il certificato Let's Encrypt rilasciato.

Creare un 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
  - name: https-listener
    port: 443
    protocol: HTTPS
    tls:
      certificateRefs:
      - name: letsencrypt-secret
    allowedRoutes:
      namespaces:
        from: Same
EOF

Nota

Quando il Controller ALB crea le risorse Gateway applicativo per contenitori in ARM, userà la convenzione di denominazione seguente per una risorsa front-end: fe-<8 caratteri generati in modo casuale>

Se si vuole modificare il nome del front-end creato in Azure, valutare la possibilità di seguire la strategia di distribuzione personalizzata (Bring Your Own Deployment).

Creare un HTTPRoute in ascolto del nome host

Creare un HTTPRoute per gestire le richieste ricevute dal https-listener listener.

Importante

Assicurarsi di sostituire contoso.com con il nome di dominio a cui si prevede di emettere il certificato.

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

Dopo aver creato la risorsa HTTPRoute, verificare che la route sia accettata e che lo stato della risorsa Gateway applicativo per contenitori sia programmato.

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

Verificare che lo stato della risorsa del Gateway applicativo per contenitori sia stato aggiornato correttamente.

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

Testare l'accesso all'applicazione

A questo punto è possibile inviare traffico all'applicazione di esempio tramite il nome host usato per il certificato.

Importante

Assicurarsi di sostituire contoso.com con il nome di dominio a cui si prevede di emettere il certificato.

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

Al termine, dovrebbe essere visualizzato

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

Il controller ALB è stato installato, è stata distribuita un'applicazione back-end, è stato rilasciato un certificato da Let's Encrypt with cert-manager e il traffico indirizzato all'applicazione tramite gateway applicazione per contenitori.