Guide et instructions

1. Objectifs

  • Exposer les services
  • Utilisation des règles « Ingress »

2. Introduction

Sur un cluster Kubernetes, le déploiement d’applications est très rapide à faire : quelques déclarations, le lancement d’une commande et le cluster se charge du reste. En revanche, les applications sont déployées dans une bulle et elles ne sont pas accessibles directement depuis l’extérieur.

Pour exposer ces services, le lecteur a abordé une première technique basée sur l’utilisation de règles « Ingress ». Ces règles permettent d’associer un hôte virtuel avec un service interne. Elles sont lues par un contrôleur « Ingress » qui se charge de configurer un proxy inverse qui sert de point d’entrée. Créer un dossier « lab05 » et se mettre dans ce dossier.

mkdir lab05
cd lab05

Pour pouvoir créer et manipuler des objets ingress il est d’abord nécessaire d’installer un « ingress controller » dans le cluster. Sur minikube il faut utiliser la commande suivante:

minikube -p kubelabs addons enable ingress

Vérifiez que le contrôleur NGINX Ingress est en cours d’exécution

kubectl get pod -n ingress-nginx

3. Ingress

Créer dans le répertoire lab05 un fichier appelé ns-lab05.yaml en ajoutant le contenu suivant:

apiVersion: v1
kind: Namespace
metadata:
  name: ns-lab05

Créer le « Namespace » dans le cluster k8s

kubectl apply -f ns-lab05.yaml

Pour illustrer l’utilisation du concept « Ingress », nous allons déployer deux applications app1 et app2 basées sur la même image Docker Nginx. On va modifier la page index.html de chaque conteneur afin d’identifier clairement l’application visée par nos requêtes.

Ensuite, nous utiliserons un « Ingress » avec deux règles pour accéder à ces applications.

Pour la première application on va définir un fichier appelé app1.yaml qui décrit un objet Deployment et un objet Service ClusterIP.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app1pod
  template:
    metadata:
      labels:
        app: app1pod
    spec:
      containers:
      - name: app1container
        image: nginx:latest
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: 
                - /bin/sh
                - -c
                - >                  
                  mkdir /usr/share/nginx/html/app1;
                  echo App 1 fanout from $HOSTNAME > /usr/share/nginx/html/app1/index.html;
                  echo App 1 vhosts from $HOSTNAME > /usr/share/nginx/html/index.html
---
apiVersion: v1
kind: Service
metadata:
  name: app1service
spec:
  selector:
    app: app1pod
  type: ClusterIP
  ports:
    - protocol: TCP
      targetPort: 80
      port: 8080

Pour la deuxième application créez le manifeste app2.yaml qui contient aussi un objet Deployment et un objet Service ClusterIP.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app2pod
  template:
    metadata:
      labels:
        app: app2pod
    spec:
      containers:
      - name: app2container
        image: nginx:latest
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: 
                - /bin/sh
                - -c
                - >
                  mkdir /usr/share/nginx/html/app2;
                  echo App 2 fanout from $HOSTNAME > /usr/share/nginx/html/app2/index.html;
                  echo App 2 vhosts from $HOSTNAME > /usr/share/nginx/html/index.html                  
---
apiVersion: v1
kind: Service
metadata:
  name: app2service
spec:
  selector:
    app: app2pod
  type: ClusterIP
  ports:
    - protocol: TCP
      targetPort: 80
      port: 8080

Appliquez les deux manifestes pour créer les déployer les deux applications sur le cluster k8s.

kubectl apply -f app1.yaml -n ns-lab05
kubectl apply -f app2.yaml -n ns-lab05

Maintenant on va procéder aux descriptions des règles ingress pour exposer nos deux applications. Créez le un manifeste appelé app-ingress-path.yaml.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: moningressfanout
spec:
  rules:
    - http:
        paths:
        - path: /app1
          pathType: Prefix
          backend:
            service:
              name: app1service
              port:
                number: 8080
        - path: /app2
          pathType: Prefix
          backend:
            service:
              name: app2service
              port:
                number: 8080

Deux règles sont définies. La première s’applique au Service « app1service » avec le chemin (path) /app1 et la seconde gère le chemin (path) /app2 et s’applique au Service « app2service ».

Appliquez ces règles :

kubectl apply -f app-ingress-path.yaml -n ns-lab05

Afficher le détail complet de cet Ingress avec l’option « describe » pour s’assurer que tout est configuré correctement :

kubectl describe ingress -n ns-lab05 moningressfanout

Il ne reste plus qu’à tester les deux règles en effectuant des requêtes vers le nœud maître (ou nœud de travail) via l’outil « cURL ». Récupérez l’adresse IP de cluster minikube avec la commande suivante:

minikube -p kubelabs ip

Ensuite

curl [MINKUBEIP]:80/app1/
curl [MINKUBEIP]:80/app2/

Les Ingress permettent également de gérer les hôtes virtuels pour éviter d’utiliser les sous-chemins (fanout). Ainsi, au lieu d’utiliser cette forme d’URL http://<IP_NODE>/app1 nous allons plutôt utiliser celle-ci http://app1.mydomain.test. Toutefois, puisque nous ne disposons pas du domaine nous allons utiliser le service « nip.io ». Ce domaine DNS a pour particularité de répondre à toutes les résolutions DNS par l’adresse IP contenue derrière le préfixe « .nip.io ».

Quelques exemples de résolution de nom avec le domaine DNS nip.io :

  • 127.0.0.1.nip.io → 127.0.0.1
  • 192.168.0.1.nip.io → 192.168.0.1
  • entree-dns;10.10.12.1.nip.io → 10.10.12.1

Dans notre d’utilisation d’Ingress, les entrées DNS utilisaient l’adresse IP de la machine Minikube combinée avec le mécanisme DNS de nip.io. Pour les deux applications, on va utiliser les DNS suivant :

  • app1.[replacewithminikubeIP].nip.io
  • app2.[replacewithminikubeIP].nip.io

Dans le cadre d’un test, ce mécanisme est suffisant. En revanche, pour un hébergement professionnel, il devient nécessaire de faire appel à des entrées DNS.

Créez dans le manifeste app-ingress-vhost.yaml qui décrit un Ingress en utilisant des hôtes virtuels

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: moningressvhosts
spec:
  rules:
    - host: "app1.[replacewithminikubeIP].nip.io"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app1service
                port: 
                  number: 8080
    - host: "app2.[replacewithminikubeIP].nip.io"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app2service
                port: 
                  number: 8080

Appliquez cette configuration pour créer cet Ingress

kubectl apply -f app-ingress-vhost.yaml -n ns-lab05

Tester les deux règles associées à des hôtes virtuels en effectuant des requêtes via l’outil cURL:

curl app1.[MINKUBEIP].nip.io
curl app2.[MINKUBEIP].nip.io

Nettoyer les ressources

kubectl -n ns-lab05 delete service,deploy,ingress,pod --all