Traefik

What’s traefik?

Quoting verbatim it’s own definition:

Traefik is an Edge Router, it means that it’s the door to your platform, and that it intercepts and routes every incoming request: it knows all the logic and every rule that determine which services handle which requests (based on the path, the host, headers, and so on …).

But I see it as a hyper-musculated reverse proxy, and they too, because the used reverse-proxy as service name on their documentation.

Adding traefik to my lab

I copied their service definition on the docker-compose.yml I’ve been using for my prometheus tests.

  traefik:
    # The official v2 Traefik docker image
    image: traefik:v2.4
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

And I was able to access the /api/rawdata and see an ugly json text which I didn’t undertand. I thought everything was OK. So I started adding labels to my services:

prometheus:
    ...
    labels:
      - "traefik.http.routers.prometheus.rule=Host(`prometheus.docker.garmo`)"
    ...
    
  cadvisor:
    ...
    labels:
      - "traefik.http.routers.cadvisor.rule=Host(`cadvisor.docker.garmo`)"
    ...
    
  grafana:
    ...
    labels:
      - "traefik.http.routers.grafana.rule=Host(\"grafana.docker.garmo\")"
    ...

  influxdb:
    ...
    labels:
      - "traefik.http.routers.influxdb.rule=Host(`influx.docker.garmo`)"
    ...

And added the choosen names to my /etc/hosts as I don’t have a real domain for my tests, maybe I can set an entry *.lab1.garciaamaya.com on my DNS, but I don’t want to wait for TTL in case I had to do changes.

Troubleshooting

It didn’t work. I couldn’t see the routers on the rawdata json. The first usual suspect is always SELinux. Traefik quick start guide is meant for Ubuntu, and there was no mention of it.

I’m ashamed of doing it, but I tested with setenforce permissive and it worked, so I tested with :z on the docker.sock binding, but it wasn’t useful. A quick googling for a solution pointed me to a serverfault page which mentions a bug report on red hat’s bugzilla stating that is wasn’t a bug, it is a security feature. And the author referenced a blog post he wrote explaining the security concerns of allowing access to docker.sock

Fortunatelly, David Wragg wrote a SELinux policy to allow access. Once applied, traefik is able to access de socket and read the containers.

traefik running

I noticed it displayed all my running containers and also created default http routes using “service dash project” as hostname, but the services were unreachable.

This was not traefik’s fault, is how docker-compose creates the networks for its projects. So the solution was adding my other project’s network to traefik service as a external network.

  traefik:
    ...
    networks:
      - default
      - es-docker_default

networks:
  es-docker_default:
    external: true

And then I was able to access my elasticsearch’s lab node through traefik:

curl -H Host:esmaster00-es-docker http://127.0.0.1/_cat/nodes
192.168.123.166  6 57 0 0.09 0.10 0.12 di - es06
192.168.123.167 10 65 1 0.10 0.47 0.89 mi - esmaster00
192.168.123.166  5 57 0 0.09 0.10 0.12 di - es05
192.168.123.166  5 57 0 0.09 0.10 0.12 di - es03
192.168.123.167  9 57 0 0.10 0.47 0.89 di - es09
192.168.123.166  6 57 0 0.09 0.10 0.12 di - es04
192.168.123.167 10 57 0 0.10 0.47 0.89 di - es08
192.168.123.166 21 63 0 0.09 0.10 0.12 mi - esmaster02
192.168.123.167  8 57 0 0.10 0.47 0.89 di - es07
192.168.123.167  9 57 0 0.10 0.47 0.89 di - es10
192.168.123.167 13 67 1 0.10 0.47 0.89 mi * esmaster01

Conclusion

Traefik is a powerful tool with a lot of features I haven’t explored yet, in following exercises I would like to try:

  • Authentication
  • TLS termination
  • Raw TCP and UDP ports
  • Metrics