August 20, 2020
Issue Let's Encrypt certificates for domains in a Kubernetes cluster
We will use cert-manager to issue HTTPS certificates for domains served publicly by a Kubernetes cluster.
The application can be installed via Helm, but it’s recommended to install CRDs (Custom Resource Definitions) separately. That may come in handy if you need to delete cert-manager
without losing already issued certificates. Don’t forget to change the “version” accordingly on all commands.
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.16.1/cert-manager.crds.yaml
Add JetStack charts to your Helm client.
helm repo add jetstack https://charts.jetstack.io
helm repo update
Install the application.
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.16.1
To issue actual certificates, you will need a production Issuer or ClusterIssuer. The following yaml defines a ClusterIssuer and assumes that you have a nginx
ingress controller. If it suit your needs, apply it to your cluster.
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: <your_email>
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
Verify if your set up is working.
$ kubectl get clusterissuers -A
NAME READY AGE
letsencrypt-prod True 30m
The cert-manager
stack will act upon ingresses that comply with a couple of conditions to generate HTTPS certificates. The following example illustrates that. Take special note of the annotations and the “secretName” property under “tls”.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/tls-acme: "true"
name: nginx-ingress
namespace: ingress-testing
spec:
rules:
- host: <public_URL>
http:
paths:
- backend:
serviceName: <service_name>
servicePort: 80
tls:
- hosts:
- <public_URL>
secretName: <secret_name_of_your_choosing>
Rancher users
If you’re installing the Helm Chart via Rancher, you may see the error release cert-manager failed: resource's namespace kube-system doesn't match the current namespace cert-manager
. This happens because cert-manager
tries to make changes to more than one namespace and Rancher doesn’t support that. There is an issue discussing this.
Thankfully, cert-manager
offers an option to only operate in one namespace. Set “global.leaderElection.namespace” to “cert-manager” to achieve this.
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.16.1 \
--set global.leaderElection.namespace=cert-manager
k3s users
In k3s, at least up to version 1.18.x, cert-manager
has problems running its webhook. At this time, to deal with this, we have to use an older version of cert-manager
that can run without it. Set “webhook.enabled” to “false” and use v0.13.1.
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.13.1 \
--set webhook.enabled=false