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