Getting Started with Traefik: The Modern Load Balancer
Exploring a next-gen cloud-optimized reverse-proxy and load-balancer
In cloud computing, efficient management of resources is critical, especially for web and distributed systems. There are many technologies that enable these systems to perform in an optimized manner. One such family of technologies is called the reverse-proxy AKA the load-balancer.
The reverse-proxy / load-balancer is a core component of service-oriented architected systems. In this style of software architecture, the system runs light-weight software services that are decoupled from each other and expose interfaces to enable features and implement functional requirements. We also see that there are numerous instances of the same service that allow the system to distribute its workloads across as opposed to pushing them through a single service. The job of the reverse-proxy / load-balancer is to enable the distribution of workloads across service instances in order to increase reliability of the system substantially.
There are several projects that implement this technology. A few of them are HAProxy, nginx, Envoy, and Traefik. They all have their tradeoffs, but today I want to show the power of Traefik.
First, it will be helpful to discuss some recurring issues with a lot of reverse-proxies.
A lot of manual and static configuration is required to configure and maintain reverse-proxies.These two points can make developing distributed systems challenging. The reason why is because these systems need to be told what services running on a given host need to be connected to and fed traffic. Adding services may require complex configuration changes, and may also require the system to be taken down to bring on more services running on a host.
Enabling security protocols like SSL can be painful for the services added to the proxy. On load-balancers, there may be a large subsystem designed just for handling the certificates that a service handles, which means making direct changes to the host environment, requiring complex maintenance that can disrupt the services.
Traefik does a beautiful job of handling these at the expense of a little bit more over-head than non-cloud optimized reverse-proxies like HAProxy and nginx.
Traefik has a very simple system for enabling a self-managing service easily, which we will do now. It runs on top of docker, and you manage it by making changes to a container management system like kubernetes or docker compose. This guide uses docker compose.
The requirements for running Traefik are relatively straightforward. Assuming you are running an ubuntu server, you can perform the following 3 steps to prep your system to run Traefik in a containerized environment:
1: Install ca-certificates and curl:
sudo apt-get update && sudo apt-get install -y ca-certificates curl
2: Install docker and docker compose by following the guide. I would recommend using the apt method, but use whatever works best for you: https://docs.docker.com/desktop/setup/install/linux/ubuntu/
3: Install the docker packages:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Once you have performed these steps, you are all set to run Traefik.
There are a couple more steps for actually running Traefik, though. Those steps are to create a traefik and docker-compose configurations:
1: Create the traefik configuration:
The goal of this step is to set up a repository or directory such that it can pull and run a Traefik docker container in a proxy network and connect it to a service running on the same host.
In a base directory or repository, run the following:
mkdir -p config
touch config/acme.json
chmod 600 config/acme.json
touch config/traefik.yml
chmod 644 config/traefik.yml
and then place the following content in traefik.yml:
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: proxy
certificatesResolvers:
letsencrypt:
acme:
email: *your_email*
storage: acme.json
httpChallenge:
entryPoint: web
…and make sure to replace your_email in the file with the email that you want to coordinate with letsencrypt.
After this has been completed, create a docker-compose.yml file in the same directory as the config directory, and place the following content in it:
networks:
proxy:
external: true
services:
traefik:
image: traefik:v2.10
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.yml:/traefik.yml:ro
- ./config/acme.json:/acme.json
networks:
- proxy
site:
build: .
image: site
volumes:
- .:/site/app
- /site/app/node_modules
- /site/app/.next
- ./site/public:/usr/src/app/public
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.myservice-http.rule=PathPrefix(`/`)"
- "traefik.http.routers.myservice-http.entrypoints=web"
- "traefik.http.routers.myservice-https.rule=PathPrefix(`/`)"
- "traefik.http.routers.myservice-https.entrypoints=websecure"
- "traefik.http.routers.myservice-https.tls=true"
#- "traefik.http.routers.nextjs-https.tls.certresolver=letsencrypt"
- "traefik.http.services.nextjs.loadbalancer.server.port=3000"
This docker compose configuration launches a Traefik container in the proxy network and passes the configuration that we just created to it. We also give it ports 80 and 443 from the host, because this example is running a web application and it needs HTTP and HTTPS ports. Notice that the certresolve label is commented out. The reason why is because we aren’t trying to forward traffic to a specific site to the app, we are just forwarding all traffec based on the http.rule and the https.rules give by the ‘/’ above it.
After that we run the following to launch the configuration:
docker network create proxy
docker build --force-rm -t site .
docker compose up
Assuming that everything is set up properly, we should see that Traefik launches and handles everything from the configuration setup to coordinating with letsencrypt for enabling TLS for the traffic that we receive. We should see an output that looks similar to the following:
Just to summarize, the beauty of Traefik is that we have a simple system for running and handling web applications and servers. Traefik enables me to host however many services I want, but in my case, it automatically handles my website’s encryption. This comes at the tradeoff of high-performance, but if your usecase is focused more on the features, then Traefik is an incredibly powerful tool that makes building and running a website simple.
The source code for this example can be downloaded and ran by doing the following:
git clone https://github.com/leonematt/research
cd research/cloud/load-balancers/traefik/example
./install.sh
./run.sh