How To Install Traefik Ingress Controller In Kubernetes

Introduction

This tutorial will show how to use Traefik as an Ingress Controller in Kubernetes (or k8s) to provide load balancing, name-based virtual hosting, and SSL termination.

To follow this tutorial you need:

  • A running Kubernetes cluster or a Managed Kubernetes
  • A Load Balancer that dynamically distributes your traffic to any Kubernetes resource that is marked as LoadBalancer
  • A PRIMARY_DOMAIN
💡
Note: The domain that I use in this post is PRIMARY_DOMAIN, please change accordingly. If your desired domain is paulsblog.dev, replace PRIMARY_DOMAIN with paulsblog.dev.

What is an Ingress Controller?

An Ingress Controller is an API object that will manage external access to any deployed service in a Kubernetes cluster. Typically HTTP or HTTPS is used. Furthermore, it provides load balancing, name-based virtual hosting, and SSL termination.

Why do you need an Ingress Controller?

This list will show the most important benefits of using an Ingress Controller in a Kubernetes cluster:

  • Load balance any traffic between every service that is deployed outside of the Kubernetes cluster
  • Allow HTTP traffic between services within the cluster but enforce HTTPS traffic from outside the Kubernetes cluster while terminating encryption.
  • Simplify interaction between internal services and re-route when required by changing the Ingress Routing Rule.

Prepare Kubernetes Environment

Installing Helm, Kubernetes Package Manager

To install Helm on your Kubernetes cluster you can use the official Helm installer script that will automatically install the latest version.

Before installing Helm, you can get a deeper understanding of Helm if you read about it in the official Helm documentation. Afterward, download the script and execute it locally.

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

Configure kubectl To Access The Kubernetes Cluster

If kubectl is used you can use three different techniques to work with the cluster:

1. Use --kubeconfig flag for every command:

kubectl get pods --kubeconfig=config1
kubectl get pods --kubeconfig=config2

2. Use KUBECONFIG environment variable:

export KUBECONFIG=config1 
kubectl get pods
kubectl get all

export KUBECONFIG=config2
kubectl get pods
kubectl get all

3. Copy the config file to $HOME/.kube/config

Prepare Helm Chart

To install Traefik you have to add the official Traefik Helm repository to your Helm client. This could be done by executing:

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

Afterward, you have to configure the Helm chart by creating a values.yaml. All possible values can be found in the GitHub of the Traefik Helm chart and will be used to set the static configuration of the Traefik proxy.

Now, you should create a values.yaml and paste the following into it:

---
additionalArguments:
  - --entrypoints.websecure.http.tls.certresolver=ionos
  - --entrypoints.websecure.http.tls.domains[0].main=PRIMARY_DOMAIN
  - --entrypoints.websecure.http.tls.domains[0].sans=*.PRIMARY_DOMAIN
  - --certificatesresolvers.ionos.acme.dnschallenge.provider=ionos
  - --certificatesresolvers.ionos.acme.email=webmaster@PRIMARY_DOMAIN
  - --certificatesresolvers.ionos.acme.dnschallenge.resolvers=1.1.1.1
  - --certificatesresolvers.ionos.acme.storage=/data/acme.json

deployment:
  initContainers:
    - name: volume-permissions
      image: busybox:1.31.1
      command: ["sh", "-c", "chmod -Rv 600 /data/*"]
      volumeMounts:
        - name: data
          mountPath: /data

env:
  - name: IONOS_API_KEY
    valueFrom:
      secretKeyRef:
        key: IONOS_API_KEY
        name: ionos-api-credentials

ingressRoute:
  dashboard:
    enabled: false

persistence:
  enabled: true
  path: /data
  size: 128Mi

This values.yaml is used to configure the Traefik proxy and will:

  • use IONOS as the certificate resolver. To find your provider consult the traefik documention
  • set the certificates main domain to PRIMARY_DOMAIN
  • set the certificates sans to *.PRIMARY_DOMAIN
  • store every generated certificate in /data/acme.json
  • run a busybox init container to fix a common permission problem that is explained here: https://github.com/containous/traefik/issues/6972
  • load the IONOS_API_KEY from a secret. If using some other provider add every needed environment variable
  • deactivate the Traefik dashboard
  • enable persistence for the Traefik proxy

Install Traefik Proxy As Ingress Controller

To install Traefik Proxy in your Kubernetes cluster follow the next 4 simple steps

1. Begin with creating a Kubernetes namespace:

kubectl create namespace traefik

2. Create a treafik-secret.yaml that will contain the secret used within the Helm chart for SSL certificate creation:

---
apiVersion: v1
kind: Secret
metadata:
  name: ionos-api-credentials
  namespace: traefik

type: Opaque
stringData:
  IONOS_API_KEY: asdkjalshdasdlasdasd.asdahsdhasdkjahsdkasgdkasdg;aksda;d

3. Apply the secret in your Kubernetes cluster:

kubectl apply -f traefik-secret.yaml

4. Install Traefik using Helm and apply values.yaml

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

If you change anything within the values.yaml and want to update the Traefik proxy this can be done by executing:

helm upgrade traefik traefik/traefik --namespace=traefik --values=values.yaml

Some minutes later your Traefik is deployed correctly and you can map your PRIMARY_DOMAIN A record to the IP of the Traefik Load Balancer. You can find the external IP by executing:

kubectl get all -n traefik

 It should output the following:

Output of kubectl get all within traefik namespace

If the external IP is not set wait some time and retry it. If you did not receive an external IP you probably did not have an external load balancer installed/bought.

Enable Traefik Dashboard

To enable the Traefik Dashboard within the Kubernetes cluster you will have to create an Ingress route and a middleware to enable Basic authentication.

Create a new folder called traefik-dashboard which will contain every file to set up the Traefik dashboard.

Now, create a base64 encoded user and password that will be used within the Kubernetes secret:

htpasswd -nb superTraefikUser unbelievableSafePassword | openssl base64

Afterward, copy the htpasswd string and create the Kubernetes secret 001-auth-secret

---
apiVersion: v1
kind: Secret
metadata:
  name: traefik-dashboard-auth
  namespace: traefik

data:
  users: YOUR_UNBELIEVABLE_SECURE_HTPASSWD_STRING

Then create a Kubernetes middleware 002-middleware that will use the basic auth secret:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: traefik-dashboard-basicauth
  namespace: traefik

spec:
  basicAuth:
    secret: traefik-dashboard-auth

Now you can create the Ingress route 003-ingressroute for the Traefik dashboard:

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: traefik

spec:
  entryPoints:
    - websecure

  routes:
    - match: Host(`traefik.PRIMARY_DOMAIN`)
      kind: Rule
      middlewares:
        - name: traefik-dashboard-basicauth
          namespace: traefik
      services:
        - name: api@internal
          kind: TraefikService

If you named the files as described you should have the following file structure:

traefik-dashboard
--001-auth-secret
--002-middleware
--003-ingressroute

Switch to the upper folder and use the following command to apply all files in the correct order:

kubectl apply -f traefik-dashboard

Closing Notes

I hope this article gave you a quick and neat overview of how to set up Traefik Proxy as an Ingress Controller within your Kubernetes cluster.

Using Helm to set up a Traefik Ingress controller makes it really easy to install, reconfigure, and update the Traefik Proxy.

I would love to hear your feedback about this tutorial. Furthermore, if you already run a Traefik installation and use a different approach please comment here and explain what you have done differently. Also, if you have any questions, please ask them in the comments. I try to answer them if possible.

Feel free to connect with me on Medium, LinkedIn, Twitter, and GitHub.