An Ingress controller is an API that manages external access to the services in a Kubernetes cluster and other containerized environments. Routing traffic around applications in Kubernetes brings challenges and complexities. An ingress controller solves this problem by providing a bridge between the Kubernetes and external services. An Ingress controller can provide load balancing, name-based virtual hosting, and SSL termination
The main tasks performed by an Ingress Controller are:
- Manage egress traffic within a cluster for services that need to communicate with other services outside of a cluster
- Accept traffic from outside the Kubernetes platform, and load balance it to pods (containers) running inside the platform
- Monitor the pods running in Kubernetes and automatically update the load‑balancing rules when pods are added or removed from a service
Traefik Ingress Controller is a Kubernetes ingress controller that manages access to the cluster services by supporting the Ingress specification. It was originally designed to provide a lightweight reverse proxy service but with time, it gained the capability to be integrated with Kubernetes clusters.
There are other alternatives to Traefik that include caddy and ingress-nginx. Traefik Ingress Controller is preferred due to the following features:
- It has a dashboard with a pretty UI
- It is very extensible with middlewares
- It has documentation that is riddled with examples for each provider type, for each feature
- Handles TLS certificate auto-renewal painlessly
In this guide, we will walk through how to install and configure Traefik Ingress Controller on k0s.
Step 1 – Setup Kubernetes Cluster Using k0s
K0S is a new lightweight Kubernetes distribution from Mirantis that ships the bare minimum of extensions. This allows users to customize their preferences such as defining ingress, storage, and configuring the cluster during bootstrap and controllers in the CRD manifest.
To set up a Kubernetes cluster using k0s, use the aid in the guide below:
Once set up, install and configure kubectl using the command:
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin
Allow kubectl to access your cluster/
export KUBECONFIG=/var/lib/k0s/pki/admin.conf
Or set it permanent
mkdir ~/.kube
sudo cp /var/lib/k0s/pki/admin.conf ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
View the available nodes in the cluster:
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 115s v1.26.2+k0s
node1 Ready <none> 75s v1.26.2+k0s
node2 NotReady <none> 61s v1.26.2+k0s
Step 2 – 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
Verify the installation:
$ helm version
version.BuildInfo{Version:"v3.11.1", GitCommit:"293b50c65d4d56187cd4e2f390f0ada46b4c4737", GitTreeState:"clean", GoVersion:"go1.18.10"}
Add the Traefik Ingress helm repo
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
Install the Traefik Ingress Controller using the helm chart.
helm install traefik traefik/traefik
Sample Output:
NAME: traefik
LAST DEPLOYED: Fri Aug 12 17:09:03 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Alternatively, you can install the Traefik Ingress controller with additional parameters as shown:
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:
# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/traefik-f89df87d4-bqqpf 1/1 Running 0 72s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m48s
service/traefik LoadBalancer 10.111.222.143 <pending> 80:30619/TCP,443:32519/TCP 72s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traefik 1/1 1 1 72s
NAME DESIRED CURRENT READY AGE
replicaset.apps/traefik-f89df87d4 1 1 1 72s
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 |grep traefik
ingressroutes.traefik.containo.us 2022-08-12T09:45:05Z
ingressroutetcps.traefik.containo.us 2022-08-12T09:45:05Z
ingressrouteudps.traefik.containo.us 2022-08-12T09:45:05Z
middlewares.traefik.containo.us 2022-08-12T09:45:05Z
middlewaretcps.traefik.containo.us 2022-08-12T09:45:05Z
serverstransports.traefik.containo.us 2022-08-12T09:45:05Z
tlsoptions.traefik.containo.us 2022-08-12T09:45:05Z
tlsstores.traefik.containo.us 2022-08-12T09:45:05Z
traefikservices.traefik.containo.us 2022-08-12T09:45:05Z
Step 3 – Install and Configure MetalLB
MetalLB is a Kubernetes solution that allows the monitoring of services with the LoadBalancer type and assigns them an IP address from a virtual pool. It allows one to access Kubernetes services from a logical IP.
This can be installed using the commands:
git clone https://github.com/techviewleo/metalLB.git && cd metalLB
kubectl apply -f namespace.yaml
kubectl apply -f metallb.yaml
Create the Config map
vim metallb-config.yaml
The file contains a virtual pool with an addressable IP range that works on your local machine.
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.205.40-192.168.205.50
Apply the manifest with the command:
kubectl apply -f metallb-config.yaml
After this, the LoadBalalcer service will have an external IP Address as shown:
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m25s
traefik LoadBalancer 10.111.222.143 192.168.205.40 80:30619/TCP,443:32519/TCP 3m49s
Now update the DNS entry for your domain by adding the provided IP address to /etc/hosts
$ sudo vim /etc/hosts
192.168.205.40 traefik.computingforgeeks.com
Step 4 – Deploy and access the Traefik Dashboard
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.computingforgeeks.com
404 page not found
The Traefik dashboard listens on port 9000 which has not been exposed. To expose it, edit the Traefik service:
kubectl edit svc/traefik
In the opened file, find the ports segment and add the lines below:
ports:
........
- name: traefik
port: 9000
protocol: TCP
targetPort: traefik
......
Save the file and verify if the changes have been made:
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m16s
traefik LoadBalancer 10.106.13.208 192.168.205.40 80:30504/TCP,443:30232/TCP,9000:31827/TCP 13m
Now proceed and access the Traefik Dashboard using the URL http://domain_name:9000/dashboard/ (do not forget to include the slash at the end of the URL)

Step 5 – Test Traefik Ingress on Kubernetes
To test if the Traefik Ingress Controller on k0s is working as desired, we will create a simple application as below;
vim whoami.yaml
Add the below lines to the file:
---
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:
kubectl create -f whoami.yaml
Create a ClusterIP type service for the application
vim service.yaml
Add the lines below:
---
apiVersion: v1
kind: Service
metadata:
name: whoami-svc
spec:
type: ClusterIP
selector:
app: whoami
ports:
- port: 80
Create the service:
kubectl create -f service.yaml
Verify the creation:
# kubectl describe svc whoami
Name: whoami-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=whoami
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.102.149.75
IPs: 10.102.149.75
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.5:80
Session Affinity: None
Events: <none>
Now, this application is still not accessible until you create an Ingress to expose the service.
vim app-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.computingforgeeks.com
http:
paths:
- path: /whoami
pathType: Prefix
backend:
service:
name: whoami-svc
port:
number: 80
Apply the Ingress:
kubectl apply -f app-ingress.yaml
View the created Ingress:
# kubectl get Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
whoami-http <none> traefik.computingforgeeks.com 80 9s
Now access the deployment using the URL http://domain_name/whoami

That is it!
Closing Thoughts
That marks the end of this guide on how to install and configure the Traefik Ingress Controller on k0s. The knowledge gathered here can be used to configure Kubernetes services and access them remotely via a domain name. I hope this was of great significance to you.
See more:
- Deploy Nginx Ingress Controller on Kubernetes using Helm Chart
- Use Let’s Encrypt SSL Certificates on OpenShift 4.x Ingress / Routes
- Install MicroK8s Kubernetes on Rocky Linux 9 / AlmaLinux 9