Introduction to Traefik Ingress Controller
It has been quite a while since I wrote my last post related to Traefik. Covid-19 has changed a lot of things including my relationship with Traefik, which I did not expect at all. Because of these changes, I was reluctant to do any new contents for Traefik. However, recently one of my viewers asked me to cover this topic again, I finally made up my mind to write this long waiting post to who you how to use Traefik as Ingress Controller.
If you’ve read my previous posts you would know that Traefik has two types of configurations. The Static Configuration
is used to configuration Traefik itself and the Dynamic Configuration
is used to define how Traefik routes requests to different backend services. Static configurations are set during the installation time and dynamic configuration comes from Ingress, middleware, services that we can create dynamically.
Let’s get started.
Installation
Add Traefik helm repo
Before we start, we need to add Traefik repo.
1 | helm repo add traefik https://helm.traefik.io/traefik |
Install Traefik with Helm
Let’s start by installing Traefik. If you’ve read my blog posts before, you know I tend to use the most simple installation to get you started. Below settings are the things that I believe is essential.
image.tag
: As usual, I like to use the most recent version which is 2.5 at the momentingressRoute.dashboard.enabled
: I don’t need Traefik to create a dashboard for me. I will show you how to do it later on.pilot.dashboard
: This is to disable the notoriousConnect to Traefik Pilot
button. For more discussion, you can read thisGitHub issue
. IMO it should be turn off by default.ports.websecure.tls.enabled
: This is used to enable SSL on websecure entrypoint.ingressClass.enabled
: ingress.class annotation had been officially deprecated, I reckon users should start using ingressClass.
1 | helm upgrade -i traefik traefik/traefik -n traefik \ |
This will create a LoadBalancer service for Traefik. Cloud providers like AWS or Azure normally creates a loadbalancer with an external IP automatically. I am using MetalLB in my environment which also assigns an IP for this service. Let’s call this IP <TRAEFIK_PROXY>
.
Enable Traefik Dashboard
I’ve yet to find a
native
way to create ingress object for Traefik Dashboard so I have to use theirIngressRoute
CRD to access dashboard.
Please save below to dashboard.yaml
.
1 |
|
First thing you will notice is that I’ve created a basicAuth
middleware
because I don’t want to use insecure mode to access dashboard. This middleware
requires reading username and password from Kubernete secret. We will use htpasswd
to generate our username and password string, base64 encoded it and then put it in secret traefik-dashboard-auth-secret.
1 | htpasswd -nb admin qwer1234 | base64 |
Then it is the IngressRoute
. In my config, it matches requests coming to /dashboard/
(the ending /
is critical) and route them to api@internal
service which is our dashboard. PathPrefix(`/api`)
is actually a must because Traefik dashboard needs to read data from this endpoint.
Let’s run kubectl apply -f dashboard.yaml
to apply this file. After that we should be able to access to dashboard at <TRAEFIK_PROXY>/dashboard/
.
Usage
There are two methods to use Traefik Ingress Controller.
- Kubernetes Ingress: Users apply Traefik annotations on native Kuberentes Ingress objects.
- Kubernetes CRD: Users define Traefik CRD objects like IngressRoute, TraefikService or Middleware to route their requests differently. You can find these CRD references here. These CRDs provides extra features on top of native kubernetes resources. For example users can use TraefikServices for server loadbalancing or mirroring the request to different services. If you want to read how these CRDs are defined, you can checl official doc here.
To better understand how these two methods are used, I will show you how to do the same thing with these two methods below.
Preparation
We will create a httpbin deployment as demo app.
- Create httpbin deployment.
1
kubectl create deployment httpbin --image=kennethreitz/httpbin
- Expose this httpbin deployment with
httpbin-svc
service at port 80.1
kubectl expose deployment httpbin --name httpbin-svc --port 80
Once the service is up, we need to route our request to this application.
Kuberenete Ingress
Annotation can be added to native Kubernetes Ingress objects to instruct Traefik how to route requests.
I notice that unlike the other ingress controllers, Traefik does not seem to care if an Ingress Object has
kubernetes.io/ingress.class: traefik
annotation or ingressClass. It will always route the request. With that being said, I still includeingressClassName
in our ingress object.
Create Ingress
Let’s start by creating a simple ingress object. This ingress is pretty straight forward, when the request comes in with host header httpbin.li.traefik
, it routes the request to httpbin-svc
.
1 | apiVersion: networking.k8s.io/v1 |
Please note I’ve set the IP address for
httpbin.li.traefik
to be the same as<TRAEFIK_PROXY>
because Traefik is our entrypoint.
Now when we access this domain, we should see 200 response.
1 | curl http://httpbin.li.traefik/anything -I |
Create Ingress with TLS
TLS management is a big topic. If you’ve read my posts before, you know how much I praise Traefik for making ACME so easy on Docker. However, I would recommend using cert-manager to manage tls certificates on kubernetes in general. You can also check my cert-manager post for more information.
Create Secret
I’ve prepared a self-sign wildcard certificate for*.li.traefik
, let’s create tls secret.1
kubectl create secret tls traefik-cert --cert=li.traefik.ecc.cert.pem --key=li.traefik.ecc.key.pem
Update Ingress Object
Let’s update our ingress object with tls we created.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpbin-route
namespace: default
spec:
ingressClassName: traefik
rules:
- host: httpbin.li.traefik
http:
paths:
- backend:
service:
name: httpbin-svc
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- httpbin.li.traefik
secretName: traefik-cert
We can access this route via both https.
1 | curl https://httpbin.li.traefik/anything -I |
http redirect to https
There are two methods to redirect http to https.
The first methods is to redirect at entryPoint level which is part of static configuration. You can enable it by passing this --set ports.web.redirectTo=websecure
when you are deploying Traefik with helm.
The second method is to use redirectScheme
middleware.
Define Middleware
First we need to define the redirect middleware. I called ithttp-redirect-https
.1
2
3
4
5
6
7
8
9apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: http-redirect-https
namespace: default
spec:
redirectScheme:
scheme: https
permanent: trueApply middleware to ingress
We will use annotation to associate this middleware with our ingress object. The value of the middleware annotion is<middleware-namespace>-<middleware-name>@kubernetescrd
. For more information, please check provider namespace from official doc.1
kubectl annotate ingress httpbin-route traefik.ingress.kubernetes.io/router.middlewares=default-http-redirect-https@kubernetescrd
Now when you access the route via http, you will receive 308 Permanent Redirect response.
1
2
3
4
5
6
7
8curl http://httpbin.li.traefik/anything -IL
HTTP/1.1 308 Permanent Redirect
Location: https://httpbin.li.traefik/anything
Date: Mon, 06 Sep 2021 15:19:01 GMT
Content-Length: 18
Content-Type: text/plain; charset=utf-8
HTTP/2 200
This is a very basic usage of using Traefik annotations on ingress. You can find more annotations on official documentation. Some of them can be used on Ingress object and some can be used on Service object.
Kubernetes CRD
Let’s start by creating exactly the same as above example. Please save below to traefik-crd-demo.yaml
.
I’ve defined
- Middleware
redirectScheme
for http to https redirect - IngressRoute
httpbin-http-route
for http traffic - IngressRoute
httpbin-https-route
for https traffic
1 |
|
If you have read my post about using file provider you probable can see how similar the concept of IngressRoute and file provider are.
Let’s run kubectl apply -f traefik-crd-demo.yaml
to apply this file. After that we should be able to see the same http to https redirects.
1 | curl http://httpbin.li.traefik/anything -LI |
In summary
Personally I prefer native Kubernetes Ingress with annotations as I believe Ingress Controller CRDs should be used to extend the functionalities of native Kubernetes objects not to replace them. Using IngressRoute to replace Ingress might cause more issues sometimes. As you can see from above example, we must create two IngressRoute object to do the same thing that we can achieve with 1 ingress object. IngressRoute CRD does not support cert-manager properly either. As stated on official website. The workaround they mentioned is to use native Kubernetes Ingress with annotations.
When using the Traefik Kubernetes CRD Provider, unfortunately Cert-Manager cannot yet interface directly with the CRDs. A workaround is to enable the Kubernetes Ingress provider to allow Cert-Manager to create ingress objects to complete the challenges.
Users can also achieve most of their features by using annotations. Let’s use official template as an example:
1 | apiVersion: traefik.containo.us/v1alpha1 |
For annotations that can be added to Ingress Object
entryPoints
–>traefik.ingress.kubernetes.io/router.entrypoints
priority
–>traefik.ingress.kubernetes.io/router.priority
middlewares
–>traefik.ingress.kubernetes.io/router.middlewares
tls
->traefik.ingress.kubernetes.io/router.tls
certResolver
–>traefik.ingress.kubernetes.io/router.tls.certresolver
To save us some time I won’t list all of them in this post but you should get the idea.
That’s all I want to share you today. My next post will be focusing on using Kong Ingress Controller. If you are interested, stay tuned.
See you next time.