Getting an ssl certificate for Kubernetes ingress

Cloud Platform (intermediate level) posted on 22nd March 2018

This is a part of the series of posts on Getting an API running in Kubernetes. For this to make sense you should have worked through a few of the earlier examples. This uses kube-leo which is being deprecated in favour of cert-manager. You can read how to use cert-manager instead here

I recommend that you save your commands in various scripts so you can repeat them or modify them later.  

In this article - we're doing this.


Before you can secure access to your service and run it over https, you'll need to generate a certificate and certificate key. Working with certificates is horrible, and causes brain freeze in many people - including me. Luckily we have 3 things to help us.
  • Letsencrypt allows you to get free certificates (normally you'd have to pay for them). 
  • Kube-lego is a set of Kubernetes components that can manage the whole business of renewing and applying those certificates, and is available as a helm-chart. Kube-lego has been superseded by cert-manager, but it's a lot simpler , so we'll stick with that one.
  • Kubernetes can store secrets and they can be accessed by other cluster resources.


You should already have helm installed from Bringing up an ingress controller, but if you dont - this'll do it.

curl | bash
helm init

Next, install kube-lego, changing the email address to yours. Note I'm installing this in the kube-system namespace. kube-lego can work across namespaces - so it could be handy in other work in this cluster.
echo "start up  kubelego"
helm install stable/kube-lego --namespace kube-system --set,config.LEGO_URL=

If you hit a permissions problem with the deployment itself, you can try appending this to the helm install line. If you get problems with tiller permissions see Bringing up an ingress controller for how to deal with it.
--set rbac.create=true

You should see a deployment for kube-lego
kubectl get deploy -n kube-system 

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
event-exporter-v0.1.7            1         1         1            1           9d
heapster-v1.4.3                  1         1         1            1           9d
kube-dns                         2         2         2            2           9d
kube-dns-autoscaler              1         1         1            1           9d
kubernetes-dashboard             1         1         1            1           9d
l7-default-backend               1         1         1            1           9d
listless-nightingale-kube-lego   1         1         1            1           1d
tiller-deploy                    1         1         1            1           4d

As well as a service
kubectl get service -n kube-system

NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
default-http-backend   NodePort   <none>        80:31830/TCP    9d
heapster               ClusterIP   <none>        80/TCP          9d
kube-dns               ClusterIP    <none>        53/UDP,53/TCP   9d
kube-lego-nginx        ClusterIP    <none>        8080/TCP        1d
kubernetes-dashboard   ClusterIP    <none>        443/TCP         9d
tiller-deploy          ClusterIP    <none>        44134/TCP       4d

What does kube-lego do

It searches for ingresses (not ingress controllers) that have a specific annontation (more about what that is later)
metadata: annotations: "true"
and creates and manages letsencrypt certificates for them, storing them as kubernetes secrets. If you check the log of the kube-lego pod, you'll see how it does that. An annoyance with letsencrypt is that their certs expire after 90 days. Kube-lego takes care of that too by automcatically renewing them if they look like they'll expire.


You may have notices "annotations" in some of the .yaml configurations. These are markers that can be read by other kubernetes resources. The next step is to create an ingress for our service that will contain an annotation like the one above to let kube-lego know that it needs to be processed for a certificate. 
  • The ingress controller checks for annotations in the configuration of ingresses to see if it should handle them
  • Kube-lego checks ingresses for the tls-acme annotation to see if it needs to manage certificates 

Next step

Nearly done - next step is the final piece of the puzzle. The ingress to connect the service to the ingress controller and to signal to kube-lego it needs to be managed.  See Getting an API running in Kubernetes for how.

Why not join our forum, follow the blog or follow me on twitter to ensure you get updates when they are available.