Kubernetes Ingress and Traefik Ingress controller are considered essential components of any Kubernetes cluster for managing and routing external traffic to your Kubernetes services. In this article, we’ll explore the basics of Kubernetes Ingress, and the process of installing Traefik Ingress controller on a Kubernetes cluster, and how you can utilize it to manage traffic in a Kubernetes cluster.
A Kubernetes Ingress is a resource that defines rules for managing external traffic to Kubernetes services. This resource has rules that define how traffic is routed to different Kubernetes services based on criteria such as hostnames, paths, and protocols. An Ingress Controller is a component within Kubernetes that manages incoming traffic to Kubernetes internal services. An Ingress controller is used to manage traffic at Layer 7 (HTTP/HTTPS) and also for terminating SSL/TLS and provide load balancing capabilities.
Main functions of an Ingress Controller:
- Receive incoming external traffic and forwards it to the appropriate Kubernetes backend service.
- Implements routing rules specified in an Ingress resource.
- Handles SSL/TLS encryption and decryption – SSL termination.
- Provides load balancing capabilities to distribute traffic across multiple pods and nodes in a Kubernetes cluster.
There are several Ingress Controllers available for use in Kubernetes environment, and each has its own set of features and capabilities. The one that we’ll use in this article is Traefik Ingress Controller.
Traefik Ingress Controller is a modern, cloud-native, and dynamic Ingress Controller with support for several backends and can be used to manage traffic across multiple Kubernetes clusters. Traefik provides advanced routing capabilities and load balancing features.
Step 1 – Deploy Kubernetes Cluster
A functional kubernetes cluster is required to follow our guide along. Refer to the articles available on the website on how you can deploy a kubernetes cluster;
- Deploy Lightweight Kubernetes Cluster in 5 minutes with K3s
- Deploy HA Kubernetes Cluster on Rocky Linux 8 using RKE2
- Install Kubernetes Cluster on Ubuntu 22.04 with kubeadm
- Install Kubernetes Cluster on Rocky Linux 8 with Kubeadm & CRI-O
- Install Kubernetes Cluster on CentOS 7 with kubeadm
- Deploy Kubernetes on KVM using Flatcar Container Linux
If the setup is working and kubectl
is configured, we can test it by listing available nodes in our Kubernetes cluster.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane 85d v1.24.6
master02 Ready control-plane 85d v1.24.6
master03 Ready control-plane 78d v1.24.6
node01 Ready <none> 85d v1.24.6
node02 Ready <none> 85d v1.24.6
node03 Ready <none> 85d v1.24.6
node04 Ready <none> 78d v1.24.6
node05 Ready <none> 78d v1.24.6
Step 2 – Install and Configure MetalLB
MetalLB is an open-source load balancer solution for Kubernetes. It enables you to use a range of external load balancers to expose your Kubernetes services. It is an ideal solution for Kubernetes clusters running on dedicated hardware, and not in a cloud environment. MetalLB provides Layer 2 load balancing solution for any network infrastructure, and it integrates with Kubernetes to automatically assign IP addresses to services based on their requirements.
We have a guide dedicated to setting up of MetalLB on Kubernetes.
Once the Load Balancer is installed and configured, you can proceed to setup Traefik Ingress Controller on Kubernetes cluster.
Step 3 – Install Traefik Ingress Controller
In this guide, we will install the Traefik Ingress Controller using Helm. Begin by installing Helm as below
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
sudo ./get_helm.sh
Check your version of helm
to confirm it was successfully installed.
$ helm version
version.BuildInfo{Version:"v3.10.2", GitCommit:"50f003e5ee8704ec937a756c646870227d7c8b58", GitTreeState:"clean", GoVersion:"go1.18.8"}
Add the Traefik Ingress helm repository in your workstation by running the commands below.
helm repo add traefik https://helm.traefik.io/traefik
Update helm charts with the commands given below.
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "traefik" chart repository
...Successfully got an update from the "metrics-server" chart repository
...Successfully got an update from the "nfs-subdir-external-provisioner" chart repository
...Successfully got an update from the "kubevious" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Create a namespace called traefik
kubectl create ns traefik
Install the Traefik Ingress Controller using the helm chart on traefik namespace.
helm install traefik traefik/traefik --namespace traefik
Sample output of successful command execution:
NAME: traefik
LAST DEPLOYED: Wed Mar 8 17:33:01 2023
NAMESPACE: traefik
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Traefik Proxy v2.9.8 has been deployed successfully
on traefik namespace !
You can customize the install with a values
file. There are some EXAMPLES provided. Complete documentation on all available parameters is in the default file.
Example:
helm upgrade --install traefik \
--namespace traefik \
--set dashboard.enabled=true \
--set rbac.enabled=true \
--set nodeSelector.node-type=master \
--set="additionalArguments={--api.dashboard=true,--log.level=INFO,--providers.kubernetesingress.ingressclass=traefik-internal,--serversTransport.insecureSkipVerify=true}" \
traefik/traefik \
--version <version>
Verify the installation by checking all resources in the namespace.
$ kubectl get all -n traefik
NAME READY STATUS RESTARTS AGE
pod/traefik-6c77767cfd-pjkt7 1/1 Running 0 5m6s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/traefik LoadBalancer 10.233.26.243 192.168.1.34 80:32715/TCP,443:30295/TCP 5m7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traefik 1/1 1 1 5m7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/traefik-6c77767cfd 1 1 1 5m7s
From the above output, we have a LoadBalancer service with a pending external IP Address. This will be configured later in the guide.
View the Traefik CRDs with the command;
$ kubectl get crd -n traefik | grep traefik
ingressroutes.traefik.containo.us 2023-03-08T14:32:55Z
ingressroutetcps.traefik.containo.us 2023-03-08T14:32:55Z
ingressrouteudps.traefik.containo.us 2023-03-08T14:32:55Z
middlewares.traefik.containo.us 2023-03-08T14:32:55Z
middlewaretcps.traefik.containo.us 2023-03-08T14:32:55Z
serverstransports.traefik.containo.us 2023-03-08T14:32:55Z
tlsoptions.traefik.containo.us 2023-03-08T14:32:55Z
tlsstores.traefik.containo.us 2023-03-08T14:32:55Z
traefikservices.traefik.containo.us 2023-03-08T14:32:55Z
Step 4 – Expose Traefik Dashboard
Check Traefik service to check its Load balancer IP address.
$ kubectl get svc -l app.kubernetes.io/name=traefik -n traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.233.26.243 192.168.1.34 80:32715/TCP,443:30295/TCP 3h43m
We can confirm our load balancer IP address is 192.168.1.34. You can map this in your /etc/hosts
file.
$ sudo vim /etc/hosts
traefik.geeksforgeeks.org 192.168.1.34
Confirm you can ping the IP address using domain name.
$ ping -c 2 traefik.home.cloudlabske.io
PING traefik.home.cloudlabske.io (192.168.1.34): 56 data bytes
64 bytes from 192.168.1.34: icmp_seq=0 ttl=64 time=8.333 ms
64 bytes from 192.168.1.34: icmp_seq=1 ttl=64 time=3.596 ms
--- traefik.home.cloudlabske.io ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 3.596/5.965/8.333/2.369 ms
This HelmChart does not expose the Traefik dashboard by default, for security concerns. Thus, there are multiple ways to expose the dashboard. For instance, the dashboard access could be achieved through a port-forward, Nodeport or via Ingress.
Expose using Port forwarding (Recommended way)
You can gain access to the dashboard through port-forward. To achieve this run the following commands in your workstation where kubectl
is configured.
kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000
You can then access the dashboard on http://127.0.0.1:9000/dashboard/
Expose using Load balancer port
Create a new file with ports exposed for Traefik service.
vim traefik-dashboard-service.yml
This will be used to patch the service. Here we’re adding new entry for port 9000
spec:
ports:
- name: web
port: 80
protocol: TCP
targetPort: web
- name: websecure
port: 443
protocol: TCP
targetPort: websecure
- name: traefik
port: 9000
protocol: TCP
targetPort: traefik
Apply the manifest with --patch
option while providing the file path.
$ kubectl -n traefik patch svc/traefik --patch "$(cat traefik-dashboard-service.yml)"
service/traefik patched
Confirm the service is updated with new port 9000 where the dashboard will be exposed. You can choose any other port as you prefer.
$ kubectl get svc traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.233.26.243 192.168.1.34 80:32715/TCP,443:30295/TCP,9000:30811/TCP 4h3m
From the output we can confirm our Load Balancer IP address to be 192.168.1.34. You can access Traefik web dashboard on this IP directly or via domain name mapped to the IP address in your /etc/hosts
file or actual DNS server.
192.168.1.34 traefik.geeksforgeeks.org
Now that your cluster has an IP address/domain name, you can easily access the Traefik Dashboard and web services. But currently, the service is not available since we do not have any Ingress created.
# curl http://traefik.geeksforgeeks.org
404 page not found
Now proceed and access the Traefik Dashboard using the http://LB_IP:9000/dashboard/
Or the URL http://domain_name:9000/dashboard/ (do not forget to include the slash at the end of the URL)
Step 5 – Protect Traefik Dashboard with basic Auth (Recommended)
Create the custom middlewares used by the IngressRoute dashboard. We can start by downloading the default values file.
wget https://raw.githubusercontent.com/traefik/traefik-helm-chart/master/traefik/values.yaml -O traefik-values.yaml
Edit around line 144 and customize. Alternatively create a new custom values file.
vim custom-traefik-values.yaml
Add the contents given below while setting your own username and password.
# Create an IngressRoute for the dashboard
ingressRoute:
dashboard:
enabled: true
# Additional ingressRoute annotations (e.g. for kubernetes.io/ingress.class)
annotations: {}
# Additional ingressRoute labels (e.g. for filtering IngressRoute by custom labels)
labels: {}
# The router match rule used for the dashboard ingressRoute
matchRule: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
# Specify the allowed entrypoints to use for the dashboard ingress route, (e.g. traefik, web, websecure).
# By default, it's using traefik entrypoint, which is not exposed.
# /!\ Do not expose your dashboard without any protection over the internet /!\
entryPoints: ["traefik"]
# Additional ingressRoute middlewares (e.g. for authentication)
middlewares:
- name: traefik-dashboard-auth
# Create the custom middlewares used by the IngressRoute dashboard (can also be created in another way).
# /!\ Yes, you need to replace "changeme" password with a better one. /!\
extraObjects:
- apiVersion: v1
kind: Secret
metadata:
name: traefik-dashboard-auth-secret
type: kubernetes.io/basic-auth
stringData:
username: admin
password: StrongAdminPassw0rd
- apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-dashboard-auth
spec:
basicAuth:
secret: traefik-dashboard-auth-secret
Upgrade Traefik helm deployment.
$ helm upgrade --values custom-traefik-values.yaml traefik traefik/traefik --namespace traefik
Release "traefik" has been upgraded. Happy Helming!
NAME: traefik
LAST DEPLOYED: Fri Mar 10 12:08:47 2023
NAMESPACE: traefik
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
Traefik Proxy v2.9.8 has been deployed successfully
on traefik namespace !
Reload Traefik dashboard to confirm if password authentication is required.
Provide set username and password to gain access.
Step 6 – Test Traefik Ingress on Kubernetes
Let’s create a sample application to test the functionality of Traefik Ingress on Kubernetes.
vim whoami.yaml
Add the lines below to the file – this defines the deployment of whoami application
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: whoami
name: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- image: traefik/whoami:latest
name: whoami
ports:
- containerPort: 80
Apply the manifest with kubectl
command
kubectl create -f whoami.yaml
Within few seconds the pod should be running, you can check with the commands below.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
traefik-6c77767cfd-pjkt7 1/1 Running 0 18h
whoami-6ff6dcfdc8-q8rcc 1/1 Running 0 11s
Create a service entry file for whoami service
$ vim whoami-service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: whoami-svc
spec:
type: ClusterIP
selector:
app: whoami
ports:
- port: 80
Create the object on Kubernetes by applying the manifest.
kubectl create -f whoami-service.yaml
Confirm service creation was successful.
$ kubectl get svc whoami-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
whoami-svc ClusterIP 10.233.0.100 <none> 80/TCP 2m11s
Now, this application is still not accessible until you create an Ingress to expose the service.
vim whoami-ingress.yaml
Add the below lines and replace the host with the domain name added in /etc/hosts for the external IP address:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-http
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: traefik.geeksforgeeks.org
http:
paths:
- path: /whoami
pathType: Prefix
backend:
service:
name: whoami-svc
port:
number: 80
Create ingress object on kubernetes
kubectl apply -f app-ingress.yaml
View the created Ingress:
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
whoami-http traefik traefik.geeksforgeeks.org 80 57s
Now access the deployment using the URL http://domain_name/whoami
This confirms Traefik to be working as expected in our Kubernetes cluster.
Books For Learning Kubernetes Administration:
Closing Thoughts
In this article we’ve been able to demonstrate how you can install and configure Traefik Ingress Controller in your Kubernetes environment. We were able to test Traefik Ingress setup by sending traffic to the external IP address of the Traefik service and verifying that it is correctly routed to the associated Kubernetes service (whoami). Traefik is a popular open-source load balancer and reverse proxy applicaion that can be used as an ingress controller in Kubernetes to route external traffic to internal services. We hope this article was informative and we would like to appreciate your continued support. Cheers!
See more:
Deploy Nginx Ingress Controller on Kubernetes using Helm Chart
Use Let’s Encrypt SSL Certificates on OpenShift 4.x Ingress / Routes