Auto provisioning Let’s Encrypt wildcard certificates with cert-manager on GKE

Google Cloud Platform offers Google Managed Certificates for External Load Balancers and GKE Ingress but does not currently support the ability to manage wildcard certs. If you are looking to have Google manage your *.example.com certificate then you are out of luck until the feature becomes available.

This guide outlines how to use cert-manager on GKE to automatically provision a wildcard certificate when your Ingress resource gets created. Cert-manager will perform domain verification, request the certificate from Let’s Encrypt, and handle auto-renewing your certificate before the 90 day expiration date.

Prerequisites:

  • Requires GKE version v1.16.0 or greater
  • Requires a running GKE cluster

I will be doing these steps in Cloud Shell. Cloud shell can be accessed through the GCP console by clicking the Cloud Shell icon on the upper right corner of the console as detailed in the screenshot below.

Cert-manager installation:

Once the cloud shell loads up you need to get credentials to connect to your running GKE cluster.

Create a namespace where cert-manager will live.

Create a ClusterRoleBinding to give yourself permissions to deploy cert-manager on the cluster

Install the latest cert-manager into your cluster. (to find out the latest release of cert-manager go to the cert-manager Releases Page)

After a few minutes you should see it running on your cluster (yours will have different names)

Create the DNS zone if not created yet:

For this guide I created a new zone for my domain in Google Cloud DNS. It is possible that you already have a zone somewhere for your domain and if so you can skip this part. You need a DNS zone to validate you are the owner of the domain for certificate verification. Getting wildcard certificates from Let’s Encrypt requires DNS validation.

To create a public zone on Cloud DNS follow this guide.

Create a GCP service account and download the key:

(You only need to do this if you are using Google Cloud DNS for validation)

You need to create a GCP service account that has access to add a TXT record to your DNS zone. The ClusterIssuer will use it to access Cloud DNS from the K8s cluster and automatically create a TXT record in order to validate you own the domain.

Note: The use of the dns.admin role in this example role is for convenience. If you want to ensure cert-manager runs under a least privilege service account, you will need to create a custom role with the following permissions:

  • dns.resourceRecordSets.*
  • dns.changes.*
  • dns.managedZones.list

Create a kubernetes secret from your newly created service account credentials:

I am using Google Cloud DNS to validate my certs but if you are using Cloudflare or Route53 or something else you need to follow the instructions to add API tokens to secrets instead of the service account.

This secret is used by the ClusterIssuer to add a TXT record to Google Cloud DNS for cert validation.

Create the ClusterIssuer:

The ClusterIssuer is the part of cert-manager that tells cert-manager where to get the cert. For this we are using Let’s Encrypt. It also contains the information about what DNS provider you are using and how to authenticate to it. In this example we are using Cloud DNS but there are other solvers that can be plugged into this including Cloudflare and Route53.

Now apply the ClusterIssuer

And you can check and see if it successfully registered you to let’s encrypt by describing.

Create your deployment and service:

Now you will create your deployment and service for your application.

For this example I deploy a simple hello-app

And expose a service of type NodePort

Create your GKE Ingress and get your managed wildcard cert at the same time:

The best part of cert-manager is it automatically adds a TXT record to your DNS and validates and issues a cert from Let’s Encrypt when you create an Ingress resource in GKE. It also auto-renews the certificate for you. Wildcard domain certificates (those covering *.yourdomain.com) can only be requested using DNS validation.

It can take over an hour to get your cert. To check the status of the certificate do

If READY shows False you probably have to wait longer. You can check the status of the cert process for errors by checking the logs of the cert-manager container.

Get the name of the cert-manager pod

Check the logs of the cert-manager pod

You will see errors here if something went wrong. You can also check your DNS provider to see if the TXT record got inserted. If it did then the validation is still going and you need to wait a bit longer.

After a while you should get a public IP from the Load Balancer

Change your DNS to point to the new Public IP created by the Ingress

You can then change your DNS to point to this new IP address.

You might want to edit your local hosts file first to make sure things work okay before moving your DNS over.

I do Cloud architecture, Kubernetes, Service Mesh, CI/CD and other cloud native things. Customer Engineer at Google Cloud. Opinions stated here are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store