Cert-Manager è un controller utilizzato per la gestione dei certificati. Un Cert-Manager può aiutare a emettere certificati da diversi emittenti come Let's Encrypt, HashiCorp Vault, Venafi, una semplice coppia di chiavi di firma o autofirmati. Cert-Manager convalida i certificati, assicura che siano aggiornati e li rinnova prima della scadenza. Cert-Manager è composto da diversi componenti come indicato di seguito.
- Emittente : Issuers e ClusterIssuers sono oggetti in Kubernetes che rappresentano le autorità di certificazione (CA) in grado di generare certificati firmati.
- Certificato : Un Certificato è una risorsa con spazio dei nomi che fa riferimento a un Emittente o ClusterIssuer e sarà rinnovata e tenuta aggiornata.
- Richiesta di certificato : Il CertificateRequest è una risorsa con spazio dei nomi utilizzata per richiedere un certificato a un emittente o un emittente del cluster.
- Ordini ACME : Un ordine rappresenta una richiesta di certificato che verrà creata una volta creata una nuova risorsa CertificateRequest che fa riferimento a un emittente ACME
- Sfide ACME :quando viene creata una risorsa per l'ordine, le risorse Challenge per ogni nome DNS autorizzato con il server ACME verranno create dal controller dell'ordine.
- Webhook :viene distribuito come un altro pod insieme ai principali pod Cert-Manager e ha 3 funzioni: ValidatingAdmissionWebhook, MutatingAdmissionWebhook e CustomResourceConversionWebhook.
- CA Iniettore r:Aiuta a configurare i certificati per Webhook di convalida, Webhook di mutazione e Webhook di conversione.
In questo articolo, imposteremo un Cert-Manager con l'emittente Let's Encrypt. Proteggeremo la nostra applicazione di esempio utilizzando i certificati TLS e avremo HTTPS nel nostro nome host per accedere all'applicazione tramite Ingress. Per fare ciò, aggiungeremo annotazioni a Ingress in modo che la risorsa del certificato venga creata per nostro conto.
Per conoscere in dettaglio Cert-Manager, visita la documentazione ufficiale qui. L'obiettivo di questo articolo è impostare il Cert-Manager utilizzando Helm e si presume che tu abbia familiarità con i concetti relativi al Cert-Manager.
Prerequisiti
- Account AWS (crea se non ne hai uno).
- Kubernetes Cluster (fai clic qui per imparare a creare un Kubernetes Cluster utilizzando Kops e saperne di più.)
- Nginx Ingress Controller nel cluster K8S (cerca "What is Ingress Controller and how to deploy Nginx Ingress Controller in Kubernetes Cluster on AWS using Helm" per imparare a configurare Nginx Ingress Controller)
- Helm v3.5.3 (fai clic qui per imparare a installare Helm su Ubuntu Server)
- Bucket S3 (fai clic qui per imparare a creare un bucket S3 su AWS).
- Nome dominio (fai clic qui per imparare a registrare un dominio su AWS).
- Ruolo IAM con autorizzazioni di amministratore(fai clic qui per imparare a creare un ruolo IAM su AWS).
Cosa faremo?
- Controlla il controller di ingresso nel cluster
- Imposta un gestore certificati
- Crea file di definizione oggetto per un'applicazione di esempio
- Impostazione di staging e produzione Let's Encrypt Issuer
- Distribuisci un'applicazione di esempio
- Distribuisci un oggetto Ingress con TLS
Controlla il controller di ingresso nel cluster
Prima di procedere, controlla se il controller di ingresso Nginx è in esecuzione nel cluster.
kubectl get pods
kubectl get svc
Gestione certificati di installazione
Note: I have used Helm binary present at my current location, hence you can see ./helm in screenshots.
Usa Helm v3.5.3 ed esegui i seguenti comandi, questo installerà Helm Chart per 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
Nella schermata sopra, puoi vedere che il grafico Helm per Cert-Manager è stato installato.
Controlla i pod che sono stati creati come parte del Cert-Manager.
kubectl get pods -A
Puoi vedere 3 nuovi pod nello spazio dei nomi "cert-manager".
Crea file di definizione oggetto per un'applicazione di esempio e gli emittenti
Crea 1-nginx-main-app.yaml per l'applicazione 1
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea 2-nginx-green-app.yaml per l'applicazione 2.
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea 3-nginx-blue-app.yaml per l'applicazione 3
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea 4-tls-ingress.yaml per creare regole di ingresso basate sul percorso con Staging Issuer.
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea 5-tls-ingress-prod-issuer.yaml per creare regole Ingress basate sul percorso con Production Essuer.
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea staging_issuer.yaml per Let's Encrypt Staging Issuer
Link Github:fai clic qui per copiare il file dal mio repository 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
Crea production_issuer.yaml per Let's Encrypt Production Issuer
Link Github:fai clic qui per copiare il file dal mio repository 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
Puoi trovare tutti questi file nel mio repository Github qui.
Impostazione staging e produzione Let's Encrypt Issuer
Installeremo sia Staging che Production Cluster Issuer.
Messa in scena :
Lo staging ha "server: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
Questo crea un segreto chiamato "letsencrypt-staging-private-key"
kubectl get secret letsencrypt-staging-private-key -n cert-manager -o json
Produzione :
La produzione ha "server: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
Questo crea un segreto chiamato "letsencrypt-production-private-key"
kubectl get secret letsencrypt-production-private-key -n cert-manager -o json
Distribuisci un'applicazione di esempio
Distribuiamo le nostre 3 applicazioni di esempio.
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
Distribuisci ingresso
Innanzitutto, distribuiamo un Ingress with Staging Issuer.
kubectl apply -f sample-app/4-tls-ingress.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
Dopo aver creato la risorsa Ingress, puoi vedere cosa è successo in background per emettere il certificato per la sezione TLS di 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
È ora possibile accedere all'applicazione tramite HTTPS, ma poiché abbiamo utilizzato l'ambiente di staging dell'emittente Let's Encrypt, riceveremo un avviso "La tua connessione a questo sito non è sicura".
Distribuisci Ingress con l'emittente di produzione.
Ora eliminiamo l'Ingress utilizzando lo Staging e creiamo un nuovo Ingress puntato all'emittente di produzione.
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
Questa volta se provi ad accedere all'applicazione, non riceverai nessun avviso come "La connessione a questo sito non è sicura".
Conclusione
In questo articolo, abbiamo visto i passaggi per configurare un Cert-Manager sul cluster Kubernetes. Abbiamo distribuito un'applicazione di esempio e instradato il traffico attraverso l'ingresso in base al percorso e protetto la connessione con HTTPS utilizzando un certificato emesso dall'emittente del cluster Let's Encrypt. Abbiamo prima emesso un certificato utilizzando l'ambiente Let's Encrypt Staging e poi utilizzato l'ambiente di produzione Let's Encrypt