Deploying Traefik as Ingress Controller on Kubernetes
Traefik is a powerful cloud-native edge router that can be utilised in many different environments, the most popular being Kubernetes and Docker. The built-in ACME client, amongst other features, makes Traefik a great choice as an edge router.
Traefik has two types of configuration: Dynamic configuration, which is set on the Kubernetes services we want to expose as annotations, and static configuration, which configures Traefik itself.
The first configuration that needs to be defined is the static configuration, used when Helm installs Traefik. The static configuration can be declared using CLI, YAML or TOML. In this case, we will use YAML.
First, set Traefik as the default Ingress Controller for Kubernetes:
ingressClass: enabled: true isDefaultClass: true
Disable the Traefik dashboard. The dashboard is not something we want to expose to the internet:
ingressRoute: dashboard: enabled: false
Configure Traefik to obtain SSL certificates from LetsEncrypt. Because we are using HTTP verification, ensure your domain name is already pointing to the IP address your Kubernetes cluster will be exposed on.
additionalArguments: - --certificatesresolvers.letsencrypt.acme.caServer=https://acme-v02.api.letsencrypt.org/directory - --certificatesresolvers.letsencrypt.acme.httpChallenge.entryPoint=web - --certificatesresolvers.letsencrypt.acme.storage=/ssl-certs/acme-generic.json
The certificate issued by LetsEncrypt is saved in /ssl-certs/acme-generic.json. Use a persistent volume to save and re-use this certificate across new Traefik containers:
persistence: enabled: true name: ssl-certs size: 1Gi path: /ssl-certs
Sometimes, there can be permission issues when Traefik tries to save or read the certificate from the persistent volume. Deploying this busybox container will ensure the permissions are correct within the volume:
deployment: initContainers: - name: volume-permissions image: busybox:1.31.1 command: ["sh", "-c", "chmod -Rv 600 /ssl-certs/*"] volumeMounts: - name: ssl-certs mountPath: /ssl-certs
Lastly, the ports used to connect to Traefik from the internet need to be configured. By default, the Traefik Helm chart refers to port 443 as websecure, and port 80 as web. We can configure web traffic on port 80 to be redirected to port 443, to ensure all web traffic to Traefik is encrypted. We can also define which certificate resolver to use on port 443:
ports: web: redirectTo: websecure websecure: tls: enabled: true certResolver: letsencrypt
Additional configuration options and default values for Traefik’s static configuration when installing with Helm can be found in the Traefik Helm chart GitHub.
To install Traefik with your static configuration YAML file with Helm:
- Add the Traefik Helm repo:
helm repo add traefik https://helm.traefik.io/traefik
- Update the Helm chart repository:
helm repo update
- Install the Traefik Helm chart with your static configuration file:
helm install traefik/traefik -values traefik-static-configuration.yaml
After Traefik has been installed, we can use Traefik to expose Kubernetes services.
First of all, we need to define a Kubernetes deployment. For example, an Nginx deployment exposed on port 5000:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 5000
Next, we need to define a ClusterIP service:
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: ClusterIP ports: - port: 5000 targetPort: 5000 selector: app: nginx
Lastly, we create an Ingress definition which includes the Traefik dynamic configuration:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress spec: rules: - host: "cloudcover.ch" http: paths: - path: / pathType: Prefix backend: service: name: nginx port: number: 5000
A big thank you to The Digital Life on YouTube, who provide templates for this deployment method on their GitHub page.