Deuxième partie de l'article qui décrit comment utiliser Istio, External-Dns et Cert-Manager dans un cluster Kubernetes pour déployer automatiquement une application accessible en HTTPS et que les entrées DNS et le certificat Let's Encrypt soient créés automatiquement lors de ce déploiement. Dans cette deuxième partie, nous allons aborder Cert-manager et l'installation de l'application.
Abordons donc l’installation de Cert-Manager et le déploiement de l’application.
La première partie de l’arcticle est disponible ici.
Cert-Manager
Composants
Cert-Manager
Cert-manager vient sous la forme de trois Pods :
Issuer
Les Issuers et Cluster Issuers sont des ressources Kubernetes qui représentent des autorités de certification (CA) capables de générer des certificats signés en honorant les demandes de signature de certificats. Tous les certificats des gestionnaires de certificats nécessitent un émetteur référencé qui est en état de répondre à la demande.
Celui utilisé ici est configuré pour Let’s Encrypt en mode staging:
Certificate
Cert-manager ajoute la Custom Resource Definition (CRD) Certificat qui définit un certificat x509 souhaité et qui sera renouvelé et tenu à jour. Un certificat est une ressource lié à un namespace qui fait référence à un Issuer ou Cluster Issuer qui détermine ce qui honorera la demande de certificat.
Lorsqu’une CRD Certificat est créé, une CRD CertificateRequest correspondante est créée par le gestionnaire de certificats, contenant la demande de certificat x509 encodée, la référence de l’émetteur et d’autres options basées sur la spécification de la CRD Certificat.
Ci dessous, le certificat utilisé dans notre cas:
Challenge
Les Challenges sont utilisées par l’émetteur d’ACME pour gérer le cycle de vie d’un défi ACME qui doit être complété afin de compléter une autorisation pour un nom/identifiant DNS unique.
Un Challenge est créé pour chaque nom DNS qui est autorisé par le serveur ACME.
En tant qu’utilisateur final, vous n’aurez jamais besoin de créer manuellement une ressource Challenge.
Resolver
Pod
Lorsqu’un certificat est demandé via le protocole ACME en mode HTTP, un Pod contenant le Token généré par l’autorité de certification permettant de résoudre le challenge est créé par cert-manager. Ce Pod disparaît lorsque le challenge est résolu et que le certificat a été généré.
Exemple de Pod:
Service
Un service est créé par cert-manager pour exposer le pod contenant la réponse au challenge (le Token). Il correspond à la description ci dessous.
Ingress
En plus du Pod et du service, un Ingress Kubernetes est créé par cert-manager pour accéder au service. Dans notre cas, cet Ingress est détecté par Istio qui va ajouter à l’Ingress Gateway une route vers le service exposant le Pod contenant la réponse au challenge (le Token). Cette route est supprimée lorsque le challenge est résolu.
Fonctionnement
Un objet Certificat est déployé sur le cluster. Cet objet contient notamment les informations suivantes:
Le nom DNS pour lequel on souhaite un certificat.
Le type et le nom de l’Issuer à utiliser.
Le nom du Secret qui contiendra le certificat. Ce nom doit être le même que celui indiqué dans le paramétrage de la Gateway.
Cert-Manager récupère les informations du Certificat.
Cert-Manager récupère les informations de configuration de l’Issuer indiqué dans le Certificat.
Cert-Manager va créer un challenge (non représenté ici) ainsi que le nécessaire pour résoudre le challenge.
L’ingress Gateway ajoute une route correspondant au service exposant le pod contenant la réponse au challenge (un Token).
Cert-Manager demande un certificat au serveur configuré dans l’Issuer (ici Let’s Encrypt staging).
Let’s Encrypt va résoudre le nom. C’est pour cela que External-Dns est nécessaire.
Let’s Encrypt va appeler le Load Balancer exposant l’Ingress Gateway à l’extérieur du Cluster et qui expose donc l’application et le resolver.
Le Pod contenant la réponse au challenge (le Token) est appelé et le Token renvoyé à Let’s Encrypt qui va générer le certificat.
Cert-Manager récupère le certificat et le stocke dans un Secret Kubernetes.
L’Istio Ingress Gateway récupere le certificat dans secret via le Secret Discovery Service (sds) d’Istio.
Une fois ceci réalisé, l’Ingress, le Service et le Pod du resolver sont supprimés.
Configuration
Copier la configuration de l’Issuer dans un fichier letsencrypt-staging-ClusterIssuer.yaml.
Déploiement
Cert-Manager
Issuers
Application
Composants
Le déploiement d’une application comprend plusieurs objets :
Le ou les Pods où tourne l’application.
Le service (de type ClusterIp) permettant d’accéder aux Pods.
Une Gateway (Custom Resource Définition fournie par Istio) contenant la configuration concernant les ports. utilisés, les hostnames acceptés ainsi que la configuration TLS (SSL).
Le Virtual Service permettant de gérer plus finement les règles d’accès et de routage.
A CRD Certificat pour l’obtention du certificat.
Configuration
Application
L’application utilisé est httpbin. Elle est présente dans les exemples fournis par istio (istio-1.5.0/samples/httpbin).
La configuration est dans un fichier httpbin.yaml:
Gateway
La Gateway est configurée pour paramétrer l’Istio Ingress Gateway ayant le label istio: ingressgateway-ssl.
Elle possède l’annotation externaldns: ssl pour être prise en compte par External-Dns.
Elle accepte les requêtes sur le nom d’hôte application.sample.com uniquement.
Elle écoute sur les ports 80 et 443. Les requêtes sur le port 80 sont redirigées automatiquement sur le port 443.
Le nom du secret contenant le certificat pour le port 443 est application.sample.com.
Copier le contenu suivant dans un fichier gateway-application.yaml:
Virtual Service
Le Virtual Service est configuré pour être rattaché à la Gateway nommée application-gateway dans le namespace istio-system.
Copier le contenu suivant dans un fichier virtualservice-application.yaml:
Certificate
Le certificat est configuré pour utiliser l’Issuer letsencrypt-staging, et pour obtenir un certificat pour le nom application.sample.com.
Copier le contenu suivant dans un fichier certificate-application.yaml:
Déploiement
Le déploiement consiste à appliquer les fichiers yaml avec kubectl. Il est possible de ne faire qu’un seul fichier contenant toute la configuration pour n’avoir qu’un commande à exécuter.