Kubernetes Ingress Automatic Let's Encrypt Certificates

Kubernetes Ingress is a powerful resource that can automate load balancing and SSL/TLS termination. Let’s Encrypt is a fantastic service that provides free SSL/TLS certificates. This is a comprehensive guide to provision automated Let’s Encrypt certificates for your Kubernetes Ingress using Kubernetes Jobs to generate and Cron Jobs to renew Let’s Encrypt certificates.

Prerequisites

You must have an Ingress Controller deployed to your Kubernetes cluster. If you are running on Google Kubernetes Engine, you can easily use the GCE Ingress Controller. Otherwise you can use the NGINX Ingress Controller.

You should have an NFS server available with an NFS path owned by UID/GID 1000:1000 for storage of the Let’s Encrypt certificates. You can follow the NFS Example to setup a NFS server in your Kubernetes cluster.

Define Variables

Separating configuration from logic is an important first step to staying organized. First, we’ll create a file called vars.env that holds all of the configuration for our resources.

NAMESPACE: the Kubernetes namespace that the Ingress, Job, and CronJob will be deployed to

CERT_NAME: the primary certificate name. For a normal hostname, this is the same as DOMAIN_1. For a wildcard hostname, replace the asterics with an underscore, i.e. if DOMAIN_1 is *.boxboat.com, then CERT_NAME should be _.boxboat.com

TLS_SECRET: name of the TLS Secret that will be used for your Ingress resource

Setup Kubernetes Service Account and NFS Volume Resources

The certificate generation and renewal jobs will need to automatically update the TLS Secret on the Ingress resource with generated Let’s Encrypt certificates. We’ll create a ServiceAccount, Role, and RoleBinding to update the TLS Secret.

Run the script ./lego-setup.sh. You should now see resources when you run the following:

# should print a "lego" service account
kubectl -n YOUR_NAMESPACE get serviceaccount
# should print a "lego-secret-update" role
kubectl -n YOUR_NAMESPACE get role
# should print a "lego-secret-update" rolebinding
kubectl -n YOUR_NAMESPACE get rolebinding
# should print a "YOUR_NAMESPACE-lego-nfs" pv
kubectl get pv
# should print a "lego-nfs" pvc
kubectl -n YOUR_NAMESPACE get pvc

Setup DNS Challenge Secret

The lego Let’s Encrypt client is used to generate certificates. The dns-01 challenge is used to prove that we own the domains in the certificate request. Our example uses the AWS Route 53 provider, however it can be easily customized for any supported DNS provider.

Create file called lego-secret.yml to hold the DNS provider credentials: