Introduction
In this document, we are going to look at the steps on how we can configure traefik with cert manager to generate self signed certificates for my kubernetes services.
Previously, I have also outline how we can set up traefik for containers to generate self signed certificates services deployed in a containerized environments.
Self Signed Certificates and DNS Setup using Traefik
Pre Requisites
Before we start with the installing and configuring anything, we need to install or make sure that we have metal lb configured and running within our kubernetes environment.
Metal LB
We can install metal lb using the following helm commands
1
2
3
4
5
6
7
8
## Add Metal LB helm chart
helm repo add metallb https://metallb.github.io/metallb
## Update helm repos
helm repo update
## Install Metal LB
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
The following is the Metal LB configuration file that I used,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- <IP Ranges> # Choose an unused IP range in your network
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: advert
namespace: metallb-system
Traefik
Before moving on to Cert Manager for certificates, We will have to install traefik for load balancing and will act as a reverse proxy for my services.
We will be using helm for installing the traefik repository,
1
2
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
We also need to create a namespace for traefik
1
kubectl create namespace traefik
verify the namespaces created using,
1
kubectl get namespaces
the following helm command to traefik. Now, we can install the default traefik, but I had to customize based on my requriement, which can be done by modifying the values.yaml
file.
1
helm install --namespace=traefik traefik traefik/traefik --values=values.yaml
Once all the pods are deployed and are running, you can check the external IP assigned to traefik service. This IP must be specified in the values.yaml
. Also, this IP should be in the range specified in the Metal LB.
Now that we have traefik up and running, Lets move on to create wild card certificates
Cert Manager
Add the cert manager helm repo (make sure to udpate the version, current version is 1.17)
1
helm repo add jetstack https://charts.jetstack.io
Create a namespace for cert-manager
1
kubectl create namespace cert-manager
Before we install cert manager, we have to make sure that all the CRDs are installed for cert manager to be installed and configured properly.
1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
After installing the CRDs, we can go ahead and install cert manager with helm. Similar to traefik, we can use values.yaml
file to customize the configuration
1
helm install cert-manager jetstack/cert-manager --namespace cert-manager --values=values.yaml --version v1.9.1
Now, we need to generate a token in cloudflare that this instance of cert manager can use to verify domain by creating some dummy DNS records within our Zone. The API would need Zone: Read
and DNS:Edit
permission to do this verification.
We can create a kubernetes secret with this token
1
kubectl apply -f secret-cf-token.yaml
Kubernetes uses its secrets in order to create and manage certs in our kubernetes environment. Let’s create an issuer and a certificate related to that in cloudflare’s staging environment. (As there is an API rate limit to the production endpoint, we will test with staging and migrate to production)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: <NAME>
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: <EMAIL_ACCOUNT>
privateKeySecretRef:
name: <NAME_FOR_CERT>
solvers:
- dns01:
cloudflare:
email: <CLOUDFLARE_EMAIL>
apiTokenSecretRef:
name: <CLOUDFLARE_TOKEN_SECRET_NAE>
key: cloudflare-token
selector:
dnsZones:
- "<DNS_ZONE_NAME>"
The yaml of my certificate would look something like
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: <NAME>
namespace: default
spec:
secretName: <SECRET_NAME>
issuerRef:
name: <ISSUER_CREATED_ABOVE>
kind: ClusterIssuer
commonName: "TOP_LEVEL DOMAIN"
dnsNames:
- "DOMAIN/SUB_DOMAIN_FOR_CERTIFICATE"
Now, we can apply these files. Now when we create any new service, we need to create an ingress route, which will let cert manager and traefik know that we are trying to reach them on a certain domain.