Créer un contrôleur d’entrée non géré

Un contrôleur d’entrée est un logiciel qui fournit un proxy inversé, un routage du trafic configurable et un arrêt TLS pour les services Kubernetes. Des ressources d’entrée Kubernetes sont utilisées pour configurer les règles d’entrée et les itinéraires des services Kubernetes individuels. Quand vous utilisez un contrôleur d’entrée et des règles d’entrée, une seule adresse IP peut être utilisée pour router le trafic vers plusieurs services dans un cluster Kubernetes.

Cet article montre comment déployer le contrôleur d’entrée NGINX dans un cluster Azure Kubernetes Service (AKS). Plusieurs applications sont ensuite exécutées dans le cluster AKS, chacune étant accessible via l’adresse IP unique.

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.

Remarque

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). Dans cet article, nous utiliserons le contrôleur d’entrée de la communauté Kubernetes.

Avant de commencer

  • 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 au dépôt Helm ingress-nginx. 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 auprès d’Azure Container Registry à partir d’Azure Kubernetes Service.
  • L’intégrité du point de terminaison healthz de l’API Kubernetes a été dépréciée dans Kubernetes v1.16. Vous pouvez plutôt remplacer ce point de terminaison par les points de terminaison livez et readyz. Voir Points de terminaison de l’API Kubernetes pour l’intégrité pour déterminer le point de terminaison qui convient à votre scénario.
  • 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.

Configuration de base

Pour créer un contrôleur d’entrée NGINX de base sans personnaliser les valeurs par défaut, vous allez utiliser Helm. La configuration suivante utilise la configuration par défaut pour des raisons de simplicité. Vous pouvez ajouter des paramètres pour personnaliser le déploiement, comme --set controller.replicaCount=3.

Remarque

Si vous souhaitez activer la préservation de l’adresse IP source du client pour les requêtes aux conteneurs de votre cluster, ajoutez --set controller.service.externalTrafficPolicy=Local à la commande d’installation Helm. L’IP source du client est stockée dans l’en-tête de la requête sous X-Forwarded-For. Quand vous utilisez un contrôleur d’entrée pour lequel la conservation de l’adresse IP source du client est activée, un transfert direct TLS ne fonctionne pas.

NAMESPACE=ingress-basic

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --create-namespace \
  --namespace $NAMESPACE \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
  --set controller.service.externalTrafficPolicy=Local

Remarque

Dans ce tutoriel, service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path est défini sur /healthz. Cela signifie que si le code de réponse des requêtes à /healthz n’est pas 200, tout le contrôleur d’entrée est arrêté. Vous pouvez changer la valeur en un autre URI dans votre propre scénario. Vous ne pouvez pas supprimer cette partie ni annuler la valeur, car sinon le contrôleur d’entrée reste arrêté. Le package ingress-nginx utilisé dans ce tutoriel, fourni par la documentation Kubernetes officielle, retourne toujours le code 200 en réponse à une requête de /healthz. En effet, il est conçu comme back-end par défaut pour faciliter le démarrage des utilisateurs, sauf s’il est remplacé par des règles d’entrée.

Configuration personnalisée

En guise d’alternative à la configuration de base présentée dans la section ci-dessus, la prochaine série d’étapes montre comment déployer un contrôleur d’entrée personnalisé. Vous aurez la possibilité d’utiliser une adresse IP statique interne ou une adresse IP publique dynamique.

Importer les images utilisées par le graphique Helm dans votre ACR

Pour contrôler les versions des images, vous pouvez les importer dans votre propre registre de conteneurs Azure. Le chart Helm du contrôleur d’entrée NGINX repose sur trois images conteneur. Utilisez az acr import pour importer ces images dans votre ACR.

REGISTRY_NAME=<REGISTRY_NAME>
SOURCE_REGISTRY=registry.k8s.io
CONTROLLER_IMAGE=ingress-nginx/controller
CONTROLLER_TAG=v1.8.1
PATCH_IMAGE=ingress-nginx/kube-webhook-certgen
PATCH_TAG=v20230407
DEFAULTBACKEND_IMAGE=defaultbackend-amd64
DEFAULTBACKEND_TAG=1.5

az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$CONTROLLER_IMAGE:$CONTROLLER_TAG --image $CONTROLLER_IMAGE:$CONTROLLER_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$PATCH_IMAGE:$PATCH_TAG --image $PATCH_IMAGE:$PATCH_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG --image $DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG

Notes

En plus d’importer des images de conteneur dans votre ACR, vous pouvez également importer des graphiques Helm dans votre ACR. Pour plus d’informations, consultez Envoyer (push) et tirer (pull) des charts Helm vers un registre de conteneurs Azure.

Créer un contrôleur d’entrée

Pour créer le contrôleur d’entrée, utilisez Helm pour installer ingress-nginx. Le contrôleur d’entrée doit être planifié sur un nœud Linux. Les nœuds Windows Server ne doivent pas exécuter le contrôleur d’entrée. Un sélecteur de nœud est spécifié en utilisant le paramètre --set nodeSelector pour que le planificateur Kubernetes exécute le contrôleur d’entrée NGINX sur un nœud Linux.

Pour renforcer la redondance, deux réplicas des contrôleurs d’entrée NGINX sont déployés avec le paramètre --set controller.replicaCount. Pour tirer pleinement parti de l’exécution de réplicas des contrôleurs d’entrée, vérifiez que votre cluster AKS comprend plusieurs nœuds.

L’exemple suivant crée un espace de noms Kubernetes pour les ressources d’entrée ingress-basic et est destiné à fonctionner dans cet espace de noms. Spécifiez un espace de noms de votre propre environnement, si besoin. Si le contrôle d’accès en fonction du rôle Kubernetes n’est pas activé sur votre cluster AKS, ajoutez --set rbac.create=false aux commandes Helm.

Notes

Si vous souhaitez activer la préservation de l’adresse IP source du client pour les requêtes aux conteneurs de votre cluster, ajoutez --set controller.service.externalTrafficPolicy=Local à la commande d’installation Helm. L’IP source du client est stockée dans l’en-tête de la requête sous X-Forwarded-For. Quand vous utilisez un contrôleur d’entrée pour lequel la conservation de l’adresse IP source du client est activée, un transfert direct TLS ne fonctionne pas.

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>

# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
    --version 4.7.1 \
    --namespace ingress-basic \
    --create-namespace \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.image.registry=$ACR_LOGIN_SERVER \
    --set controller.image.image=$CONTROLLER_IMAGE \
    --set controller.image.tag=$CONTROLLER_TAG \
    --set controller.image.digest="" \
    --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
    --set controller.service.externalTrafficPolicy=Local \
    --set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
    --set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
    --set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
    --set controller.admissionWebhooks.patch.image.digest="" \
    --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
    --set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
    --set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
    --set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
    --set defaultBackend.image.digest=""

Créer un contrôleur d'entrée grâce à une adresse IP interne

Par défaut, un contrôleur d’entrée NGINX est créé avec une affectation d’adresse IP publique dynamique. Une exigence de configuration courante est celle d’utiliser un réseau privé interne et une adresse IP. Cette approche vous permet de limiter l’accès à vos services aux utilisateurs internes, en excluant tout accès externe.

Utilisez les paramètres --set controller.service.loadBalancerIP et --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true pour attribuer une adresse IP interne à votre contrôleur d’entrée. Fournissez votre propre adresse IP interne pour une utilisation avec le contrôleur d’entrée. Vérifiez que cette adresse IP n’est pas déjà utilisée au sein de votre réseau virtuel. Si vous utilisez un réseau virtuel et un sous-réseau existants, vous devez configurer votre cluster AKS avec les autorisations appropriées afin de pouvoir les gérer. Pour plus d’informations, consultez Utiliser un réseau kubenet avec vos propres plages d’adresses IP dans Azure Kubernetes Service (AKS) ou Configurer un réseau Azure CNI dans Azure Kubernetes Service (AKS).

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>

# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
    --version 4.7.1 \
    --namespace ingress-basic \
    --create-namespace \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.image.registry=$ACR_LOGIN_SERVER \
    --set controller.image.image=$CONTROLLER_IMAGE \
    --set controller.image.tag=$CONTROLLER_TAG \
    --set controller.image.digest="" \
    --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.service.loadBalancerIP=10.224.0.42 \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
    --set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
    --set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
    --set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
    --set controller.admissionWebhooks.patch.image.digest="" \
    --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
    --set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
    --set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
    --set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
    --set defaultBackend.image.digest="" 

Vérifier le service d’équilibrage de charge

Vérifier le service d’équilibrage de charge en utilisant kubectl get services.

kubectl get services --namespace ingress-basic -o wide -w ingress-nginx-controller

Quand le service d’équilibreur de charge Kubernetes est créé pour le contrôleur d’entrée NGINX, une adresse IP est affectée sous EXTERNAL-IP, comme indiqué dans l’exemple de sortie suivant :

NAME                       TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
ingress-nginx-controller   LoadBalancer   10.0.65.205   EXTERNAL-IP     80:30957/TCP,443:32414/TCP   1m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

Si vous accédez à l’adresse IP externe à ce stade, une page 404 s’affiche. Cela est dû au fait que vous devez toujours configurer la connexion à l’adresse IP externe, ce qui est effectué dans les sections suivantes.

Exécuter des applications de démonstration

Pour voir le contrôleur d’entrée à l’œuvre, exécutons deux applications de démonstration dans votre cluster AKS. Pour cet exemple, vous utilisez kubectl apply pour déployer deux instances d’une simple application Hello world.

  1. Créez un fichier aks-helloworld-one.yaml et copiez-y l’exemple YAML suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aks-helloworld-one  
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aks-helloworld-one
      template:
        metadata:
          labels:
            app: aks-helloworld-one
        spec:
          containers:
          - name: aks-helloworld-one
            image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
            ports:
            - containerPort: 80
            env:
            - name: TITLE
              value: "Welcome to Azure Kubernetes Service (AKS)"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: aks-helloworld-one  
    spec:
      type: ClusterIP
      ports:
      - port: 80
      selector:
        app: aks-helloworld-one
    
  2. Créez un fichier aks-helloworld-two.yaml et copiez-y l’exemple YAML suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aks-helloworld-two  
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aks-helloworld-two
      template:
        metadata:
          labels:
            app: aks-helloworld-two
        spec:
          containers:
          - name: aks-helloworld-two
            image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
            ports:
            - containerPort: 80
            env:
            - name: TITLE
              value: "AKS Ingress Demo"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: aks-helloworld-two  
    spec:
      type: ClusterIP
      ports:
      - port: 80
      selector:
        app: aks-helloworld-two
    
  3. Exécutez les deux applications de démonstration avec kubectl apply :

    kubectl apply -f aks-helloworld-one.yaml --namespace ingress-basic
    kubectl apply -f aks-helloworld-two.yaml --namespace ingress-basic
    

Créer un itinéraire d’entrée

Les deux applications sont maintenant en cours d’exécution sur votre cluster Kubernetes. Pour acheminer le trafic vers chaque application, créez une ressource d’entrée Kubernetes. La ressource d’entrée configure les règles qui acheminent le trafic vers l’une des deux applications.

Dans l’exemple suivant, le trafic vers EXTERNAL_IP/hello-world-one est routé vers le service nommé aks-helloworld-one. Le trafic vers EXTERNAL_IP/hello-world-two est routé vers le service aks-helloworld-two. Le trafic vers EXTERNAL_IP/static est acheminé vers le service nommé aks-helloworld-one pour les ressources statiques.

  1. Créez un fichier nommé hello-world-ingress.yaml et copiez-y l’exemple de code YAML suivant :

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ingress
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/use-regex: "true"
        nginx.ingress.kubernetes.io/rewrite-target: /$2
    spec:
      ingressClassName: nginx
      rules:
      - 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
      rules:
      - http:
          paths:
          - path: /static(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port: 
                  number: 80
    
  2. Créez la ressource d’entrée avec la commande kubectl apply.

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

Tester le contrôleur d’entrée

Pour tester les itinéraires du contrôleur d’entrée, accédez aux deux applications. Ouvrez un navigateur web à l’adresse IP de votre contrôleur d’entrée NGINX, par exemple EXTERNAL_IP. La première application de démonstration s’affiche dans le navigateur web, comme illustré dans l’exemple suivant :

First app running behind the ingress controller

Maintenant, ajoutez le chemin /hello-world-two à l’adresse IP, par exemple EXTERNAL_IP/hello-world-two. La deuxième application de démonstration portant le titre personnalisé s’affiche :

Second app running behind the ingress controller

Tester une adresse IP interne

  1. Créez un pod de test et joignez-y une session de terminal.

    kubectl run -it --rm aks-ingress-test --image=mcr.microsoft.com/dotnet/runtime-deps:6.0 --namespace ingress-basic
    
  2. Installez curl dans le pod en utilisant apt-get.

    apt-get update && apt-get install -y curl
    
  3. Accédez à l’adresse de votre contrôleur d’entrée Kubernetes en utilisant curl, par exemple http://10.224.0.42. Fournissez votre propre adresse IP interne spécifiée lors du déploiement du contrôleur d’entrée.

    curl -L http://10.224.0.42
    

    Aucun chemin n’ayant été fourni avec l’adresse, la route par défaut du contrôleur d’entrée est /. La première application de démonstration est retournée, comme l’illustre l’exemple de sortie condensée suivant :

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <link rel="stylesheet" type="text/css" href="/static/default.css">
        <title>Welcome to Azure Kubernetes Service (AKS)</title>
    [...]
    
  4. Ajoutez le chemin d’accès /hello-world-two à l’adresse, par exemple http://10.224.0.42/hello-world-two.

    curl -L -k http://10.224.0.42/hello-world-two
    

    La deuxième application de démonstration avec le titre personnalisé est retournée, comme l’illustre l’exemple de sortie condensée suivant :

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <link rel="stylesheet" type="text/css" href="/static/default.css">
        <title>AKS Ingress Demo</title>
    [...]
    

Nettoyer les ressources

Cet article vous a montré comment utiliser Helm pour installer les composants d’entrée 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’espace de noms exemple en entier ou des ressources individuelles.

Supprimer l’espace de noms exemple et toutes les ressources

Pour supprimer l’espace de noms exemple en entier, utilisez la commande kubectl delete et spécifiez le nom de votre espace de noms. Toutes les ressources de l’espace de noms sont supprimées.

kubectl delete namespace ingress-basic

Supprimer les ressources individuellement

Sinon, une approche plus précise consiste à supprimer les ressources individuelles créées.

  1. Listez les versions de Helm avec la commande helm list.

    helm list --namespace ingress-basic
    

    Recherchez les graphiques nommés ingress-nginx et aks-helloworld, comme illustré dans l’exemple de sortie suivant :

    NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
    ingress-nginx           ingress-basic   1               2020-01-06 19:55:46.358275 -0600 CST    deployed        nginx-ingress-1.27.1    0.26.1  
    
  2. Désinstallez les versions avec la commande helm uninstall.

    helm uninstall ingress-nginx --namespace ingress-basic
    
  3. 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
    
  4. Supprimez la route d’entrée qui a dirigé le trafic vers les exemples d’applications.

    kubectl delete -f hello-world-ingress.yaml
    
  5. Supprimez l’espace de noms en utilisant la commande kubectl delete et en spécifiant le nom de votre espace de noms.

    kubectl delete namespace ingress-basic
    

Étapes suivantes

Pour configurer TLS avec vos composants d’entrée existants, consultez Utiliser TLS avec un contrôleur d’entrée.

Pour configurer votre cluster AKS pour utiliser le routage d’application HTTP, consultez Activer le module complémentaire de routage d’application HTTP.

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