Kubernetes nous offre beaucoup de flexibilité pour définir la manière dont nous voulons que nos services soient exposés. Vous pouvez configurer vos objets Services pour vous assurer qu'un groupe de pods n'est accessible que dans le cluster ou permettre un accès depuis l'extérieur du cluster.

Si votre fournisseur de cloud choisi le prend en charge, vous pouvez même demander une adresse IP ou un nom d’hôte avec load-balancing pour votre service. L'objet Service nous offre un moyen simple de connecter des services exécutés dans des pods. Toutefois, si vous souhaitez configurer des règles de routage de base pour différents services ou si vous souhaitez configurer des éléments tels que TLS, la ressource Ingress offre un moyen beaucoup plus souple de configurer cet accès.

Une Ingress peut être supportée par différentes implémentations via l'utilisation de différents contrôleurs d'ingress. Le contrôleur le plus populaire est le contrôleur d’ingénierie NGINX. Toutefois, d’autres options sont disponibles, telles que Traefik, Rancher, HAProxy, etc.

Chaque contrôleur doit prendre en charge une configuration de base, mais peut même exposer d’autres fonctions annotations.  Dans ce guide, nous allons examiner la configuration du contrôleur d'ingress NGINX dans notre cluster et créer des itinéraires d’entrée pour un exemple d’application. Vous apprendrez comment sont définis les objets Ingress, notamment comment configurer TLS et l’authentification de base

Prérequis  

Ce guide repose sur les pré-requis suivants:  

  • Vous avez une connaissance de base de Kubernetes Deployments, Services et autres objets API.
  • Vous avez des connaissances de base sur les charts de Helm et sur la façon de les créer.
  • Vous avez un cluster externe Kubernetes s'exécutant sur GKE ou sur une autre plate-forme.
  • La ligne de commande kubectl (CLI kubectl) est installée.
  • Helm et Tiller sont installés.
  • Un nom de domaine avec possibilité de configurer le DNS.
  • L'utilitaire htpasswd, requis uniquement si vous prévoyez d'implémenter l'authentification de base, comme décrit plus bas.

On démarre comme d'habitude avec Gcloud Components :

gcloud init

Puis on enchaine avec la zone géographique de notre projet et enfin avec la création du cluster Kubernetes :

MBP-de-admin:~ admin$ gcloud config set compute/zone europe-west1-c
Updated property [compute/zone].
MBP-de-admin:~ admin$ gcloud container clusters create ghost-cluster   --enable-cloud-logging   --enable-cloud-monitoring   --subnetwork default

Ce qui nous donne :

kubeconfig entry generated for ghost-cluster.
NAME           LOCATION        MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
ghost-cluster  europe-west1-c  1.10.11-gke.1   35.233.39.100  n1-standard-1  1.10.11-gke.1  3          RUNNING
MBP-de-admin:~ admin$ gcloud container clusters get-credentials ghost-cluster
Fetching cluster endpoint and auth data.
kubeconfig entry generated for ghost-cluster.
MBP-de-admin:~ admin$ kubectl cluster-info
Kubernetes master is running at https://35.233.39.100
GLBCDefaultBackend is running at https://35.233.39.100/api/v1/namespaces/kube-system/services/default-http-backend:http/proxy
Heapster is running at https://35.233.39.100/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://35.233.39.100/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://35.233.39.100/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

Installer HELM sur le cluster

Helm est le moyen le plus simple d'exécuter et de gérer des applications dans un cluster Kubernetes. Helm vous permet d'effectuer des opérations clés pour la gestion d'applications telles que l'installation, la mise à niveau ou la suppression. Helm est composé de deux parties: Helm (le client) et Tiller (le serveur).

Suivez les étapes ci-dessous pour terminer l'installation de Helm et de Tiller et créer les objets Kubernetes nécessaires pour que Helm fonctionne avec le contrôle d'accès basé sur un rôle (RBAC): Contrôleur de notre cluster et créer des itinéraires d'ingress pour un exemple d'application.

CONSEIL: Si vous utilisez OS X, vous pouvez l'installer à l'aide de la commande brew install:

brew install kubernetes-helm.

Appliquez comme indiqué ci-dessous, les commandes suivantes :

MBP-de-admin:~ admin$ kubectl create serviceaccount --namespace kube-system tiller
serviceaccount "tiller" created
MBP-de-admin:~ admin$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io "tiller-cluster-rule" created
MBP-de-admin:~ admin$ helm init --service-account tiller
$HELM_HOME has been configured at /Users/admin/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
MBP-de-admin:~ admin$ kubectl get deployments -n kube-system
NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
event-exporter-v0.2.3   1         1         1            1           5m
fluentd-gcp-scaler      1         1         1            1           4m
heapster-v1.5.3         1         1         1            1           5m
kube-dns                2         2         2            2           5m
kube-dns-autoscaler     1         1         1            1           5m
l7-default-backend      1         1         1            1           5m
metrics-server-v0.2.1   1         1         1            1           5m
tiller-deploy           1         1         1            0           6s

Vérifier si le Tiller est bien installé :

MBP-de-admin:~ admin$ kubectl --namespace kube-system get pods | grep tiller
tiller-deploy-689d79895f-s74lf                            1/1       Running   0          25s

Installer Nginx Ingress Controller

La première étape consiste à installer le contrôleur d'ingress NGINX. Le moyen le plus simple de le faire fonctionner sur n'importe quelle plate-forme consiste à utiliser le chart Helm stable.

helm install stable/nginx-ingress --namespace kube-system

Une fois le contrôleur créé et en cours d'exécution, nous pouvons accéder au serveur NGINX via l'IP LoadBalancer ou NodePort de son service.

MBP-de-admin:~ admin$ kubectl get svc understood-walrus-nginx-ingress-controller -n kube-system
NAME                                         TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                      AGE
understood-walrus-nginx-ingress-controller   LoadBalancer   10.7.241.75   35.233.46.86   80:32116/TCP,443:32141/TCP   2m

Si tout est configuré, vous devriez obtenir une réponse «backend par défaut - 404» lors de l'accès au serveur Nginx. Cela nous indique que le contrôleur ne sait pas où router notre demande - nous n’avons encore configuré aucune règle - il répond donc avec le backend par défaut.  

Déployer l'application Joomla

Maintenant que nous avons un contrôleur d’ingress, nous pouvons commencer et créer des règles d'ingress ! Tout d’abord, nous avons toutefois besoin d’une application.  Le charts repository de Kubernetes propose de nombreuses applications facilement déployables pour le tester. Cet exemple utilise le logiciel Joomla!

helm install stable/joomla --name ingress-example 

Par défaut, le chart créera un service avec une adresse IP LoadBalancer. Nous pouvons nous assurer que Joomla! fonctionne en visitant l'adresse IP externe ou NodePort dans le navigateur. Cependant, comme nous voulons configurer l’accès au CMS via une route d’ingress, il serait préférable de n’autoriser que le Service à être exposé en interne au sein du cluster (c’est-à-dire avec le type ClusterIP).  

Modifiez le service pour qu'il utilise le type ClusterIP et supprimez les ports de nœud associés.  

kubectl patch svc ingress-example-joomla --type='json' -p '[{"op":"remove","path":"/spec/ports/0/nodePort"},{"op":"remove","path":"/spec/ports/1/nodePort"},{"op":"replace","path":"/spec/type","value":"ClusterIP"}]'

Nous ne devrions plus avoir accès à Joomla! via les ports IP ou de nœud externes, mais le contrôleur Ingress sera en mesure de le remplacer au sein du cluster.

Créer un objet d'ingress

La définition d’Ingress est une liste directe de règles de routage, chacune décrivant le chemin et le service auxquels adresser un proxy. Comme nous ne servons qu'une seule application, nous n'avons besoin de définir qu'une seule règle. Le modèle est disponible ici.

Une fois adapté cela donne ceci :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-resource
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: ingress-example-joomla
          servicePort: 80

Pour créer le fichier sur votre Mac:

touch basic-ingress.yaml
nano basic-ingress.yaml

Et enfin :

kubectl apply -f basic-ingress.yaml

Une fois créé, le contrôleur NGINX Ingress prendra le nouvel objet et configurera NGINX pour appliquer les règles que nous avons créées. Pour la règle ci-dessus, une demande entrante sur le chemin racine atteindra le serveur NGINX qui agira alors en tant que proxy inverse pour l'un des serveurs Joomla!

Comme il n'y a pas de nom d'hôte défini pour cette règle, elle agira comme un caractère générique. Cela signifie que l'adresse IP externe du service NGINX et tout nom d'hôte pointant sur celui-ci suivront cette règle.  Enregistrez la définition ci-dessus dans un fichier et créez l'objet dans votre cluster avec kubectl apply -f

Après quelques secondes, Joomla! devrait être accessible via l’IP externe du service NGINX (c’est-à-dire la même adresse IP que celle utilisée pour atteindre le serveur par défaut à l’étape 1). Notez que le contrôleur d’ingress NGINX impose un certificat TLS auto-signé pour les itinéraires génériques. Dans l’étape suivante, nous allons le rendre plus sécurisé en configurant un véritable certificat TLS pour le projet Joomla!

Configurer TLS avec LetsEncrypt et Kube-Lego

Maintenant que nous avons réactivé l’accès externe à notre site Joomla! l’étape suivante consiste à lui attribuer un nom de domaine et à activer TLS.

LetsEncrypt est une autorité de certification TLS gratuite. Grâce au contrôleur kube-lego, nous pouvons automatiquement demander et renouveler les certificats LetsEncrypt pour les noms de domaine public, simplement en ajoutant quelques lignes à notre définition Ingress!  Pour que cela fonctionne correctement, un nom de domaine public est requis et doit avoir un enregistrement A, pointant vers l'adresse IP externe du service NGINX.

Dans ces exemples, nous utilisons «YOUR_DOMAIN», mais ces références doivent être remplacées par un vrai nom de domaine.  Pour terminer ce processus, suivez les étapes ci-dessous:  Installez le chart kube-lego. Pour vous inscrire au service LetsEncrypt, un courrier électronique doit être fourni lors de l'installation du graphique (remplacez YOUR_EMAIL par une adresse électronique valide). Par défaut, le chart utilise l'environnement intermédiaire LetsEncrypt à des fins de test. Vous pouvez le modifier en définissant l'URL de production lors de l'installation du chart.

helm install stable/kube-lego --namespace kube-system --set config.LEGO_EMAIL=YOUR_EMAIL,config.LEGO_URL=https://acme-v01.api.letsencrypt.org/directory

Définissez le nom d'hôte pour Joomla! dans la définition d’ingress et configurez la section TLS. L'annotation tls-acme est également ajoutée pour indiquer au contrôleur kube-lego de demander un certificat pour cette règle d'entrée. Remplacez «YOUR_DOMAIN» par le nom de domaine configuré pour pointer vers le service NGINX.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: joomla-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: 'true'
spec:
  tls:
  - hosts:
    - gsagnard.fr
    secretName: joomla-tls-cert
  rules:
  - host: gsagnard.fr
    http:
      paths:
      - path: /
        backend:
          serviceName: ingress-example-joomla
          servicePort: 80

Enregistrez la nouvelle définition dans un fichier et appliquez les modifications dans le cluster.

MBP-de-admin:~ admin$ kubectl apply -f tls-ingress.yaml
ingress.extensions "joomla-ingress" created

kube-lego enregistrera les modifications apportées à l'objet Ingress, demandera le certificat à LetsEncrypt et le stockera dans le secret «joomla-tls-cert». À son tour, le contrôleur d’ingress NGINX liera la configuration TLS et chargera le certificat à partir du secret. Une fois le serveur NGINX mis à jour, une visite du domaine dans le navigateur devrait présenter le logiciel Joomla! site via une connexion sécurisée TLS.

Une autre façon de gérer les certificats LetsEncrypt sur Kubernetes consiste à utiliser kube-cert-manager. Ce contrôleur utilise ThirdPartyResources (maintenant CustomResourceDefinitions) au lieu d’Ingress pour demander des certificats pour les domaines. Ces certificats sont stockés dans un secret que vous pouvez ensuite référencer dans la ressource Ingress comme ci-dessus. Cette approche est plus souple car elle ne nécessite pas l’utilisation d’objets Ingress, vous pouvez utiliser les certificats directement dans vos applications. Cependant, kube-lego est plus simple si vous utilisez uniquement TLS dans votre Ingress.