Traefik Docker Swarm Deployment

Traefik configuration in docker swarm with external wildcard certificates

Complete Tutorial for Traefik with Docker Swarm , Docker UCP implementation

Basics of Traefik

Traefik is an reverse proxy which will simplify SSL implementation process using automatic Let’s Encrypt certificates.

It will also make your docker apps or other applications available through easily specified URL.

You don’t have to expose your application ports to the internet or remember the port numbers for the application servers.

For example, http://<hostname-or-ipaddress>:8080

The below guide will explain you how to use traefik in the docker swam environment and also docker UCP EE edition

Benefits of Traefik

Let us take an example. Let’s say you have application that is accessible at the following address

http://hostname:8082

A Traefik can make it be available like below

The below is called Subdomain approach

https://app.example.com

OR

The below is called Subdirectory approach

https://example.com /app

Prerequisites Needed

  1. A domain name like www.example.com and *.example.com all pointing to one server within the swarm cluster.
  2. You can also point domain name of A record to all your master nodes ip address within the cluster.
  3. In my case, I had three master nodes and three worker nodes.

    I used Docker UCP(Universal Control Plane) in my environment.

    For UCP, a domain name is needed to see the graphical view of the swarm cluster. So ucp domain name is pointed to two master nodes. For example. https://ucp.company.com and a domain name like www.example.com and *.example.com all pointing to one of the master server

    This is all about the architectural view.

    Note: Traefik reverse proxy listens on port 80 and 443. Make sure that these ports are available.

    Previously Docker UCP was using port 80 and 443, I changed the http port and https port in Docker UCP admin settings.

    Creating a Traefik Network

    To make Docker containers available through Traefik reverse proxy, we will need to create networks.

    Create external network for use by Traefik proxy (we will call this traefik_proxy).

    docker network create --driver overlay --subnet=10.0.9.0/24 traefik_proxy

    In the above command, created a subnet so that container runs in the same network and name of the network is “traefik_proxy”.

    You can rename it to whatever you wish to.

    What is ACME

    In simple, Let’s Encrypt uses ACME protocol to enable HTTPS on your website. Let’s Encrypt will act as Certificate Authority (CA).

    In order to get a certificate for your website’s domain with Let’s Encrypt, you do this by using small piece of software that uses the ACME protocol, which runs on your web host and issues a certificate.

    Basically it has automated the certificate generating process.

    There are basically two ways to configure traefik

    1. Either go for CLI flags
    2. or

    3. Have toml configuration file and mount in the traefik volume.
    4. In this tutorial we have used only the CLI flags and subdomain approach.

    Download Configuration files

    Click traefik.zip to to download the complete files necessary for this tutorial

    Method 1

    Traefik Configuration without https and acme

    Below is the traefik configuration without https and acme.

    Locate the traefik-service-http.yml file which you have downloaded above.

    Breakdown of configurations

    constraint=node.role==manager -> Instructing to run only on manager nodes

    mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock -> Access to docker sockets so that traefik can find the running containers ip addresses and communicate with the docker daemon.

    docker.swarmmode -> Instructing to run in swarm mode.

    Docker.domain -> name of your web domain

    That’s it deploy using the command

    sudo docker stack deploy –c traefik-service-http.yml traefik

    Method 2

    Traefik Configuration in docker swarm with ACME Let’s Encrypt and Consul

    What is Consul?

    In simple terms, it is a distributed key value store and service discovery tool.

    What is Service discovery?

    Let's imagine that we have two services running. One is application and other is database for that application.

    If you have demoapp service running and if the demoapp service needs to find the related database then the service discovery helps in attaining these.

    Also if the demoapp database is suddenly down, the swarm mode will retry to make the demoapp database service to run in the other container and the other container will have different ip address.

    In this case service discovery registers the new ip address and stores it so that the demoapp service can communicate with demoapp database.

    Earlier days docker needs external service discovery, now Docker Engine now acts as a Swarm manager, Swarm worker, and service registry.

    However, finding services is not the only reason for service discovery. We need service registries or key-value stores to store the key-values, certificates etc.

    In that case, consul is recommended.

    Other tools like consul are Etcd, Zookeeper etc.

    Registrator

    Registrator will run as Docker container.

    It will watch for new containers that are started on the same host and then registers those containers with your service discovery consul.

    It will also watch for containers that are stopped and it will deregisters it.

    Before running consul, run the below command in all the master and worker nodes,

    docker run -d --name=registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest -internal consul://localhost:8500

    Click traefik.zip to download and locate the traefik-consul-acme.yml file. Let’s see the explanation for the yaml file below.

    Traefik_init Configuration Breakdown

    entrypoints=Name:http Address::80 Redirect.EntryPoint:https -> once the request is available at 80, it will get redirected to port 443

    storeconfig -> Traefik_init service will push the config to Consul through the storeconfig sub-command. This service will retry until finishing without error because Consul may not be ready when the service tries to push the configuration.

    To enable Let's Encrypt support, you need to add --acme flag.

    acme.storage -> the place where to store certificates.

    acme.httpChallenge.entryPoint=http -> Domain validation is done by two challenges Http challenge and Domain Challenge to prove that server controls the domain. In this it uses http challenge.

    To know more please copy the link https://letsencrypt.org/how-it-works/ to read more about it and come back.

    acme.onHostRule=true -> Enable certificate generation on frontends host rules.

    docker.domain=example.com -> remember to change your domain. If you don't have domain name, you can replace it with hostname and you can access the traefik in your browser with "hostname:8080" after deployment

    consul.endpoint=consul:8500 -> this is consul endpoint. You can keep the same.

    Below is the traefik configuration with CLI flags,

    Traefik configuration Breakdown

    1. In networks, we are using two networks to communicate inside the cluster (Internal) and communicate outside the cluster (traefik_proxy).
    2. In labels tag, we have created a traefik.example.com as a front end rule, so that traefik can be accessed through this url and you can see the traefik dashboard. This is for subdomain access for traefik services. You can access the traefik service at traefik.example.com. Also you can replace it with hostname and you can access the traefik in your browser with "hostname:8080" after deployment
    3. Traefik.enable > Enabling to route through traefik
    4. In ports section, you can see that mode is set to host. So that Host and containers share same ip address.

    Below is the consul configuration:

    Consul configuration breakdown

    1. agent -server -bootstrap-expect=1 -ui -client 0.0.0.0 -bind '{{ GetInterfaceIP \"eth0\" }} -> bootstrapping the server and expecting at least expect one agent to join and we are binding the Ethernet interface.
    2. In this we have used local volume only.

    This is the consul dashboard where in you can see the services and key/value stores in which certificates will be stored.

    We have named the datacenter as us_east2 in yml file.

    That’s it deploy using the command

    sudo docker stack deploy –c traefik-consul.yml traefik

    Once deployed, you can access the consul at http://<nodename>:8500

    you can access the traefik dashboard at https://traefik.example.com

    Method-3

    Traefik Configuration in docker swarm with Wildcard certificate and consul

    In this we are going to create traefik with our own wildcard certificates and using secrets to secure the certificates.

    Click traefik.zip to download and locate the traefik-consul-wildcard.yml file. Let’s see the explanation for the yaml file below.

    Secrets for Wildcard certificate

    When you created a wildcard certificate for *.example.com. You will be having a .key and .crt provided.

    create secret using the below command:

    docker secret create certificate.key ./certificate.key

    docker secret create certificate.crt ./certificate.crt

    You need to provide the path of the .key and .crt file.

    In my case .key and .crt are in same location and secret name for the location path of the file ./certificate.key is "certificate.key" and "certificate.crt" is the name for the file ./certificate.crt.

    You can rename it to whatever.

    Below is the Traefik, consul with wildcard certificate configuration,

    Configuration Breakdown

    entrypoints=Name:https Address::443 Compress:true TLS:/run/secrets/certificate.crt,/run/secrets/certificate.key -> provide the wildcard certificate path of the container.

    Below source is the name that we have created for the Secret and target will be inside the container location path , so that entrypoints can fetch the certificate secrets.

    Also make sure to declare the secrets as external at the end of yml file.

    Once done with the deployment, you can see that ssl certificate didn’t show any warning.

    Here you can see that there are multiple frontend and backend, don’t worry if you can’t see in your app.

    Because I have created my app with following frontend and backend rule to route it via traefik.

    Read the below following contents to create front end and backend rules for your docker stack file

    Docker Stack file changes for traefik to access

    In the docker stack file, service level labels are necessary to get routed through traefik.

    Below are the example of how the stack files need to be created.

    Ensure the port number to redirect and network should be traefik_proxy so that traefik can route it.

    If you need to access the particular service in your app, you can access service level url by seeing the route frontend rule that you have configured.

    In my case, I have taken this app in the docker stack file as an example.

    Note:

    If your app has “ports” section, you don’t have to provide in the stack file. You can give in the “traefik.port”.

    You can also provide the same port for multiple services if your services in your app uses it.

    But don’t forget to create a different frontend url for different services. It shouldn’t be same.

    I have created a frontend rule defined below so that I can access the jhispter-elasticsearch dashboard at the frontend url

    https://jhispter-elasticsearch.example.com using this url I can access jhispter-elasticsearch

    In this way you can access each services defined in your stack and as well as compose file.