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
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>
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.
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
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