Traefik Migrating V1 to V2
Traefik
Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience. It receives requests on behalf of your system and finds out which components are responsible for handling them.
source: https://docs.traefik.io/
Why Traefik?
Traefik is a great solution when using container platforms such as Docker Swarm, Kubernetes, Openshift, etc. It has a great Auto Discover solution, and the use of configuration labels makes it easier to configure and implement when using Docker Swarm.
About this article
At Gonkar we have some customers running their workload on Docker Swarm clusters solutions. Docker Swarm is a great solution when your work load does not require advanced configuration and also it helps to keep it simple.
Recently the Traefik released their new version Traefik v2.1. It introduces new features like Consul Catalog, Load Balancing Mirroring, More Control in Internal Routing and much more.
In our case, we were running Traefik v1.7.x, and after the release of v2.1, we felt that the branch 2.x is mature enough to start some migration work in our test environment.
What I need to know?
When migrating from v1.7.x to v2.x, we have a significant change in how Traefik works and is being configured. It means that commands to start Traefik service changed as well as the Docker labels.
Command arguments
What we did to update our commands in our Traefik Docker Swarm deployment was to use the help from the Traefik service.
Docker:docker run traefik:2.1 --help
Podman:podman run traefik:2.1 --help
It is great if we start getting used to Podman since Kubernetes and Openshift are moving in that direction, and the commands are basically the same as docker
With the above command we will see all the new options we have to pass to our Traefik instance.
Something that can help, is if you are looking the command arguments for Docker provider you could just use grep to simplify the search.
podman run traefik:2.1 --help | grep docker
--providers.docker (Default: "false")
--providers.docker.constraints (Default: "")
--providers.docker.defaultrule (Default: "Host(`{{ normalize .Name }}`)")
--providers.docker.endpoint (Default: "unix:///var/run/docker.sock")
--providers.docker.exposedbydefault (Default: "true")
--providers.docker.network (Default: "")
--providers.docker.swarmmode (Default: "false")
--providers.docker.swarmmoderefreshseconds (Default: "15")
--providers.docker.tls.ca (Default: "")
--providers.docker.tls.caoptional (Default: "false")
--providers.docker.tls.cert (Default: "")
--providers.docker.tls.insecureskipverify (Default: "false")
--providers.docker.tls.key (Default: "")
--providers.docker.usebindportip (Default: "false")
--providers.docker.watch (Default: "true")
In this way we can find the new arguments used in v2.x and update our existent v1.7.x config.
Here I shared our stable Docker Compose for Traefik v2.1
version: '3.7'
services:
traefik:
image: traefik:2.1
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
command: >
--api
--log.level=INFO
--accesslog=true
--metrics.prometheus=true
--providers.docker=true
--providers.docker.endpoint=unix:///var/run/docker.sock
--providers.docker.swarmMode=true
--providers.docker.exposedbydefault=false
--providers.docker.network=traefik-net
--entrypoints.http.address=:80
--entrypoints.https.address=:443
--certificatesResolvers.certbot=true
--certificatesResolvers.certbot.acme.httpChallenge=true
--certificatesResolvers.certbot.acme.httpChallenge.entrypoint=http
--certificatesResolvers.certbot.acme.email=hostmaster@example.com
--certificatesResolvers.certbot.acme.storage=/certs/acme-v2.json
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /data/traefik/certs:/certs
networks:
- traefik-net
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
labels:
# v2.1
- "traefik.docker.network=traefik-net"
- "traefik.enable=true"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
# Http
- "traefik.http.routers.traefik.rule=Host(`ingress.traefik.example.com`)"
- "traefik.http.routers.traefik.entrypoints=http,https"
# Enable Let's encrypt auto certificat creation
- "traefik.http.routers.traefik.tls.certresolver=certbot"
# Enable authentification
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:HASH"
# Redirect All hosts to HTTPS
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls"
networks:
traefik-net:
driver: overlay
name: traefik-net
Our config is set up to work with Docker Swarm provider, enabling the API and Dashboard you could access as it appears in our example going to https://ingress.traefik.example.com.
Labels
Labels will define how we want our service to be integrated with Traefik. Basically, we will configure our routers and middlewares in order to pass to Traefik parameters such as hostname, ports, redirects, etcs.
In our case, what we did and what we recommend is to check the official documentation. There are two links there that I recommend:
https://docs.traefik.io/migration/v1-to-v2/
This link helps compare the labels between both versions and also shows some configs
https://docs.traefik.io/user-guides/docker-compose/basic-example/
The second link shows basic examples related to Docker Provider.
We can take as an example a service like Nginx that use as a webserver for this blog.
version: '3'
services:
web:
image: "${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}:latest"
ports:
- "80"
networks:
- traefik-net
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-net"
- "traefik.http.routers.adminsecblog.rule=Host(`adminsecurity.guru`)"
- "traefik.http.routers.adminsecblog.entrypoints=https"
- "traefik.http.services.adminsecblog.loadbalancer.server.port=80"
- "traefik.http.routers.adminsecblog.tls.certresolver=certbot"
networks:
traefik-net:
external: true
Explaining each label
traefik.enable=true
This option tells to Traefik that this service can be discovered.
traefik.docker.network=traefik-net
Here we define the network that containers and services use to communicate.
traefik.http.routers.adminsecblog.rule=Host(
adminsecurity.guru)
TheHost
rule sets the hostname. It knows where to route the request and also to create the certificate
traefik.http.routers.adminsecblog.entrypoints=https
Here we define our entry point. In our case, since Traefik router is sending all requests to HTTPS, we use only thehttps
entrypoint.
traefik.http.services.adminsecblog.loadbalancer.server.port=80
Our service is set to listen this port(80). It is important to specify when using Docker Swarm provider. With Docker provider it is not necessary to specify ports since they are recognized automatically by Traefik. But with Docker Swarm we have to keep in mind that service port needs to be defined.
traefik.http.routers.adminsecblog.tls.certresolver=certbot
This label set thecertificasteResolver
name that we defined in our Traefik config.
Conclusion
Every day, Traefik improves the ways we use ingress routers and load balancing for our containerized deployments, and it is easy to implement among different container orchestration platforms.
Migration between v1 and v2 is effortless following the official documentation, and it should not produce big downtime in your production environments.
Should you need any assistance with Traefik or container technologies, be sure to contact Gonkar and check our Consultancy Services.