Home Self Signed Certificates for kubernetes with Cert Manager and Traefik
Post
Cancel

Self Signed Certificates for kubernetes with Cert Manager and Traefik

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.

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