Utiliser TLS avec un contrôleur d’entrée sur Azure Kubernetes Service (AKS)

Le protocole TLS (Transport Layer Security) utilise des certificats pour assurer la sécurité de la communication, du chiffrement, de l’authentification et de l’intégrité. L’utilisation du protocole TLS avec un contrôleur d’entrée sur AKS vous permet de sécuriser la communication entre vos applications et de bénéficier des avantages d’un contrôleur d’entrée.

Vous pouvez apporter vos propres certificats et les intégrer au pilote CSI du magasin des secrets. Vous pouvez aussi utiliser cert-manager, qui génère et configure automatiquement des certificats Let’s Encrypt. Deux applications s’exécutent dans le cluster AKS, chacune étant accessible par la biais d’une seule adresse IP.

Important

Nous recommandons le module complémentaire de routage d’applications pour l’entrée dans AKS. Pour obtenir plus d’informations, consultez Entrée NGINX managée avec le module complémentaire de routage d’applications.

Important

Microsoft ne gère ni ne prend en charge le gestionnaire de certificats (cert-manager) ni les problèmes liés à son utilisation. Pour plus d’informations sur les problèmes liés au gestionnaire de certificats, consultez la documentation sur la résolution des problèmes du gestionnaire de certificats.

Il existe deux contrôleurs d’entrée open source pour Kubernetes basés sur Nginx : un est tenu à jour par la communauté Kubernetes (kubernetes/ingress-nginx) et l’autre par NGINX, Inc. (nginxinc/kubernetes-ingress). Cet article utilise le contrôleur d’entrée de la communauté Kubernetes.

Avant de commencer

  • Cet article suppose également que vous disposez d’un contrôleur d’entrée et d’applications configurés. Si vous avez besoin d’un contrôleur d’entrée ou d’un exemple d’applications, consultez Créer un contrôleur d’entrée.

  • Cet article utilise Helm 3 pour installer le contrôleur d’entrée Nginx sur une version prise en charge de Kubernetes. Vérifiez que vous utilisez la version la plus récente de Helm et que vous avez accès aux dépôts Helm ingress-nginx et jetstack. Les étapes décrites dans cet article peuvent ne pas être compatibles avec les versions précédentes du Helm Chart, NGINX Ingres Controller ou Kubernetes.

  • Cet article suppose que vous disposez d’un cluster AKS existant avec un ACR (Azure Container Registry) intégré. Pour plus d’informations sur la création d’un cluster AKS avec un ACR intégré, consultez S’authentifier avec ACR à partir d’AKS.

  • Si vous utilisez Azure CLI, cet article nécessite que vous exécutiez Azure CLI version 2.0.64 ou ultérieure. Exécutez az --version pour trouver la version. Si vous devez installer ou mettre à niveau, voir Installer Azure CLI.

  • Si vous utilisez Azure PowerShell, cet article nécessite que vous exécutiez Azure PowerShell version 5.9.0 ou ultérieure. Exécutez Get-InstalledModule -Name Az pour trouver la version. Si vous avez besoin de procéder à une installation ou à une mise à niveau, consultez Installer Azure PowerShell.

Utiliser TLS avec vos propres certificats avec le pilote CSI du magasin des secrets

Pour utiliser TLS avec vos propres certificats avec le pilote CSI du magasin de secrets, vous avez besoin d’un cluster AKS avec le pilote CSI du magasin des secrets configuré et d’une instance Azure Key Vault.

Pour plus d’informations, consultez Configurer le pilote CSI du magasin des secrets pour activer le contrôleur d’entrée NGINX avec TLS.

Utiliser TLS avec des certificats Let’s Encrypt

Pour utiliser TLS avec des certificats Let’s Encrypt, vous allez déployer cert-manager, qui génère et configure automatiquement des certificats Let’s Encrypt.

Importer les images du gestionnaire de certificats utilisées par le chart Helm dans votre ACR

  • Utilisez az acr import pour importer les images suivantes dans votre ACR.

    REGISTRY_NAME=<REGISTRY_NAME>
    CERT_MANAGER_REGISTRY=quay.io
    CERT_MANAGER_TAG=v1.8.0
    CERT_MANAGER_IMAGE_CONTROLLER=jetstack/cert-manager-controller
    CERT_MANAGER_IMAGE_WEBHOOK=jetstack/cert-manager-webhook
    CERT_MANAGER_IMAGE_CAINJECTOR=jetstack/cert-manager-cainjector
    
    az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG
    az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG
    az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG
    

Remarque

Vous pouvez également importer des graphiques Helm dans votre ACR. Pour plus d’informations, consultez Envoyer (push) et tirer (pull) des graphiques Helm vers un ACR.

Options de configuration du contrôleur d’entrée

Vous pouvez configurer votre contrôleur d’entrée NGINX à l’aide d’une adresse IP publique statique ou d’une adresse IP publique dynamique. Si vous utilisez un domaine personnalisé, vous avez besoin d’ajouter un enregistrement A à votre zone DNS. Si vous n’utilisez pas de domaine personnalisé, vous pouvez configurer un nom de domaine complet (FQDN) pour l’adresse IP du contrôleur d’entrée.

Créer une adresse IP publique statique ou dynamique

Utiliser une adresse IP publique statique

Vous pouvez configurer votre contrôleur d’entrée avec une adresse IP publique statique. L’adresse IP publique statique reste si vous supprimez votre contrôleur d’entrée. L’adresse IP ne reste pas si vous supprimez votre cluster AKS.

Lorsque vous mettez à niveau votre contrôleur d’entrée, vous devez passer un paramètre à la version Helm pour vous assurer que le service du contrôleur d’entrée est informé de l’équilibreur de charge qui lui sera alloué. Pour que les certificats HTTPS fonctionnent correctement, vous utilisez une étiquette DNS pour configurer un FQDN pour l'adresse IP du contrôleur d'entrée.

  1. Obtenez le nom du groupe de ressources du cluster AKS avec la commande az aks show.

    az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
    
  2. Créez une adresse IP publique avec la méthode d’allocation statique à l’aide de la commande az network public-ip create. L’exemple suivant crée une adresse IP publique nommée myAKSPublicIP dans le groupe de ressources du cluster AKS obtenu à l’étape précédente.

    az network public-ip create --resource-group MC_myResourceGroup_myAKSCluster_eastus --name myAKSPublicIP --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv
    

Notes

Vous pouvez également créer une adresse IP dans un autre groupe de ressources qui peut être géré séparément de votre cluster AKS. Si vous créez une adresse IP dans un autre groupe de ressources, vérifiez que les conditions suivantes sont remplies :

  • L'identité de cluster utilisée par le cluster AKS dispose d’autorisations déléguées au groupe de ressources, comme Contributeur réseau.
  • Ajoutez le paramètre --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>". Remplacez <RESOURCE_GROUP> par le nom du groupe de ressources où réside l'adresse IP.
  1. Ajoutez le paramètre --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>". L’étiquette DNS peut être définie lors du premier déploiement du contrôleur d’entrée ou être configuré ultérieurement.

  2. Ajoutez le paramètre --set controller.service.loadBalancerIP="<STATIC_IP>". Spécifiez votre propre adresse IP publique, créée à l’étape précédente.

    DNS_LABEL="<DNS_LABEL>"
    NAMESPACE="ingress-basic"
    STATIC_IP=<STATIC_IP>
    
    helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
      --namespace $NAMESPACE \
      --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNS_LABEL \
      --set controller.service.loadBalancerIP=$STATIC_IP \
      --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
    

Pour plus d’informations, consultez Utiliser une adresse IP publique statique et une étiquette DNS avec l’équilibreur de charge AKS.

Utiliser une adresse IP publique dynamique

Une adresse IP publique Azure est créée pour votre contrôleur d’entrée lors de sa création. Cette adresse IP publique est statique pendant la durée de vie de votre contrôleur d’entrée. L’adresse IP publique ne reste pas si vous supprimez votre contrôleur d’entrée. Si vous créez un contrôleur d’entrée, une nouvelle adresse IP publique lui est attribuée. Vous devez obtenir un résultat semblable à l’exemple de sortie qui suit.

  • Utilisez la commande kubectl get servicepour obtenir l’adresse IP publique de votre contrôleur d’entrée.

    # Get the public IP address for your ingress controller
    
    kubectl --namespace ingress-basic get services -o wide -w nginx-ingress-ingress-nginx-controller
    
    # Sample output
    
    NAME                                     TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
    nginx-ingress-ingress-nginx-controller   LoadBalancer   10.0.74.133   EXTERNAL_IP     80:32486/TCP,443:30953/TCP   44s   app.kubernetes.io/component=controller,app.kubernetes.io/instance=nginx-ingress,app.kubernetes.io/name=ingress-nginx
    

Ajouter un enregistrement A à votre zone DNS

Si vous utilisez un domaine personnalisé, vous avez besoin d’ajouter un enregistrement A à votre zone DNS. Si vous n’utilisez pas de domaine personnalisé, vous pouvez configurer l’adresse IP publique avec un nom de domaine complet.

  • Ajoutez un enregistrement A à votre zone DNS avec l’adresse IP externe du service NGINX à l’aide de az network dns record-set a add-record.

    az network dns record-set a add-record \
        --resource-group myResourceGroup \
        --zone-name MY_CUSTOM_DOMAIN \
        --record-set-name "*" \
        --ipv4-address MY_EXTERNAL_IP
    

Configurer un nom de domaine complet pour votre contrôleur d’entrée

Si vous le souhaitez, vous pouvez configurer un nom de domaine complet pour l’adresse IP du contrôleur d’entrée au lieu d’un domaine personnalisé par une étiquette DNS. Votre nom de domaine complet doit suivre la forme suivante : <CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com.

Important

Votre étiquette DNS doit être unique dans son emplacement Azure.

Vous pouvez configurer votre FQDN en utilisant l’une des méthodes suivantes :

  • Définition de l’étiquette DNS en utilisant Azure CLI ou Azure PowerShell.
  • Définition de l’étiquette DNS à l’aide des paramètres du chart Helm.

Pour plus d’informations, consultez Étiquettes de nom DNS d’adresse IP publique.

Définition de l’étiquette DNS en utilisant Azure CLI ou Azure PowerShell

Veillez à remplacer <DNS_LABEL> par votre étiquette DNS unique.

# Public IP address of your ingress controller
IP="MY_EXTERNAL_IP"

# Name to associate with public IP address
DNSLABEL="<DNS_LABEL>"

# Get the resource-id of the public IP
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)

# Update public IP address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSLABEL

# Display the FQDN
az network public-ip show --ids $PUBLICIPID --query "[dnsSettings.fqdn]" --output tsv

Définition de l’étiquette DNS à l’aide des paramètres du chart Helm

Vous pouvez transmettre un paramètre d'annotation à la configuration de votre graphique Helm en utilisant le paramètre--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name". Ce paramètre peut être défini lors du premier déploiement du contrôleur d’entrée ou être configuré ultérieurement.

L’exemple suivant montre comment mettre à jour ce paramètre après le déploiement du contrôleur. Veillez à remplacer <DNS_LABEL> par votre étiquette DNS unique.

DNSLABEL="<DNS_LABEL>"
NAMESPACE="ingress-basic"

helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace $NAMESPACE \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNSLABEL \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz

Installer cert-manager

Le contrôleur d’entrée NGINX prend en charge l’arrêt TLS. Il existe plusieurs façons de récupérer et de configurer des certificats pour le protocole HTTPS. Cet article utilise cert-manager, qui permet de générer et gérer automatiquement des certificats Let’s Encrypt.

Pour installer le contrôleur cert-manager, utilisez les commandes suivantes.

# Set variable for ACR location to use for pulling images
ACR_URL=<REGISTRY_URL>

# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress-basic cert-manager.io/disable-validation=true

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
  --namespace ingress-basic \
  --version=$CERT_MANAGER_TAG \
  --set installCRDs=true \
  --set nodeSelector."kubernetes\.io/os"=linux \
  --set image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CONTROLLER \
  --set image.tag=$CERT_MANAGER_TAG \
  --set webhook.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_WEBHOOK \
  --set webhook.image.tag=$CERT_MANAGER_TAG \
  --set cainjector.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CAINJECTOR \
  --set cainjector.image.tag=$CERT_MANAGER_TAG

Pour plus d’informations sur la configuration cert-manager, voir le projet cert-manager.

Créer un émetteur de cluster d’autorité de certification

Pour pouvoir émettre des certificats, cert-manager a besoin de l’un des émetteurs suivants :

  • Un émetteur, qui fonctionne dans un espace de noms unique.
  • Une ressource ClusterIssuer, qui fonctionne dans tous les espaces de noms.

Pour plus d’informations, voir la documentation de l’émetteur cert-manager.

  1. Créez un émetteur de cluster, tel que cluster-issuer.yaml, avec l’exemple de manifeste suivant. Remplacez MY_EMAIL_ADDRESS par une adresse valide de votre organisation.

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: MY_EMAIL_ADDRESS
        privateKeySecretRef:
          name: letsencrypt
        solvers:
        - http01:
            ingress:
              class: nginx
              podTemplate:
                spec:
                  nodeSelector:
                    "kubernetes.io/os": linux
    
  2. Appliquez l’émetteur à l’aide de la commande kubectl apply.

    kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
    

Mettre à jour vos routes d’entrée

Vous avez besoin de mettre à jour vos routes d’entrée pour gérer le trafic vers votre nom de domaine complet ou votre domaine personnalisé.

Dans l’exemple suivant, le trafic est routé ainsi :

  • Le trafic vers hello-world-ingress.MY_CUSTOM_DOMAIN est routé vers le service aks-helloworld-one.
  • Le trafic vers hello-world-ingress.MY_CUSTOM_DOMAIN/hello-world-two est routé vers le service aks-helloworld-two.
  • Le trafic vers hello-world-ingress.MY_CUSTOM_DOMAIN/static est acheminé vers le service nommé aks-helloworld-one pour les ressources statiques.

Notes

Si vous avez configuré un nom de domaine complet pour l’adresse IP du contrôleur d’entrée au lieu d’un domaine personnalisé, utilisez le nom de domaine complet au lieu de hello-world-ingress.MY_CUSTOM_DOMAIN.

Par exemple, si votre nom de domaine complet est demo-aks-ingress.eastus.cloudapp.azure.com, remplacez hello-world-ingress.MY_CUSTOM_DOMAIN par demo-aks-ingress.eastus.cloudapp.azure.com dans hello-world-ingress.yaml.

  1. Créez ou mettez à jour le fichier hello-world-ingress.yaml à l’aide de l’exemple de fichier YAML suivant. Mettez à jour les valeurs de spec.tls.hosts et de spec.rules.host avec le nom DNS que vous avez créé à l’étape précédente.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
        nginx.ingress.kubernetes.io/use-regex: "true"
        cert-manager.io/cluster-issuer: letsencrypt
    spec:
      ingressClassName: nginx
      tls:
      - hosts:
        - hello-world-ingress.MY_CUSTOM_DOMAIN
        secretName: tls-secret
      rules:
      - host: hello-world-ingress.MY_CUSTOM_DOMAIN
        http:
          paths:
          - path: /hello-world-one(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port:
                  number: 80
          - path: /hello-world-two(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-two
                port:
                  number: 80
          - path: /(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port:
                  number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ingress-static
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/rewrite-target: /static/$2
    spec:
      ingressClassName: nginx
      tls:
      - hosts:
        - hello-world-ingress.MY_CUSTOM_DOMAIN
        secretName: tls-secret
      rules:
      - host: hello-world-ingress.MY_CUSTOM_DOMAIN
        http:
          paths:
          - path: /static(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port:
                  number: 80
    
  2. Mettez à jour la ressource d’entrée en utilisant la commande kubectl apply.

    kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
    

Vérifier qu’un objet de certificat a été créé

Il faut ensuite créer une ressource de certificat. Elle définit le certificat X.509 souhaité. Pour plus d’informations, consultez Certificats cert-manager.

cert-manager crée automatiquement un objet de certificat à l’aide d’ingress-shim ; le certificat est automatiquement déployé avec cert-manager depuis la version 0.2.2. Pour plus d’informations, consultez la documentation d’ingress-shim.

Pour vérifier que le certificat a été correctement créé, utilisez la commande kubectl get certificate --namespace ingress-basic et vérifiez que READY a la valeur True. L’obtention de la sortie peut prendre plusieurs minutes.

kubectl get certificate --namespace ingress-basic

La sortie suivante indique l’état du certificat.

NAME         READY   SECRET       AGE
tls-secret   True    tls-secret   11m

Tester la configuration d’entrée

Ouvrez un navigateur web sur hello-world-ingress.MON_DOMAINE_PERSONNALISÉ ou sur le nom de domaine complet de votre contrôleur d’entrée Kubernetes. Vérifiez que les conditions suivantes sont remplies :

  • Vous êtes redirigé vers une utilisation de HTTPS.
  • Le certificat est approuvé.
  • L’application de démonstration s’affiche dans le navigateur web.
  • Ajoutez /hello-world-two à la fin du domaine et vérifiez que la seconde application de démonstration s’affiche avec le titre personnalisé.

Nettoyer les ressources

Cet article vous a montré comment utiliser Helm pour installer les composants d’entrée, les certificats et les exemples d’applications. Quand vous déployez un chart Helm, plusieurs ressources Kubernetes sont créées. Ces ressources incluent des pods, des déploiements et des services. Pour nettoyer ces ressources, vous pouvez supprimer l’exemple d’espace de noms dans son ensemble ou des ressources individuelles.

Supprimer l’espace de noms exemple et toutes les ressources

La suppression de l’exemple d’espace de noms supprime également toutes ses ressources.

  • Supprimez l’espace de noms exemple en entier en utilisant la commande kubectl delete et en spécifiant le nom de votre espace de noms.

    kubectl delete namespace ingress-basic
    

Supprimer les ressources individuellement

Vous pouvez également supprimer la ressource individuellement.

  1. Supprimez les ressources de l’émetteur de cluster.

    kubectl delete -f cluster-issuer.yaml --namespace ingress-basic
    
  2. Listez les versions de Helm avec la commande helm list. Recherchez les charts nommés nginx et cert-manager, comme illustré dans l’exemple de sortie suivant.

    $ helm list --namespace ingress-basic
    
    NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
    cert-manager            ingress-basic   1               2020-01-15 10:23:36.515514 -0600 CST    deployed        cert-manager-v0.13.0    v0.13.0
    nginx                   ingress-basic   1               2020-01-15 10:09:45.982693 -0600 CST    deployed        nginx-ingress-1.29.1    0.27.0
    
  3. Désinstallez les versions avec la commande helm uninstall. L’exemple suivant désinstalle les déploiements d’entrée et de gestionnaire de certificats NGINX.

    $ helm uninstall cert-manager nginx --namespace ingress-basic
    
    release "cert-manager" uninstalled
    release "nginx" uninstalled
    
  4. Supprimez les deux exemples d’applications.

    kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic
    kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
    
  5. Supprimez la route d’entrée qui a dirigé le trafic vers les exemples d’applications.

    kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
    
  6. Supprimez l’espace de noms lui-même. Utilisez la commande kubectl delete et spécifiez le nom de votre espace de noms.

    kubectl delete namespace ingress-basic
    

Étapes suivantes

Cet article a mentionné certains composants qui n’appartiennent pas à AKS. Pour plus d’informations sur ces composants, consultez les pages projet suivantes :

Vous pouvez également :