I have quite a few internal only services running on my Kubernetes cluster. For all these services I wanted to use SSL, but using the default method of getting an ACME certificate from Let’s Encrypt (HTTP-01) wouldn’t work due to my setup. I also didn’t want to have to generate a certificate for every service I decided to spin up. Using cert-manager
I was able to generate an ACME wildcard certificate and then set it to the default certificate on the nginx-ingress
.
First install cert-manager
using helm.
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
$ helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.6.1 --set installCRDs=true --set prometheus.enabled=false
Next, look at the cert-manager documentation to see if your DNS provider works with cert-manager. Depending on your DNS provider your setup here will look different. As an example I will show my setup using Cloudflare.
First I had to create a secret that had my Cloudflare API key set in it:
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
type: Opaque
stringData:
api-token: lksdjlfksjdlkfjslkfdj
Then I created an issuer that used Cloudflare as the DNS solver:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: [email protected]
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- dns01:
cloudflare:
email: [email protected]
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
Here is where it deviates from the normal usage of cert-manager
and ingresses. Instead of specifying a HTTPS entry on every one of my ingress resources, I created a general wildcard certificate:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: binaryronin-wildcard
spec:
secretName: binaryronin-wildcard
dnsNames:
- '*.binaryronin.io'
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
Then, I edited the nginx deployment and set the certificate as the default certificate:
...
spec:
containers:
- args:
- --default-ssl-certificate=cert-manager/binaryronin-wildcard