Deploying nginx ingress with let’s encrypt on Kubernetes using Helm

The nginx ingress controller provides an easy way to expose your web applications hosted in Kubernetes to the outside world. There is also a let’s encrypt extension for ingress controllers that requests valid certificates for endpoints that are exposed with an ingress controller. To simplify the installation of these components we are using Helm.

What is Helm?

Helm is a tool for managing Kubernetes charts. Charts are packages of pre-configured Kubernetes resources.
Use Helm to…
Find and use popular software packaged as Kubernetes charts
Share your own applications as Kubernetes charts
Create reproducible builds of your Kubernetes applications
Intelligently manage your Kubernetes manifest files
Manage releases of Helm packages

Installing Helm

If you haven’t installed Helm already you can get it by grabbing a relaese from or running brew install kubernetes-helm. Helm uses kubectl to communicate with your Kubernetes cluster. As the next step you need to install the backend component from Helm into your cluster by running helm init . Call helm version to verify thating every works:

$ helm version 
Client: &version.Version{SemVer:”v2.2.0", GitCommit:”fc315ab59850ddd1b9b4959c89ef008fef5cdf89", GitTreeState:”clean”}
Server: &version.Version{SemVer:”v2.2.0", GitCommit:”fc315ab59850ddd1b9b4959c89ef008fef5cdf89", GitTreeState:”clean”}

Installing nginx ingress controller + let’s encrypt

Fortunately, there is already a offical Helm repo with standard components that ??? you can use like this ingress controller, prometheus and a lots of other interesting charts. This repository is also the root repository for all Helm charts.

Installing nginx-lego(nginx ingress controller + let’s encrypt go) is just running one helm command:

$ helm intall stable/nginx-lego --name nginx-lego --set lego.configmap.email=<your-email>
NAME: nginx-lego
LAST DEPLOYED: Thu Feb 23 11:43:56 2017
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
nginx-lego-nginx-lego 7 1s
==> v1/Service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-lego-nginx-lego-default-backend 10.0.0.150 <none> 80/TCP 1s
nginx-lego-nginx-lego 10.0.0.59 <pending> 80:30635/TCP,443:31385/TCP 1s
==> extensions/v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-lego-nginx-lego 1 1 1 0 1s
nginx-lego-nginx-lego-default-backend 1 1 1 0 1s
NOTES:
This chart runs an nginx-ingress-controller adding the ability to use ingress resources to route in your cluster.
EXAMPLE INGRESS YAML:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: foo
annotations:
# Add to route through the nginx service
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: exampleService
servicePort: 80
path: /
$ helm list                                                                                                                                                                                                      
NAME REVISION UPDATED STATUS CHART NAMESPACE
factual-hedgehog 1 Thu Feb 23 11:28:16 2017 DEPLOYED nginx-lego-0.2.0 default

Now you are able to use the nginx-ingress controller by adding thekubernetes.io/ingress.class: nginx annotation to your ingress resources. Here is a example including an SSL certificate with let’s encrypt:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: echoserver
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- example.com
secretName: example.com-tls
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: webserver
servicePort: 80

Configuring the Helm chart

All configuration options for the nginx-lego chart are described here. You can overwrite them by either writing your own configuration file or setting them in the helm command. The default configuration points to the staging environment of let’s encrypt. To change this we will write our own-values.yamlfile:

lego:
configmap:
email: <your-email>
# Production Let's Encrypt server
url: "https://acme-v01.api.letsencrypt.org/directory"

Updating the nginx controller:

helm upgrade nginx-lego stable/nginx-lego --values=own-values.yaml

Note

nginx-lego will use a cloud provider loadbalancer by default. To change this behaviour set the configuration value nginx.service.type to either ClusterIP or NodePort .