Cert-Manager est un contrôleur utilisé pour la gestion des certificats. Un Cert-Manager peut aider à émettre des certificats de différents émetteurs tels que Let's Encrypt, HashiCorp Vault, Venafi, une simple paire de clés de signature ou auto-signé. Cert-Manager valide les certificats, s'assure qu'ils sont à jour et les renouvelle avant leur expiration. Cert-Manager est composé de plusieurs composants, comme indiqué ci-dessous.
- Émetteur : Issuers et ClusterIssuers sont des objets dans Kubernetes qui représentent des autorités de certification (CA) capables de générer des certificats signés.
- Certificat : Un Certificat est une ressource avec espace de noms qui fait référence à un Issuer ou ClusterIssuer et qui sera renouvelée et tenue à jour.
- Demande de certificat : CertificateRequest est une ressource d'espace de noms utilisée pour demander un certificat à un émetteur ou à un émetteur de cluster.
- Commandes ACME : Une commande représente une demande de certificat qui sera créée une fois qu'une nouvelle ressource CertificateRequest référençant un émetteur ACME aura été créée
- Défis ACME :lorsqu'une ressource de commande est créée, les ressources de défi pour chaque nom DNS autorisé avec le serveur ACME seront créées par le contrôleur de commande.
- Webhook :Il est déployé en tant qu'autre pod avec les principaux pods Cert-Manager et possède 3 fonctions : ValidatingAdmissionWebhook, MutatingAdmissionWebhook et CustomResourceConversionWebhook.
- CA Injecto r :Il est utile de configurer des certificats pour les webhooks de validation, les webhooks de mutation et les webhooks de conversion.
Dans cet article, nous allons mettre en place un Cert-Manager avec l'émetteur Let's Encrypt. Nous allons sécuriser notre exemple d'application à l'aide des certificats TLS et ajouter HTTPS dans notre nom d'hôte pour accéder à l'application à l'aide d'Ingress. Pour ce faire, nous ajouterons des annotations à l'Ingress afin que la ressource de certificat soit créée en notre nom.
Pour connaître en détail Cert-Manager, visitez la documentation officielle ici. Cet article se concentre sur la configuration de Cert-Manager à l'aide de Helm et il est supposé que vous êtes familiarisé avec les concepts liés à Cert-Manager.
Pré-requis
- Compte AWS (créez si vous n'en avez pas).
- Cluster Kubernetes (Cliquez ici pour apprendre à créer un cluster Kubernetes à l'aide de Kops et en savoir plus.)
- Contrôleur d'entrée Nginx dans le cluster K8S (recherchez "Qu'est-ce que le contrôleur d'entrée et comment déployer le contrôleur d'entrée Nginx dans le cluster Kubernetes sur AWS à l'aide de Helm" pour apprendre à configurer le contrôleur d'entrée Nginx)
- Helm v3.5.3 (Cliquez ici pour apprendre à installer Helm sur Ubuntu Server)
- Compartiment S3 (Cliquez ici pour apprendre à créer un compartiment S3 sur AWS).
- Nom de domaine (Cliquez ici pour apprendre à enregistrer un domaine sur AWS).
- Rôle IAM avec autorisations d'administrateur (Cliquez ici pour apprendre à créer un rôle IAM sur AWS).
Qu'allons-nous faire ?
- Vérifier le contrôleur d'entrée dans le cluster
- Configurer un gestionnaire de certificats
- Créer des fichiers de définition d'objet pour un exemple d'application
- Configuration de la mise en scène et de la production Let's Encrypt Issuer
- Déployer un exemple d'application
- Déployer un objet Ingress avec TLS
Vérifier le contrôleur d'entrée dans le cluster
Avant de continuer, vérifiez si le contrôleur d'entrée Nginx est en cours d'exécution dans le cluster.
kubectl get pods
kubectl get svc
Configurer le gestionnaire de certificats
Note: I have used Helm binary present at my current location, hence you can see ./helm in screenshots.
Utilisez Helm v3.5.3 et exécutez les commandes suivantes, cela installera le Helm Chart pour Cert-Manager.
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --set installCRDs=true
Dans la capture d'écran ci-dessus, vous pouvez voir que le Helm Chart pour Cert-Manager a été installé.
Vérifiez les pods qui ont été créés dans le cadre du Cert-Manager.
kubectl get pods -A
Vous pouvez voir 3 nouveaux pods dans l'espace de noms "cert-manager".
Créer des fichiers de définition d'objet pour un exemple d'application et des émetteurs
Créez 1-nginx-main-app.yaml pour l'application 1
Lien Github : Cliquez ici pour copier le fichier depuis mon dépôt Github.
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-main spec: replicas: 1 selector: matchLabels: run: nginx-main template: metadata: labels: run: nginx-main spec: containers: - image: nginx name: nginx --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-main spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-main
Créez 2-nginx-green-app.yaml pour l'application 2.
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-green spec: replicas: 1 selector: matchLabels: run: nginx-green template: metadata: labels: run: nginx-green spec: volumes: - name: webdata emptyDir: {} initContainers: - name: web-content image: busybox volumeMounts: - name: webdata mountPath: "/webdata" command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=green>GREEN</font></h1>" > /webdata/index.html'] containers: - image: nginx name: nginx volumeMounts: - name: webdata mountPath: "/usr/share/nginx/html" --- --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-green spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-green
Créez 3-nginx-blue-app.yaml pour l'application 3
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-blue spec: replicas: 1 selector: matchLabels: run: nginx-blue template: metadata: labels: run: nginx-blue spec: volumes: - name: webdata emptyDir: {} initContainers: - name: web-content image: busybox volumeMounts: - name: webdata mountPath: "/webdata" command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=blue>BLUE</font></h1>" > /webdata/index.html'] containers: - image: nginx name: nginx volumeMounts: - name: webdata mountPath: "/usr/share/nginx/html" --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-blue spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-blue
Créez 4-tls-ingress.yaml pour créer des règles d'entrée basées sur le chemin avec l'émetteur intermédiaire.
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: letsencrypt-staging name: ingress-resource-3 spec: tls: - hosts: - kops.devopslee.com secretName: sample-kubernetes-tls rules: - host: kops.devopslee.com http: paths: - path: / backend: serviceName: nginx-deploy-main servicePort: 80 - path: /blue backend: serviceName: nginx-deploy-blue servicePort: 80 - path: /green backend: serviceName: nginx-deploy-green servicePort: 80
Créez 5-tls-ingress-prod-issuer.yaml pour créer des règles d'entrée basées sur le chemin avec Production Issuer.
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: letsencrypt-production name: ingress-resource-3 spec: tls: - hosts: - kops.devopslee.com secretName: sample-kubernetes-tls rules: - host: kops.devopslee.com http: paths: - path: / backend: serviceName: nginx-deploy-main servicePort: 80 - path: /blue backend: serviceName: nginx-deploy-blue servicePort: 80 - path: /green backend: serviceName: nginx-deploy-green servicePort: 80
Créez staging_issuer.yaml pour Let's Encrypt Staging Issuer
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: # Email address used for ACME registration email: your-email-id-here server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: # Name of a secret used to store the ACME account private key name: letsencrypt-staging-private-key # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: class: nginx
Créer production_issuer.yaml pour Let's Encrypt Production Issuer
Lien Github : Cliquez ici pour copier le fichier depuis mon référentiel Github.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-production spec: acme: # Email address used for ACME registration email: your-email-id-here server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: # Name of a secret used to store the ACME account private key name: letsencrypt-production-private-key # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: class: nginx
Vous pouvez trouver tous ces fichiers sur mon dépôt Github ici.
Configuration de la mise en scène et de la production Let's Encrypt Issuer
Nous installerons à la fois l'émetteur de cluster intermédiaire et de production.
Mise en scène :
La mise en scène a "serveur :https://acme-staging-v02.api.letsencrypt.org/directory"
kubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/staging_issuer.yaml
Cela crée un secret nommé "letsencrypt-staging-private-key"
kubectl get secret letsencrypt-staging-private-key -n cert-manager -o json
Production :
La production a "serveur :https://acme-v02.api.letsencrypt.org/directory"
kubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/production_issuer.yaml
Cela crée un secret nommé "letsencrypt-production-private-key"
kubectl get secret letsencrypt-production-private-key -n cert-manager -o json
Déployer un exemple d'application
Déployons nos 3 exemples d'applications.
kubectl apply -f sample-app/1-nginx-main-app.yaml
kubectl apply -f sample-app/2-nginx-green-app.yaml
kubectl apply -f sample-app/3-nginx-blue-app.yaml
Check the deployments, pods, and services created by the above commands.
kubectl get deployments
kubectl get pods kubectl
get service
Déployer Ingress
Tout d'abord, déployons une entrée avec un émetteur intermédiaire.
kubectl apply -f sample-app/4-tls-ingress.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
Une fois la ressource Ingress créée, vous pouvez voir ce qui s'est passé en arrière-plan pour émettre le certificat pour la section TLS de l'Ingress.
kubectl get certificate -A
kubectl get certificaterequests.cert-manager.io -A
kubectl get orders.acme.cert-manager.io -A
kubectl get challenges.acme.cert-manager.io -A
kubectl get certificate -o json | grep secretName
kubectl get secret sample-kubernetes-tls -o yaml
L'application est désormais accessible via HTTPS, mais comme nous avons utilisé l'environnement de staging de l'émetteur Let's Encrypt, nous recevrons un avertissement "Votre connexion à ce site n'est pas sécurisée".
Déployez Ingress avec l'émetteur de production.
Maintenant, supprimons l'entrée à l'aide de la mise en scène et créons une nouvelle entrée pointée vers l'émetteur de production.
kubectl delete -f sample-app/4-tls-ingress.yaml
kubectl apply -f sample-app/5-tls-ingress-prod-issuer.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
Cette fois, si vous essayez d'accéder à l'application, vous ne recevrez aucun avertissement car "La connexion à ce site n'est pas sécurisée".
Conclusion
Dans cet article, nous avons vu les étapes pour mettre en place un Cert-Manager sur le cluster Kubernetes. Nous avons déployé un exemple d'application et acheminé le trafic via l'entrée en fonction du chemin et sécurisé la connexion avec HTTPS à l'aide d'un certificat émis par l'émetteur du cluster Let's Encrypt. Nous avons d'abord émis un certificat à l'aide de l'environnement de préproduction Let's Encrypt, puis avons utilisé l'environnement de production Let's Encrypt