Home Wildcard Certificates with Traefik + cert-manager + Let's Encrypt in Kubernetes Tutorial
Post
Cancel

Wildcard Certificates with Traefik + cert-manager + Let's Encrypt in Kubernetes Tutorial

Wildcard Certificates with Traefik + cert-manager + Let's Encrypt in Kubernetes Tutorial

Traefik, cert-manager, Cloudflare, and Let’s Encrypt are a winning combination when it comes to securing your services with certificates in Kubernetes. Today, we’ll install and configure Traefik, the cloud native proxy and load balancer, as our Kubernetes Ingress Controller. We’ll then install and configure cert-manager to manage certificates for our cluster. We’ll set up Let’s Encrypt as our Cluster Issuer so that cert-manager can automatically provision TLS certificates and even wildcard certificates using Cloudflare DNS challenge absolutely free. We’ll walk through all of this, step by step, so you can help secure your cluster today.

📺 Watch Video

A HUGE thanks to Datree for sponsoring this video!

Combat misconfigurations. Empower engineers.

https://www.datree.io

Getting Started

If you need to install a new kubernetes cluster you can use my Ansible Playbook to install one.

Resources

You can find all of the resources for this tutorial here

Helm

1
2
3
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

For other ways to install Helm see the installation docs here

Installing

Verify you can communicate with your cluster

1
kubectl get nodes

You should see

1
2
3
4
5
6
NAME     STATUS   ROLES                       AGE   VERSION
k3s-01   Ready    control-plane,etcd,master   10h   v1.23.4+k3s1
k3s-02   Ready    control-plane,etcd,master   10h   v1.23.4+k3s1
k3s-03   Ready    control-plane,etcd,master   10h   v1.23.4+k3s1
k3s-04   Ready    <none>                      10h   v1.23.4+k3s1
k3s-05   Ready    <none>                      10h   v1.23.4+k3s1

Verify helm is installed

1
helm version

You should see

1
version.BuildInfo{Version:"v3.8.0", GitCommit:"d14138609b01886f544b2025f5000351c9eb092e", GitTreeState:"clean", GoVersion:"go1.17.5"}

Traefik

These resources are in the launchpad/kubernetes/traefik-cert-manager/traefik/ folder

Add repo

1
helm repo add traefik https://helm.traefik.io/traefik

Update repo

1
helm repo update

Create our namespace

1
kubectl create namespace traefik

Get all namespaces

1
kubectl get namespaces

We should see

1
2
3
4
5
6
7
NAME              STATUS   AGE
default           Active   21h
kube-node-lease   Active   21h
kube-public       Active   21h
kube-system       Active   21h
metallb-system    Active   21h
traefik           Active   12s

Install traefik

1
helm install --namespace=traefik traefik traefik/traefik --values=values.yaml

Check the status of the traefik ingress controller service

1
kubectl get svc --all-namespaces -o wide

We should see traefik with the specified IP

1
2
3
4
5
6
NAMESPACE        NAME              TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
default          kubernetes        ClusterIP      10.43.0.1       <none>          443/TCP                      16h   <none>
kube-system      kube-dns          ClusterIP      10.43.0.10      <none>          53/UDP,53/TCP,9153/TCP       16h   k8s-app=kube-dns
kube-system      metrics-server    ClusterIP      10.43.182.24    <none>          443/TCP                      16h   k8s-app=metrics-server
metallb-system   webhook-service   ClusterIP      10.43.205.142   <none>          443/TCP                      16h   component=controller
traefik          traefik           LoadBalancer   10.43.156.161   192.168.30.80   80:30358/TCP,443:31265/TCP   22s   app.kubernetes.io/instance=traefik,app.kubernetes.io/name=traefik

Ger all pods in traefik namespace

1
kubectl get pods --namespace traefik

We should see pods in the traefik namespace

1
2
3
4
NAME                       READY   STATUS    RESTARTS   AGE
traefik-76474c4d47-l5z74   1/1     Running   0          11m
traefik-76474c4d47-xb282   1/1     Running   0          11m
traefik-76474c4d47-xx5lw   1/1     Running   0          11m

middleware

Apply middleware

1
kubectl apply -f default-headers.yaml

Get middleware

1
kubectl get middleware

We should see our headers

1
2
NAME              AGE
default-headers   25s

dashboard

Install htpassword

1
2
sudo apt-get update
sudo apt-get install apache2-utils

Generate a credential / password that’s base64 encoded

1
htpasswd -nb techno password | openssl base64

Apply secret

1
kubectl apply -f secret-dashboard.yaml

Get secret

1
kubectl get secrets --namespace traefik

Apply middleware

1
kubectl apply -f middleware.yaml

Apply dashboard

1
kubectl apply -f ingress.yaml

Visit https://traefik.local.example.com

Sample Workload

These resources are in the launchpad/kubernetes/traefik-cert-manager/nginx/ folder

1
2
3
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

Or you can apply an entire folder at once!

1
kubectl apply -f nginx

cert-manager

These resources are in the launchpad/kubernetes/traefik-cert-manager/cert-manager/ folder

Add repo

1
helm repo add jetstack https://charts.jetstack.io

Update it

1
helm repo update

Create our namespace

1
kubectl create namespace cert-manager

Get all namespaces

1
kubectl get namespaces

We should see

1
2
3
4
5
6
7
8
NAME              STATUS   AGE
cert-manager      Active   12s
default           Active   21h
kube-node-lease   Active   21h
kube-public       Active   21h
kube-system       Active   21h
metallb-system    Active   21h
traefik           Active   4h35m

Apply crds

Note: Be sure to change this to the latest version of cert-manager

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml

Install with helm

1
helm install cert-manager jetstack/cert-manager --namespace cert-manager --values=values.yaml --version v1.9.1

Apply secrets

Be sure to generate the correct token if using Cloudflare. This is using an API Token and not a global key.

From issuers folder

1
kubectl apply -f secret-cf-token.yaml

Apply staging ClusterIssuer

From issuers folder

1
kubectl apply -f letsencrypt-staging.yaml

Create certs

staging

From certificates/staging folder

1
kubectl apply -f local-example-com.yaml

Check the logs

1
kubectl logs -n cert-manager -f cert-manager-877fd747c-fjwhp

Get challenges

1
kubectl get challenges

Get more details

1
kubectl describe order local-technotim-live-frm2z-1836084675

production

Apply production ClusterIssuer

From issuers folder

1
kubectl apply -f letsencrypt-production.yaml

From certificates/production folder

1
kubectl apply -f local-example-com.yaml

⚙️ See all the hardware I recommend at https://l.technotim.live/gear

🚀 Don’t forget to check out the 🚀Launchpad repo with all of the quick start source files

This post is licensed under CC BY 4.0 by the author.