Ingresses Controllers on k3s
Ingresses Controllers on k3s
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
dashboard
as I was using the URLxyz.com/dashboard
instead ofxyz.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
curl
fu, 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.
Install Nginx as 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 ingress-controller.yaml
. 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:
1 | apiVersion: v1 |
Testing nginx ingress controller
Lets create a new namespace called nginx-test
with 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 Deployment
called test-nginx-dep
, this will deploy a Pod
called nginx-backend
and a Service
called test-nginx-svc
. We’ll also need to deploy a Ingress
resource called 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 Ingress
resource.
Save the below YAML
as a file called example.yaml
:
1 |
|
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.
Conclusion
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.