In the past, acquiring SSL certificates, setting up domain names and load balancing HTTP traffic were labor-intensive tasks. With Let’s Encrypt, Nginx and Kubernetes, you can automate a lot of this.

(If you’re just getting started with Kubernetes, read this setup guide.)


kube-lego is a daemon that runs in a cluster. When you deploy an HTTP application into that cluster, kube-lego notices. It requests a new SSL certificate from Let’s Encrypt. This certificate is used for traffic into the HTTP application. Client applications can then connect to your application over HTTPS; which is a necessity for web traffic.

kube-lego only needs to be set up once per cluster. To add kube-lego, grab the files from this repository. Replace <ADMIN_EMAIL> with your email address in configmap.yaml, and apply the directory with kubectl:

kubectl apply -f kube-lego/

That’s it; the kube-lego daemon will now be running in your cluster.

Nginx Ingress Controller

An Ingress object routes traffic into your cluster to the correct application. By default, an ingress enables a Google Cloud Load Balancer. These are some badass, globally available load balancers that can handle an outrageous amount of traffic. You probably don’t need that for most applications, especially development environments.

The Nginx ingress controller is a substitute. Its an application that runs in your cluster and handles routing and load balancing traffic. It’s simple to add an nginx ingress controller; apply the files in this repository.

kubectl apply -f nginx-ingress-controller/

It will take a moment for nginx-ingress-lb to acquire an IP address. During that time, running the command kubectl get services -n kube-system will show something like the following:

NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
default-http-backend   <nodes>       80:32516/TCP                 11d
heapster        <none>        80/TCP                       11d
kube-dns         <none>        53/UDP,53/TCP                11d
kubernetes-dashboard    <none>        80/TCP                       11d
nginx-ingress-lb   <pending>     80:32005/TCP,443:31623/TCP   6s

Where nginx-ingress-lb‘s EXTERNAL-IP is <pending>. Once that <pending> flips to an IP address, note the IP address. Navigate to VPC Network->External IP adresses in the Google Cloud console. Locate the IP address in that list and change it’s type from Ephemeral to Static. (You’ll be prompted for a name which can be whatever you like.)

Using kube-lego and nginx-ingress-controller

To tell Kubernetes that you want to use the Nginx ingress controller instead of the default load balancers, you add an annotation to your ingress object. Likewise, to tell kube-lego that an SSL certificate should be generated, you add another annotation. To enable HTTPS, include the tls field in your ingress object.

Here’s an example:

apiVersion: extensions/v1beta1
kind: Ingress
  name: api-ingress
  namespace: my-app
  annotations: "true" "nginx"
  - hosts:
    secretName: api-ingress-tls
  - host:
      - path: /
          serviceName: api-service
          servicePort: 80

For each application you deploy, create a new ingress including both annotations. The spec.tls.secretName name can be anything, but it must be different for each ingress.

Joe Conway

Founder at Stable Kernel

Leave a Reply

Your email address will not be published. Required fields are marked *