An ingress controller is a special loadbalancer on kubernetes. It accepts traffic from outside kubernetes (k8s) and routes it to resources inside k8s.
By default kubernetes installations don’t come with an ingress controller. K3s however, does come with Traefik by default.
Traefik is an open sourced edge router, it automatically discovers the configuration (based on labels and ingress definitions) and routes as requested. However, after trying out the default Traefik installation, I ran into a series of noob problems that soured my experince:
- I struggled to reach the default
dashboardas I was using the URL
xyz.com/dashboard/. The trailing
/was needed to trigger the router. I’m sure there’s some way to disable or change this, but as someone new to Traefik, it was annoying.
- I wanted to expose a self-hosted homepage called Flame. The route was discovered as expected, the setup looks great but I kept hitting a blank page. After some
curlfu, it seems like there were some header shenanigans going on that prevented JS from loading. I was able to find a few issues online hitting the same issue, however most solutions seem to use Nginx behind Traefik or using some Middleware service to fix the headers before routing. Again, extremely overwhelming for a noob to Traefik.
Having used Nginx and HAProxy extensively in the past, I didn’t see a real reason to stick with Traefik and its potential unknowns any longer. So I got rid of my existing cluster with the default Traefik (an easy action thanks to
pulumi) and setup a new cluster with the flag
--disable=traefik during the
k3s server setup process. This would setup k3s without a default ingress controller.
Once the new k3s cluster is setup, check again that there indeed is no ingress controller. Once checked, we’d want to go to the Nginx bare metal setup docs found here.
There’s a simple in the above URL, fetch it and save it on a local file called
kubectl apply -f said file to specify all the required components. To make it a bit more transparent, I fetched the file and saved it in my local git repo to be a bit more explicit as to what is deployed on the cluster.
We still need a entrypoint, so lets depoy one:
Lets create a new namespace called
kubectl create namespace nginx-test. We’ll deploy all the required resources for the test in this namespace.
Now we will attempt to deploy a
test-nginx-dep, this will deploy a
nginx-backend and a
test-nginx-svc. We’ll also need to deploy a
test-nginx-ingress, this will specify the
host to listen on and the
path as well as the backend to route the request to. The
IngressController will then route the request specified by the
Save the below
YAML as a file called
Note: Ensure that the URL specified in
host actually routes to your k3s cluster. I achieved this by setting a DNS rule on my router to resolve
xyz.com to my cluster. The same can be achieved by modifying
/etc/hosts on a linux machine.
Apply the file with:
kubectl apply -n nginx-test -f example.yaml. This should create all the resouces required. You can now navigate to
xyz.com on your machine to see the Nginx default landing page - indicating that the nginx
IngressController picked up the
Ingress route and passes traffic as expected.
We switched the k3s cluster from the default Traefik to a Nginx ingress controller and we will now use Nginx for exposing future services as well as configuring SSL certificates.