EDIT 2019-10-31: I tried to update this guide to 0.11, as a lot of things have changed since the original publication. I haven’t tested the full guide in the new version yet, but it should work. EDIT 2019-12-09: Updated for 0.12 and helm3
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:
- Running kubernetes cluster
- DNS entries pointed towards the node running your ingress controller
First we need to install cert-manager with helm
helm repo add jetstack https://charts.jetstack.io helm repo update kubectl create ns cert-manager kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml helm install --name cert-manager --namespace cert-manager --version v0.12.0 jetstack/cert-manager
Install clusterissuers, which instruct Cert Manager to use Let’s Encrypt. Replace the email with yours
apiVersion: cert-manager.io/v1alpha2 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: default spec: acme: email: email@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx
Enable usage of the issuer we just created:
helm upgrade cert-manager stable/cert-manager --namespace cert-manager --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
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 # ...