Skip to content

Controller nos Ingress

Estimated time to read: 4 minutes

Pour nous aider à gérer nos Ingress, ingress-nginx-controller va nous aider pour automatiquement faire le routage depuis l'extérieur.

D'abord, il faut ajouter le repo Helm pour le chart:

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

Ensuite, on peut installer le chart: (1)

  1. ℹ️ l'option create-namespace force la création d'un nouveau namespace
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace nginx-ingress-controller \
  --create-namespace \
  --set controller.publishService.enabled=true

On peut vérifier que tout est installé correctement

helm ls -A

Helm installé

NAME            NAMESPACE                   REVISION    UPDATED                                 STATUS      CHART               APP VERSION
ingress-nginx   nginx-ingress-controller    1           2023-12-19 15:33:53.505518 +0100 CET    deployed    ingress-nginx-4.8.4 1.9.4       # (1)
  1. La version 1.9.4 peut variée

On peut vérifier que le namespace et les composants sont bien créés :

kubectl get ns

Le namespace est créé

NAME                       STATUS   AGE
default                    Active   5h17m
kube-node-lease            Active   5h17m
kube-public                Active   5h17m
kube-system                Active   5h17m
nginx-ingress-controller   Active   10s
kubectl get all -n nginx-ingress-controller

Les composants sont instanciés et opérationnels

NAME                                            READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-75967d99c9-9vcwr   1/1     Running   0          2m45s

NAME                                         TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.3.28.249   57.128.120.49   80:31253/TCP,443:31582/TCP   2m46s
service/ingress-nginx-controller-admission   ClusterIP      10.3.10.52    <none>          443/TCP                      2m46s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           2m46s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-75967d99c9   1         1         1       2m46s

Info

Cela peut prendre un peu de temps avant que l'IP externe soit disponible.

Une fois l'IP externe disponible, on peut facilement la récupérer:

export EXT_IP=$(kubectl get service ingress-nginx-controller -n nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo ${EXT_IP:-NOT_SET_WAIT_AND_RETRY}

Désormais, notre ingress-controller va automatiquement gérer le routage pour nous lors de l'ajout d'Ingress dans le cluster.

Pour cela, il faut définir un Ingress avec le Deployment précisant l'URL sur laquelle exposer le service et spécifier dans l'attribut host l'URL sur laquelle on souhaite exposer notre deployment.

Exemple avec le premier déploiement

(pas besoin de le faire, on l'a préparé pour vous, cf. la suite 😉)

On pourrait ajouter cela à notre 1er déploiement, par exemple:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-deployment-ingress
  namespace: demos
  annotations:
    external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" # (1)
spec:
  ingressClassName: nginx
  rules:
    - host:  simple-deployment.<votre_trigramme>.grunty.uk # (2)
      http:
        paths:
          - backend:
              service:
                name: simple-deployment-service
                port:
                  number: 80
            pathType: Prefix
            path: /
---
  1. ℹ️ Spécificité lorsque l'on utilise cloudflare
  2. 🛜 URL sur laquelle on veut exposer le service

On va installer un nouveau Deployment avec son Ingress grâce au fichier demos/deployment-with-ingress-grunty.yml

Pensez à mettre votre trigramme

Pensez bien à modifier demos/deployment-with-ingress-grunty.yml avec votre trigramme avant de faire le apply

kubectl apply -f demos/deployment-with-ingress-grunty.yml
export my_host=new-deployment.<votre_trigramme>.grunty.uk
echo "Site URL http://"${my_host}
Pour les curieux, le contenu de deployment-with-ingress-grunty.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: new-deployment
  namespace: demos
spec:
  replicas: 1
  selector:
    matchLabels:
      app: new-deployment
  template:
    metadata:
      labels:
        app: new-deployment
    spec:
      containers:
        - name: new-deployment
          image: nginxdemos/hello:plain-text
          ports:
            - name: http
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: new-deployment-service
  namespace: demos
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: new-deployment
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: new-deployment-ingress
  namespace: demos
  annotations:
    external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
spec:
  ingressClassName: nginx
  rules:
    - host: new-deployment.<votre_trigramme>.grunty.uk
      http:
        paths:
          - backend:
              service:
                name: new-deployment-service
                port:
                  number: 80
            pathType: Prefix
            path: /
---

Demo déployée

Le pod est démarré :

kubectl get po -n demos
donne
NAME                                READY   STATUS    RESTARTS   AGE
new-deployment-5998d8dbcc-kdbrk     1/1     Running   0          9m21s
simple-deployment-5897799cb-94xzv   1/1     Running   0          58m

et l'ingress créé avec la bonne url:

kubectl get ingress -n demos
donne
NAME                     CLASS   HOSTS                          ADDRESS         PORTS   AGE
new-deployment-ingress   nginx   new-deployment.mvt.grunty.uk   57.128.120.31   80      9m32s

Grâce à l'ingress controller, nous n'avons plus besoin de faire le port-forward comme précédemment car le routage est fait sur l'URL. On peut donc tester d'accéder à nos pods via curl

2️⃣ méthodes possibles:

  • En forcant un header Host avec l'URL voulue:

echo "Host: ${my_host}" "http://${EXT_IP}/"
curl --header "Host: ${my_host}" "http://${EXT_IP}/"
* ou, en surchargeant la résolution DNS dynamiquement:

curl --resolve ${my_host}:80:${EXT_IP} -H "Host: ${my_host}" -i "http://${EXT_IP}"

Les 2 commandes donnent le même résultat: (1)

  1. ⏳ La commande avec l'option --resolve est légèrement plus verbeuse
Server address: 10.2.1.6:80
Server name: new-deployment-5998d8dbcc-kdbrk
Date: 19/Dec/2023:15:07:19 +0000
URI: /
Request ID: 4246cc4f7d0d56a49792cc73024dc779

On a changé l'image Docker entre temps

Ne vous étonnez pas si vous ne voyez plus le magnifique cinéma ASCII du départ.

On a changé l'image Docker pour que ce que l'on affiche soit lisible lorsque l'on fait un cUrl

Ok ca fonctionne, mais ca reste pas super pratique à utiliser 🫤 car même si l'on a défini une URL dans notre manifest, celle-ci n'est pas référencée dans un DNS.

💡 Ca serait pratique, si automatiquement nos entrées DNS étaient crées et publiées pour que ce soit accessible depuis un navigateur comme tout autre site "classique".

Et si external-dns était la solution ⁉️

🧂 Alors ajoutons-en une pincée pour voir ➡️