Kubernetes - Ingress controller with Cloudflare

Cloudflare TLS
Cloudflare allows us to hide our server IPs, cache our static assets, protect the servers them from some attacks. To do that, they offer a Proxy service for free.

First steps

Ingress controller

For this article, I consider that we already have an ingress controller in our kubernetes cluster. For instance, my microk8s cluster uses the default nginx controller, which can be installed with the command microk8s.enable ingress.

FYI, microk8s is a simple kubernetes solution developed by Canonical. It’s powerful and easy to deploy. I deployed mine on a single Vultr VPS instance, for example.

Cloudflare

First, sign-up to Cloudflare, their website will guide you through this setup.
If you haven’t any record on your DNS, try to add an A record that points to your own server (mine points to my microk8s cluster).

Setup the encryption

Cloudflare will automatically create a TLS certificate for connections between the end users and Cloudflare. But we need to setup the encryption between Cloudflare and our servers. It’s optional, but highly recommended. AND, it’s way easier to use this method, than using Let’s encrypt with certbot on our kubernetes cluster.

Generate some certificates

Follow this guide to create a new “Cloudflare origin CA certificate”.

If we follow the steps from the guide, we should get a certificate and a private key, copy-paste them into two files: origin-ca.crt and origin-ca.pk.

Certificate: origin-ca.crt
1
2
3
4
-----BEGIN CERTIFICATE-----
BLABLABLABLABLABLABLABLABLABALBLABLA
BLABLABLABLABLABLABLABLABLABALBLABLA
-----END CERTIFICATE-----
Private key: origin-ca.pk
1
2
3
4
-----BEGIN PRIVATE KEY-----
BLABLABLABLABLABLABLABLABLABALBLABLA
BLABLABLABLABLABLABLABLABLABALBLABLA
-----END PRIVATE KEY-----

Install the certificates in our K8s cluster

We’ll store this certificate in a TLS secret. Make sure you create the secret in the namespace that your ingress lives in.

1
kubectl create secret tls cloudflare-tls --key origin-ca.pk --cert origin-ca.crt

You should get the following response:

OUTPUT
1
secret/cloudflare-tls created

Then, make sure you add the correct secretName in your ingress definition file.

ingress.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: default-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- ilightshow.app
secretName: cloudflare-tls # <----------- HERE
rules:
- host: ilightshow.app
http:
paths:
- path: /
backend:
serviceName: nginx-deployment
servicePort: 80

Setup Cloudflare to use this method

Then, go to the TLS/SSL settings from the cloudflare dashboard and make sure it’s configured to use the “Full (strict)” mode. Using this method, we’ll have a certificate that will last for 15 years in between Cloudflare and our servers. In conclusion, it’s way easier than using a certbot, and more secure! 😎