This post is mainly a note to self 📝📝📝 that describes a quick way to deploy a Kubernetes Ingress Controller with Traefik.
There is also a video version:
We will install Traefik with Helm and I assume the cluster has rbac enabled. If you deploy clusters with AKS, that is the default although you can turn it off. With rbac enabled, you need to install the server-side component of Helm, tiller, using the following commands:
kubectl apply -f tiller-rbac.yaml helm init --service-account tiller
The file tiller-rbac.yaml should contain the following:
apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system
Note that you create an account that has cluster-wide admin privileges. That’s guaranteed to work but might not be what you want.
Next, install the Traefik Ingress Controller with the following Helm one-liner:
helm install stable/traefik --name traefik --set serviceType=LoadBalancer,rbac.enabled=true,ssl.enabled=true,ssl.enforced=true,acme.enabled=true,firstname.lastname@example.org,onHostRule=true,acme.challengeType=tls-alpn-01,acme.staging=false,dashboard.enabled=true --namespace kube-system
The above command uses Helm to install the stable/traefik chart. Note that the chart is maintained by the community and not by the folks at Traefik. Traefik itself is exposed via a service of type LoadBalancer, which results in a public IP address. Use kubectl get svc traefik -n kube-system to check. There are ways to make sure the service uses a static IP but that is not discussed in this post. Check out this doc for AKS. The other settings do the following:
- ssl.enabled: yes, SSL 😉
- ssl.enforced: redirect to https when user uses http
- acme.enabled: enable Let’s Encrypt
- acme.email: set the e-mail address to use with Let’s Encrypt; you will get certificate expiry mails on that address
- onHostRule: issue certificates based on the host setting in the ingress definition
- acme.challengeType: method used by Let’s Encrypt to issue the certificate; use this one for regular certs; use DNS verification for wildcard certs
- acme.staging: set to false to issue fully trusted certs; beware of rate limiting
- dashboard.enabled: enable the Traefik dashboard; you can expose the service via an ingress object as well
Note: to specify a specific version of Traefik, use the imageTag parameter as part of –set; for instance imageTag=1.7.12
When the installation is finished, run the following commands:
# check installation helm ls # check traefik service kubectl get svc traefik --namespace kube-system -w
The first command should show that Traefik is installed. The second command returns the traefik service, which we configured with serviceType LoadBalancer. The external IP of the service will be pending for a while. When you have an address and you browse it, you should get a 404. Result from curl -v below:
Rebuilt URL to: http://IP/ Trying 18.104.22.168… Connected to 22.214.171.124 (IP) port 80 (#0) GET / HTTP/1.1 Host: IP User-Agent: curl/7.47.0 Accept: / < HTTP/1.1 404 Not Found < Content-Type: text/plain; charset=utf-8 < Vary: Accept-Encoding < X-Content-Type-Options: nosniff < Date: Fri, 24 May 2019 17:00:29 GMT < Content-Length: 19 < 404 page not found
Next, install nginx just to have a simple website to securely publish. Yes I know, kubectl run… 🤷
kubectl run nginx --image nginx --expose --port 80
The above command installs nginx but also creates an nginx service of type ClusterIP. We can expose that service via an ingress definition:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: your.domain.com http: paths: - path: / backend: serviceName: nginx servicePort: 80
Replace your.domain.com with a host that resolves to the external IP address of the Traefik service. The annotation is not technically required if Traefik is the only Ingress Controller in your cluster. I prefer being explicit though. Save the above contents to a file and then run:
kubectl apply -f yourfile.yaml
Now browse to whatever you used as domain. The result should be:
To expose the Traefik dashboard, use the yaml below. Note that we explicitly installed the dashboard by setting dashboard.enabled to true.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefikdb annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: yourother.domain.com http: paths: - path: / backend: serviceName: traefik-dashboard servicePort: 80
Put the above contents in a file and create the ingress object in the same namespace as the traefik-dashboard service. Use kubectl apply -f yourfile.yaml -n kube-system. You should then be able to access the dashboard with the host name you provided:
Note: if you do not want to mess with DNS records that map to the IP address of the Ingress Controller, just use a xip.io address. In the ingress object’s host setting, use something like web.w.x.y.z.xip.io where web is just something you choose and w.x.y.z is the IP address of the Ingress Controller. Traefik will also request a certificate for such a name. For more information, check xip.io. Simple for testing purposes!
Hope it helps!