How to generate TLS Certificate using Cert-Manager and ACME Server

cert-manager logo
Reading Time: 2 minutes

Cert-Manager introduces Certificates and Issuers as Custom Resource in the Kubernetes Cluster. This simplifies the process of renewing, obtaining and managing those certificates. ACME stands for Automatic Certificate Management Environment. Let’s Encrypt is an ACME Server, which provides free SSL certificate. But before issuing certificates, it verifies if the domain. This verification is done with the help of orders and challenges. Cert Manager creates Custom Resources of Orders and Challenges for the purpose of acquiring ACME Certificates.

Prerequisites

  • Kubernetes Cluster
  • Helm CLI installed
  • Owned Domain
  • Public facing Load Balancer

Installing Cert-Manager

To install cert-manager, execute the commands:

helm repo add jetstack https://charts.jetstack.io

helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set installCRDs=true

This will install the cert-manager. Then to check, the CRDs cert-manager creates:

kubectl get crds | grep cert-manager.io

This will give the list of the CRDs, that cert-manager will create.

Deploy a ingress and map the IP to domain

To deploy nginx ingress, execute the comamnd:

helm upgrade --install ingress-nginx ingress-nginx \                                      
 --repo https://kubernetes.github.io/ingress-nginx \                 
 --namespace ingress-nginx --create-namespace

Then, we can check the IP of the Load Balancer Service created using:

kubectl get svc -n ingress-nginx

Then, map the IP to your domain on the DNS server you are using.

Creating a ACME Issuer

Now, we will be using the Issuer and Cluster Issuer resource to create a Certificate Issuer. Cluster Issuer is cluster-scoped while Issuer is namespace-scoped. To create Let's Encrypt Cluster Issuer, create a issuer.yaml:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: lets-encrypt
spec:
  acme:
    email: <email>
    privateKeySecretRef:
      name: lets-encrypt-secret # Secret where issuer private key will be stored

    server: https://acme-v02.api.letsencrypt.org/directory  #ACME Server
    solvers:
    - http01:
        ingress:
          class: nginx

Change nginx to the ingress class of the ingress you are using and run the command

kubectl apply -f issuer.yaml

Now, to check the status of the issuer, execute:

kubectl get clusterissuers

The cluster issuer should show true under ready field. If not give it a bit of time.

Creating a ACME certificate

Now, to create a certificate, create a file cert.yaml with the content:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: tls-cert
spec:
  isCA: false
  commonName: "<Domain name>"
  secretName: tls-cert
  dnsNames:
  - "<Domain name>"
  duration: 10000h
  renewBefore: 30h
  issuerRef:
    name: lets-encrypt
    kind: ClusterIssuer

Now, apply the above yaml using the command:

kubectl apply -f cert.yaml

To check if the certificate is ready, execute:

kubectl get certs

Now, if the certificate state is ready, we can check the namespace where we deployed the certificate. We will see a secret of type tls. We can now use this secret with our ingresses. Behind the scenes, the certificate created an ingress, certificate signing request, orders and challenges. When these were fulfilled, certificate was issued.

Conclusion

In this blog, we have looked how to use Cert manager. And we have learned about certificate management using cert-manager. Now, we can use cert-manager to issue free SSL certificates.

knoldus

Written by 

Dipayan Pramanik is a DevOps Software Consultant at Knoldus Inc. He is passionate about coding, DevOps tools, automating tasks and is always ready to take up challenges. His hobbies include music and gaming.

Leave a Reply