Wildcard SSL using Let’s Encrypt for Kubernetes Ingress. GKE

Let’s Encrypt is pretty useful if you have a multi-tenant application that is based out of subdomains. Had the same requirement while developing Digihosp. We developed the application as a set of microservices and kubernetes was the choice of container orchestration.

Let’s Encrypt allows you to generate ssl certificates in two ways:

1.With shell access.

2.Without shell access.

This article explores a way to generate ssl certificates without shell access.

Install certbot:

The first step is to install certbot. If you are on mac you can install via brew install certbot.

Domain verification and ssl certificates.

There are two ways verify your domain.

  1. Through DNS:
sudo certbot certonly --manual --preferred-challenges dns

2. Through HTTP:

sudo certbot certonly --manual

Follow the instructions of certbot. CertBot will ask you to enter a list of space or comma separated domains. Specify *.your-domain.com as your domain. If you use DNS method to verify your domain certbot will ask you to add a TXT record under _acme-challenge.yourdomain.com. Add the txt record and wait till it is ready. You can press enter and your ssl certificates are ready to use.

If you use HTTP method, follow certbot’s instruction to create a url /.well-known/acme-challenge .

You should now have your certificates at: /etc/letsencrypt/live/yourdomain/fullchain.pem and key at /etc/letsencrypt/live/yourdomain/privkey.pem

Deploy to Kubernetes

You can follow the instructions here to deploy a basic ingress to GKE. You need to make a couple of changes for ssl.

Deploy secrets

kubectl create secret tls your-secret \
--cert /etc/letsencrypt/live/yourdomain/fullchain.pem --key /etc/letsencrypt/live/yourdomain/privkey.pem

Check for permissions.

Modify ingress yaml

This is a sample file based on the instructions from GKE.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- secretName: your-secret
rules:
- host:
http:
paths:
- backend:
serviceName: web
servicePort: 8080

This is the standard Kubernetes manifest file to include ssl.

Deploy ingress and point to the IP

kubectl apply -f basic-ingress.yaml

Find out the external IP address of the load balancer serving your application by running:

kubectl get ingress basic-ingress

Create A record with * as dns name and point it to the IP you got with the previous command.

Navigate to https://any-subdomain.yourdomain.com to check if it works.

Remember that the certificates expire after 3 months using this procedure. You can repeat the process or stay tuned to know how to generate ssl certificates dynamically.