In this guide you will learn how to obtain a free wildcard certificate from Let's Encrypt using cert-manager and Okteto's Civo DNS Webhook.

Pre-Requisites

  • A Kubernetes cluster on Civo, you deploy one by using the dashboard or the command line in minutes. You can sign up here.
  • A working KUBECONFIG and kubectl setup. Once you have a new or existing cluster, get your kubectl command-line to point at it and verify that with kubectl config get-contexts. See also: Install and Set Up kubectl.
  • Helm installed. I recommend you use Helm 3, since it's newer and more secure.
  • A domain name you own, added in Civo. If you don't have one, you can register it for little as $2 from namecheap.com or other DNS providers.

Create a Kuberntes cluster

To create a cluster using the Civo CLI, run the following command:

civo k3s create --create-firewall --nodes 1 -m --save --switch --wait cert-manager-demo

This will launch a one-node Kubernetes cluster in your Civo account, the -m flag would merge the kubeconfig for the new cluster with your existing kubeconfig, --switch points your kube-context to the newly created cluster.

Install Cert-Manager

If you're using Civo's managed Kubernetes service, you can directly install cert-manager from the Application Marketplace.

If you are not using Civo's instance, you can install it with the commands below:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml

More information on this is available on cert-manager's installation guide.

Install Okteto's Civo DNS Webhook

When getting a wildcard certificate, Let's Encrypt asks you to prove that you control the DNS for your domain name by putting a specific value in a TXT record under that domain name. This is known as a DNS01 challenge. cert-manager has support for a few providers out of the box, which you can extend via Webhooks. cert-manager doesn't support Civo out of the box, so we went ahead and created one.

To install the webhook, run the commands below:

helm install cert-manager-webhook-civo oci://ghcr.io/okteto/cert-manager-webhook-civo --version 0.5.4

Configuring the Civo DNS Issuer

Issuers are used by cert-manager to identify or authenticate your user with Let's Encrypt and your DNS provider. We'll use a DNS01 issuer to identify you and to create the required DNS records in your Civo DNS domain. The Civo DNS Issuer requires your API Key to be able to create the required DNS records. To retrieve it, sign into your Civo account and go the settings page. You will find your API key in its own section.

Create a secret in your cluster using the commands below:

Retrieve your Civo apikey:

export APIKEY=$(civo apikey show -o json | jq .key)

Create a secret in your cluster using the command below:

kubectl create secret generic civo-dns --namespace=cert-manager --from-literal=key=$APIKEY

Save the below file as issuer.yaml, changing the email field to yours:

kubectl apply -f- <<EOF
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: civo
spec:
  acme:
    email: example@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
    - dns01:
        webhook:
          solverName: "civo"
          groupName: civo.webhook.okteto.com
          config:
            apiKeySecretRef:
              key: key
              name: civo-dns
EOF

And apply it to your cluster:

kubectl apply -f issuer.yaml --namespace=cert-manager

Issue the Certificate

Finally, we'll create the Certificate. Creating it will prompt cert-manager to request a certificate with Let's Encrypt and perform the DNS01 challenge.

Apply the manifest below as replacing the dnsNames fields with the wildcard domains you want for your certificate:

kubectl apply -f- <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-certificate
spec:
  dnsNames:
  - '*.example.com'
  issuerRef:
    kind: Issuer
    name: civo
  secretName: wildcard-example-com-tls
EOF

And apply it: kubectl apply -f certificate.yaml --namespace=cert-manager

Your certificate will be verified after a few minutes. You can check the state of it by running the command below:

kubectl get certificate wildcard-certificate --namespace=cert-manager

Once the certificate is valid, the public and private keys and the CA information will be stored in a secret named wildcard-example-com-tls. The certificate will be valid for 90 days, and it will be renewed automatically by cert-manager.

Wrapping Up

In this guide we installed cert-manager, the Civo DNS Webhook and generated a wildcard certificate for your services. The certificate is valid, and it will be automatically renewed by cert-manager.

You now have a valid wild card certificate in your Kubernetes cluster. You can then use this to validate the identity of any service you have running on that domain.

Contributing

This webhook is open source. If you have an idea or find a bug, feel free to file an issue or submit a PR. All the required information is here.