Enabling Cloudflare in front of your Kubernetes cluster with Traefik
- kubernetes traefik cloudflare
I’m still using my arm64 4 nodes cluster for experimentation and even to serve some websites. Since I wanted to test some new Cloudflare features, I migrated one of my domain which has a bunch of websites on it.
But first a quick and simple way to serve some static pages:
Serving Static Pages
One way is to build an image with the actual pages in it and let Kubernetes serves them.
Separate your websites into directories:
ls www
mysite.com subsite.mysite.com mysuperothersite.com
Using Caddy as base image, create a Dockerfile
:
FROM caddy:2
COPY Caddyfile /etc/caddy/Caddyfile
ADD www/ /srv/
Create the proper Caddyfile
:
{
email youremail@yourdomain.com
auto_https off
}
mysite.com:80 {
root * /srv/mysite.com
file_server
}
subsite.mysite.com:80 {
root * /srv/subsite.mysite.com
file_server
}
...
Caddy 2 enabled https by default, in our case we don’t want https to be enabled in those pods since the ingress will deal with it. Create your deployment and service, and let the ingress knows about it, in my case Traefik:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: websites-ingress
namespace: web
spec:
entryPoints:
- websecure
routes:
- match: Host(`mysite.com`) || Host(`subsite.mysite.com`) || Host(`mysuperothersite.com`)
middlewares:
- name: compress
kind: Rule
services:
- name: websites
port: 80
Cloudflare and Traffic Encryption
Remember Cloudflare will proxy all the requests back to your cluster, it means you don’t need to have publicly valid certificates anymore (like Let’s encrypt), but Cloudflare will provide you with a certificate to sign the exchange between them and your ingress.
Go to your Cloudflare admin interface in SSL/TLS, then Origin Server, create a certifcate.
Store the public key in origin.pub
the private part in origin.key
.
As mentioned in Traefik documentation with Kubernetes the certificates can and must be provided by secrets.
Let’s create a secret in the correct Traefik namespace
kubectl -n kube-system create secret generic default-certificate --from-file=tls.crt=./origin.crt --from-file=tls.key=./origin.key
And point Traefik default store to the secret:
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: kube-system
spec:
defaultCertificate:
secretName: default-certificate
You can now enable Cloudflare full (strict) mode:
Encrypts end-to-end, but requires a trusted CA or Cloudflare Origin CA certificate on the server.
Common pitfalls
Beware of the difference between store and certResolver:
On your IngressRoute
you probably had a certResolver to handle let’s encrypt.
tls:
certResolver: default
On the domain handled by Cloudflare you need the default store (which is now the default).
tls:
store:
name: default