Managing ssl for ingress certificates with cert-manager

Cloud Platform (intermediate level) posted on 4th Sep 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 also replaces the info in Getting an ssl certificate for Kubernetes ingress which uses kube-lego (now being deprecated). This method uses its replacement ,cert-manager.

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, but replacing kube-lego with cert-manager.


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). 
  • Cert-Manager 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. 
  • 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.

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
curl | bash
helm init
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
helm init --service-account tiller --upgrade

Next, install cert-manager
helm install stable/cert-manager

You should see a cert manager pod
coy-dingo-cert-manager-65bf74c6b9-jl24t   1/1       Running   0          1d

What does cert-manager do

It searches for ingresses (not ingress controllers) that have a specific annotation, and generates (or renews those nearing expiry) certificates in a similar way to Kube-lego. Here are some in my ingress (which I'll cover later)
metadata: name: fidkp-ingress annotations: "true" "true" "nginx" "letsencrypt-prod"
  • tls-acme tells cert-manager that this is to use the acme protocol (as used by letsencrypt) to manage the certificate generation and renewal process.
  • cluster-issuer tells cert manager which certificate issuer to get certificates from. 


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 cert-manager 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
  • Cert-manager checks ingresses for the tls-acme annotation to see if it needs to manage certificates 


Cert-manager has the concept of an issuer (issues certificates for a specific namespace), or a clusterissuer (issues certificates across multiple namespaces in a cluster). I'm creating a cluster issuer with this example .yaml

kind: ClusterIssuer
  name: letsencrypt-prod
    # The ACME server URL
    # Email address used for ACME registration
    # Name of a secret used to store the ACME account private key
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

  • letsencrypt-prod is used to match this clusterissuer to the ingress that's going to use it
  • http01 is a method of proving that you own a domain. You may have come across this before, where you place a file on your webserver to prove you actually own it. Cert-manager generates a small file and then uses your ingress controller ip address (which is pointing at by an A record in your domain dns records) and then validates it can find it via that domain - in other words you don't actually have to place a file anywhere, but cert-manager uses that technique to validate domain ownership.


A certificate is held in a secret in Kubernetes. You can create this secret with cert-manager using this yaml. This pulls together the clusterissuer, the http01 validation and creates a secret that can be used by ssl.
kind: Certificate
  name: api-fid-crt
  namespace: default
  secretName: api-fid-crt
    name: letsencrypt-staging
    kind: ClusterIssuer
    - http01:
        ingressClass: nginx

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