QuickStart for Let's Encrypt on Kubernetes
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: youremail@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 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
# ...