Traefik for the Beginners

!
Warning: This post is over 365 days old. The information may be out of date.

In this post, I will explain you how to setup and test traefik. The level of this howto is beginner 😄

In the next episodes, you will see how to use more traefik’s capabilities.

What is traefik ?

Copied from the documentation : Træfik (pronounced like traffic) is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease.

You will find more informations on the Traefik website.

And don’t forget the documentation

Setup your environment

  • First we need to allow our containers to speak to each other. So we will create un docker network :

    $ docker network create test
    
  • Next, we will download the traefik image :

    $ docker pull traefik:1.5-alpine
    1.5-alpine: Pulling from library/traefik
    Digest: sha256:5c45266c0394d74f4e55ecc3bc7f223ff34656bfa0891d4abc53bdb88b8f69bc
    Status: Image is up to date for traefik:1.5-alpine
    

    Note: as the time of writing, the latest stable version was 1.5.

Launch traefik

$ docker run --rm -p 80:80 -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock --network test traefik:1.5-alpine \
         --api --loglevel=debug --entryPoints="Name:http Address::80" \
         --docker --docker.endpoint="unix:///var/run/docker.sock"

You will see something like this :

time="2018-05-04T14:13:39Z" level=info msg="Traefik version v1.5.4 built on 2018-03-15_01:35:21PM"             
time="2018-05-04T14:13:39Z" level=info msg="                                                            
Stats collection is disabled.                                                                
Help us improve Traefik by turning this feature on :)                            
More details on: https://docs.traefik.io/basics/#collected-data                    
"
time="2018-05-04T14:13:39Z" level=debug msg="Global configuration loaded {"LifeCycle":{"RequestAcceptGraceTimeout":0,"GraceTimeOut":10000000000},"GraceTimeOut":0,"Debug":false,"CheckNewVersi
on":true,"SendAnonymousUsage":false,"AccessLogsFile":"","AccessLog":null,"TraefikLogsFile":"","TraefikLog":null,"LogLevel":"debug","EntryPoints":{"http":{"Network":"","Address":":80","TLS":n
ull,"Redirect":null,"Auth":null,"WhitelistSourceRange":[],"Compress":false,"ProxyProtocol":null,"ForwardedHeaders":{"Insecure":true,"TrustedIPs":null}},"traefik":{"Network":"","Address":":80
80","TLS":null,"Redirect":null,"Auth":null,"WhitelistSourceRange":null,"Compress":false,"ProxyProtocol":null,"ForwardedHeaders":{"Insecure":true,"TrustedIPs":null}}},"Cluster":null,"Constrai
nts":[],"ACME":null,"DefaultEntryPoints":["http"],"ProvidersThrottleDuration":2000000000,"MaxIdleConnsPerHost":200,"IdleTimeout":0,"InsecureSkipVerify":false,"RootCAs":null,"Retry":null,"Hea
lthCheck":{"Interval":30000000000},"RespondingTimeouts":null,"ForwardingTimeouts":null,"Web":{"Address":":8080","CertFile":"","KeyFile":"","ReadOnly":false,"Statistics":null,"Metrics":null,"
Path":"/","Auth":null,"Debug":false},"Docker":{"Watch":true,"Filename":"","Constraints":null,"Trace":false,"DebugLogGeneratedTemplate":false,"Endpoint":"unix:///var/run/docker.sock","Domain"
:"","TLS":null,"ExposedByDefault":true,"UseBindPortIP":false,"SwarmMode":false},"File":null,"Marathon":null,"Consul":null,"ConsulCatalog":null,"Etcd":null,"Zookeeper":null,"Boltdb":null,"Kub
ernetes":null,"Mesos":null,"Eureka":null,"ECS":null,"Rancher":null,"DynamoDB":null,"ServiceFabric":null,"Rest":null,"API":{"EntryPoint":"traefik","Dashboard":true,"Debug":false,"CurrentConfi
gurations":null,"Statistics":null},"Metrics":null,"Ping":{"EntryPoint":"traefik"}}"
time="2018-05-04T14:13:39Z" level=info msg="Preparing server http &{Network: Address::80 TLS:<nil> Redirect:<nil> Auth:<nil> WhitelistSourceRange:[] Compress:false ProxyProtocol:<nil> Forwar
dedHeaders:0xc4205e0440} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s"
time="2018-05-04T14:13:39Z" level=info msg="Preparing server traefik &{Network: Address::8080 TLS:<nil> Redirect:<nil> Auth:<nil> WhitelistSourceRange:[] Compress:false ProxyProtocol:<nil> F
orwardedHeaders:0xc4205e0560} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s"
time="2018-05-04T14:13:39Z" level=info msg="Starting server on :80"
time="2018-05-04T14:13:39Z" level=info msg="Starting server on :8080"
time="2018-05-04T14:13:39Z" level=info msg="Starting provider *docker.Provider {"Watch":true,"Filename":"","Constraints":null,"Trace":false,"DebugLogGeneratedTemplate":false,"Endpoint":"unix
:///var/run/docker.sock","Domain":"","TLS":null,"ExposedByDefault":true,"UseBindPortIP":false,"SwarmMode":false}"
time="2018-05-04T14:13:39Z" level=debug msg="Provider connection established with docker 18.03.0-ce (API 1.37)"
time="2018-05-04T14:13:39Z" level=debug msg="Filtering container with empty frontend rule /musing_kalam"
time="2018-05-04T14:13:39Z" level=debug msg="Configuration received from provider docker: {}"
time="2018-05-04T14:13:39Z" level=info msg="Server configuration reloaded on :80"
time="2018-05-04T14:13:39Z" level=info msg="Server configuration reloaded on :8080"

Now i will explain you all the options:

  • -p 80:80 : expose the port 80 for our test
  • -p 8080:8080 : traefik use the port 8080 for it’s API dashboard
  • -v /var/run/docker.sock:/var/run/docker.sock : traefik needs to acces the docker socket, so mount it in the container
  • –network test : use the network previously created
  • –api : tells traefik to enable it’s api dashboard
  • –loglevel=debug : easy to understand 😏
  • –entryPoints=“Name:http Address::80” : tells traefik to listen on port 80 (more about Entrypoints here )
  • –docker : enable the Docker backend (you have another backends : Consul, ECS, Etcd, Rancher, etc)
  • –docker.endpoint=“unix:///var/run/docker.sock” : tells traefik where is the docker socket

Now go to http://localhost:8080 and you will see something like this:

Traefik dashboard

Traefik health

They look empty but it’s normal 😏

Use traefik with Nginx

Now that traefik is up and running, we will launch a nginx container and tell traefik to redirect the http traffic to it.

  • Download the Nginx image :

$ docker pull nginx:latest latest: Pulling from library/nginx f2aa67a397c4: Pull complete 3c091c23e29d: Pull complete 4a99993b8636: Pull complete Digest: sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884 Status: Downloaded newer image for nginx:latest ```

  • Launch the Nginx container :

$ docker run –rm –network test –label traefik.backend=nginx1
–label traefik.port=80 –label traefik.frontend.rule=“Host:test.pea”
–label traefik.frontend.entryPoints=http
nginx:latest ```

The explanations :

*  *--network test* : use the network previously created
* *--label traefik.backend=nginx1* : give the name nginx1 to the generated backend for it's container
* *--label traefik.port=80* : tells traefik that this container is listening on port 80
* *--label traefik.frontend.rule="Host:test.pea"* : it's a *matcher* for traefik. It tells traefik that your container answer to the requests addressed to *pea.test*. More about *matchers* [here](https://docs.traefik.io/basics/#matchers)
* *--label traefik.frontend.entryPoints=http* : tells traefik to use the EntryPoint http for this container
  • Watch the traefik’s logs :

time=“2018-05-04T15:05:34Z” level=debug msg=“Provider event received {Status:start ID:9ee699bff39ff7339cf1f024e3a2009609ff7dc55b2d1bb50ace5a60a6cc2daa From:nginx:latest Type:container Action:start Actor:{ID:9ee699bff39ff7339cf1f024e3a2009609ff7dc55b2d1bb50ace5a60a6cc2daa Attributes:map[image:nginx:latest maintainer:NGINX Docker Maintainers docker-maint@nginx.com name:reverent_sammet traefik.backend:nginx1 traefik.frontend.entryPoints:http traefik.frontend.rule:Host:test.pea traefik.port:80]} Scope:local Time:1525446334 TimeNano:1525446334795866332}” time=“2018-05-04T15:05:34Z” level=debug msg=“Filtering container with empty frontend rule /reverent_curran” time=“2018-05-04T15:05:34Z” level=debug msg=“Could not load traefik.frontend.whitelistSourceRange labels” time=“2018-05-04T15:05:34Z” level=debug msg=“Could not load traefik.frontend.auth.basic labels” time=“2018-05-04T15:05:34Z” level=debug msg=“Validation of load balancer method for backend backend-nginx1 failed: invalid load-balancing method ‘’. Using default method wrr.” time=“2018-05-04T15:05:34Z” level=debug msg=“Configuration received from provider docker: {“backends”:{“backend-nginx1”: {“servers”:{“server-reverent_sammet”:{“url”:“http://172.22.0.3:80”,“weight”:0}},“loadBalancer”:{“method”:“wrr”}}},“frontends”: {“frontend-Host-test-pea-0”:{“entryPoints”:[“http”],“backend”:“backend-nginx1”,“routes”:{“route-frontend-Host-test-pea-0”:{“rule”:“Host:test.pea”}}, “passHostHeader”:true,“priority”:0,“basicAuth”:[]}}}” time=“2018-05-04T15:05:34Z” level=debug msg=“Creating frontend frontend-Host-test-pea-0” time=“2018-05-04T15:05:34Z” level=debug msg=“Wiring frontend frontend-Host-test-pea-0 to entryPoint http” time=“2018-05-04T15:05:34Z” level=debug msg=“Creating route route-frontend-Host-test-pea-0 Host:test.pea” time=“2018-05-04T15:05:34Z” level=debug msg=“Creating backend backend-nginx1” time=“2018-05-04T15:05:34Z” level=debug msg=“Creating load-balancer wrr” time=“2018-05-04T15:05:34Z” level=debug msg=“Creating server server-reverent_sammet at http://172.22.0.3:80 with weight 0” time=“2018-05-04T15:05:34Z” level=info msg=“Server configuration reloaded on :80” time=“2018-05-04T15:05:34Z” level=info msg=“Server configuration reloaded on :8080” ```

Everything is fine ! The Nginx container is well detected by Traefik.
  • What’s about the API dashboard ?

Traefik dashboard with Nginx container

  • Test !!

    Of course, for this example, I have edited my /etc/hosts and added this line:

    127.0.0.1 test.pea
    

$ curl -I http://test.pea HTTP/1.1 200 OK Accept-Ranges: bytes Content-Length: 612 Content-Type: text/html Date: Fri, 04 May 2018 15:21:06 GMT Etag: “5acb8e45-264” Last-Modified: Mon, 09 Apr 2018 16:01:09 GMT Server: nginx/1.13.12 ```

After a couple of tests, go to the API dashboard and look at the *Health* section :

Traefik health after a couple of tests

Conclusion

Now you know how to test traefik. It’s very powerfull. In the next posts, we will see more options : https, more matchers, restrictions, etc..

Stay tuned 😏

Related Posts