# Quick overview of Traefik Ingress Controller Installation

- URL: https://baeke.info/2019/05/24/quick-overview-of-traefik-ingress-controller-installation/
- Author: Geert Baeke
- Published: May 24, 2019 (updated June 9, 2019)
- Topics: containers, docker, kubernetes, ingress, kubernetes, traefik
- Outdated: Helm 2 with Tiller, the stable chart repository and xip.io are gone, and Traefik 1.x is end of life.

This post is mainly a *note to self* 📝📝📝 that describes a quick way to deploy a [Kubernetes Ingress Controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) with [Traefik](https://traefik.io/).

There is also a video version:

<div class="video"><iframe src="https://www.youtube-nocookie.com/embed/Nst40Btsdnw" title="YouTube video" loading="lazy" allowfullscreen></iframe></div>

We will install Traefik with [Helm](https://helm.sh/) and I assume the cluster has [rbac](https://kubernetes.io/docs/reference/access-authn-authz/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](https://helm.sh/docs/install/), using the following commands:

```bash
kubectl apply -f tiller-rbac.yaml
helm init --service-account tiller
```

The file **tiller-rbac.yaml** should contain the following:

```yaml
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](https://github.com/helm/helm/blob/master/docs/securing_installation.md).

Next, install the Traefik Ingress Controller with the following Helm one-liner:

```bash
helm install stable/traefik --name traefik --set serviceType=LoadBalancer,rbac.enabled=true,ssl.enabled=true,ssl.enforced=true,acme.enabled=true,acme.email=email@domain.com,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](https://github.com/helm/charts/tree/master/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](https://docs.microsoft.com/en-us/azure/aks/static-ip) 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](https://docs.traefik.io/configuration/acme/#onhostrule): issue certificates based on the host setting in the ingress definition
-   acme.[challengeType](https://docs.traefik.io/configuration/acme/#tlschallenge): 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](https://kubernetes.io/docs/concepts/services-networking/service/). 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 137.117.140.116…
 Connected to 137.117.140.116 (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… 🤷

```bash
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:

```yaml
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:

```bash
kubectl apply -f yourfile.yaml
```

Now browse to whatever you used as domain. The result should be:

![](https://baeke.info/_astro/2019-05-image-45.DibwWrYL_1mGFQh.webp)

*Yes… nginx exposed via Traefik and a Let’s Encrypt certificate*

To expose the Traefik dashboard, use the yaml below. Note that we explicitly installed the dashboard by setting dashboard.enabled to true.

```yaml
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:

![](https://baeke.info/_astro/2019-05-image-46.DMbeuymk_Zxxsa.webp)

*Traefik dashboard*

**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](http://xip.io/). Simple for testing purposes!

Hope it helps!
