This post will show you how to use cert-manager to automatically create and use certificates with Let’s Encrypt on Kubernetes. This is especially useful if you are looking for a successor to kube-lego, which is no longer maintained. Take a look at the offical docs, if you want more information about how each component works.

Prerequisites for this guide:

First we need to install cert-manager with helm

helm install     --name cert-manager     --namespace kube-system     stable/cert-manager

Install clusterissuers, which instruct Cert Manager to use Let’s Encrypt. Replace the email with yours

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: default
spec:
  acme:
    email: youremail@example.com
    server: https://acme-v01.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod
    http01: {}

Enable usage of the issuer we just created:

helm upgrade cert-manager     stable/cert-manager     --namespace kube-system     --set ingressShim.defaultIssuerName=letsencrypt-prod --set ingressShim.defaultIssuerKind=ClusterIssuer

Create ingress resources for your services with kubectl apply -f e.g.:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: www-ingress
  namespace: default
  annotations:
    # This needs to be set to enable automatic certificates
    kubernetes.io/tls-acme: "true"
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - www.example.com
    # The secret will be created automatically
    secretName: www-tls
  rules:
  # The host must be identical to the above one
  - host: www.example.com
    http:
      paths:
      - path: /
        backend:
          # The name of your service
          serviceName: www-service
          servicePort: 80

This is the minimal configuration that gives you SSL. Your website should no be accessible via https at www.example.com.

Working with authentication

If you use nginx.ingress.kubernetes.io/auth-* annotations you will need to whitelist the ACME challenge location in order to succeed in proving that you operate the website to Let’s Encrypt. If you set up Nginx ingress correctly there should be a configmap for configuring nginx. Modify it (by e.g. running EDITOR=nano kubectl edit cm -n ingress-nginx nginx-configuration) to add the annotation no-auth-locations so that it looks similar to this:

apiVersion: v1
data:
  no-auth-locations: /.well-known/acme-challenge
  # ...
kind: ConfigMap
metadata:
  annotations:
    # ...
  labels:
    app: ingress-nginx
  name: nginx-configuration
  namespace: ingress-nginx
  # ...