How to Configure Cert-Manager with ZeroSSL on Kubernetes
Overview
Cert-manager allows us to automate certificate management and issuance on our Kubernetes clusters. Follow along to configure Cert-Manager with ZeroSSL on your Kubernetes cluster!
Follow along to configure a ZeroSSL ClusterIssuer, this guide assumes you've already installed cert-manager on your cluster. I recommend installing it via Helm, follow this guide to do so: Helm | cert-manager.
Cert-Manager
To install cert-manager on your cluster, I recommend using Helm. Install Helm by running:
Install Helm
1curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
2sudo apt-get install apt-transport-https --yes
3echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
4sudo apt-get update
5sudo apt-get install helm
Install Cert-Manager
Now install cert-manager:
1helm repo add jetstack https://charts.jetstack.io
2
3helm repo update
1helm install \
2 cert-manager jetstack/cert-manager \
3 --namespace cert-manager \
4 --create-namespace \
5 --version v1.6.1 \
6 --set installCRDs=true
Verify cert-manager pods are running:
1kubectl get pod -n cert-manager
ZeroSSL
ZeroSSL offers unlimited 90 day SSL certificates, this is perfect for someone that needs many SSL certificates. There's also no rate limit for ZeroSSL compared to LetsEncrypt!
Create a ZeroSSL Account
Before we get started, you'll need a ZeroSSL account Sign Up - ZeroSSL.
After you've created your account, on your ZeroSSL dashboard, navigate to the Developer tab and generate your EAB credentials.
Create YAML Templates
Now that you have your credentials you'll want to create a secret on your kubernetes cluster.
Secret
1apiVersion: v1
2kind: Secret
3metadata:
4 namespace: cert-manager # Must be the namespace cert-manager is installed in
5 name: zerossl-eab
6stringData:
7 secret: <YOUR-HMAC-KEY-HERE>
ClusterIssuer
We'll also need to create a ClusterIssuer that will use these credentials to generate our certificates.
1apiVersion: cert-manager.io/v1
2kind: ClusterIssuer
3metadata:
4 name: zerossl-prod
5spec:
6 acme:
7 # The ACME server URL
8 server: https://acme.zerossl.com/v2/DV90
9 externalAccountBinding:
10 keyID: <YOUR-EAB-KID>
11 keySecretRef:
12 name: zerossl-eab
13 key: secret
14 # Name of a secret used to store the ACME account private key
15 privateKeySecretRef:
16 name: zerossl-prod
17 # Enable the DNS-01 challenge provider
18 solvers:
19 - dns01:
20 # Replace the section below with your DNS01 provider
21 cloudflare:
22 email: <YOUR-CF-EMAIL>
23 apiTokenSecretRef:
24 name: cloudflare-api-token
25 key: api-token
DNS01 Provider
In my case, I'm using the DNS01 challenge for verification of my domain, and allowing the ClusterIssuer to add DNS entries to my domain that's managed via CloudFlare. You can learn how to add your DNS01 provider here DNS01 | cert-manager.
Apply YAML Template
Now let's put this all together into one file that we can apply to our cluster.
1apiVersion: v1
2kind: Secret
3metadata:
4 namespace: cert-manager # Must be the namespace cert-manager is installed in
5 name: zerossl-eab
6stringData:
7 secret: <YOUR-HMAC-KEY-HERE>
8---
9apiVersion: cert-manager.io/v1
10kind: ClusterIssuer
11metadata:
12 name: zerossl-prod
13spec:
14 acme:
15 # The ACME server URL
16 server: https://acme.zerossl.com/v2/DV90
17 externalAccountBinding:
18 keyID: <YOUR-EAB-KID>
19 keySecretRef:
20 name: zerossl-eab
21 key: secret
22 # Name of a secret used to store the ACME account private key
23 privateKeySecretRef:
24 name: zerossl-prod
25 # Enable the HTTP-01 challenge provider
26 solvers:
27 - dns01:
28 # Replace the section below with your DNS01 provider
29 cloudflare:
30 email: <YOUR-CF-EMAIL>
31 apiTokenSecretRef:
32 name: cloudflare-api-token
33 key: api-token
Save this into a file e.g zerossl.yaml, then apply with kubectl apply -f zerossl.yaml
.
Setup Ingress to Use the ClusterIssuer
Now all you'll need to do is add the following line to your Ingress configuration under annotations.
cert-manager.io/cluster-issuer: "zerossl-prod"
As an example
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4 name: example
5 namespace: example
6 annotations:
7 cert-manager.io/cluster-issuer: "zerossl-prod"
8
9spec:
10 ingressClassName: nginx
11 tls:
12 - hosts:
13 - www.example.com # replace with your fqdn
14 secretName: www-example-tls
15 rules:
16 - host: www.example.com # replace with your fqdn
17 http:
18 paths:
19 - path: /
20 pathType: Prefix
21 backend:
22 service:
23 name: nginx # replace with your service name
24 port:
25 number: 80
After applying your Ingress configuration the ClusterIssuer would request a certificate from ZeroSSL for www.example.com and place it in the secret www-example-tls. You'd then have secure encryption for your services! You can add multiple hosts and services to one Ingress as long as all of the services and Ingress are in the same namespace.
Conclusion
And that's all! You've now configured cert-manager to automatically issue certificates to your services with ZeroSSL. Feel free to contact me for help or if I should make any corrections to this blog post.
Troubleshooting
If anything goes wrong you can troubleshoot issues in a few ways.
Check ClusterIssuer
To see if the ClusterIssuer was successfully registered run
1kubectl describe clusterissuer zerossl-prod
if everything went smoothly you should see something like this
1 Conditions:
2 Last Transition Time: 2022-01-14T22:40:39Z
3 Message: The ACME account was registered with the ACME server
4 Observed Generation: 1
5 Reason: ACMEAccountRegistered
6 Status: True
7 Type: Ready
Check CertificateRequest
To check the status of the certificate request first find the name of the request
1kubectl get certificaterequest -n <your-ingress-namespace>`
then
1kubectl describe certificaterequest <name-of-certificate-request> -n <your-ingress-namespace`
if everything went smoothly you should see something like this
1Conditions:
2 Last Transition Time: 2022-01-13T15:05:28Z
3 Message: Certificate request has been approved by cert-manager.io
4 Reason: cert-manager.io
5 Status: True
6 Type: Approved
7 Last Transition Time: 2022-01-13T15:08:05Z
8 Message: Certificate fetched from issuer successfully
9 Reason: Issued
10 Status: True
11 Type: Ready