Skip to main content

Hashicorp Consul Refresher - Loadbalancing with Traefik

Tsim Sha Tsui, Hongkong

Load Balancing with Traefik

The main use case for Traefik in this scenario is to distribute incoming HTTP(S) and TCP requests from the Internet to front-end services that can handle these requests. Traefik can natively integrate with Consul using the Consul Catalog Provider and can use tags to route traffic.

Create the Web Service

I am going to modify the HTTP Echo service I created earlier to be load balanced by Traefik:

job "http-echo-gui" {
  datacenters = ["instaryun"]

  group "echo" {

    count = 1

    network {
      port  "http"{
        to = -1
      }
    }

    service {
      name = "echo-webapp"
      port = "http"

      tags = [
        "traefik.enable=true",
        "traefik.http.routers.http.rule=Path(`/echo`)",
      ]

      check {
        type     = "http"
        path     = "/"
        interval = "2s"
        timeout  = "2s"
      }
    }

    task "server" {
      driver = "docker"
      config {
        image = "hashicorp/http-echo:latest"
        ports = ["http"]
        args  = [
          "-listen", ":${NOMAD_PORT_http}",
          "-text", "${attr.os.name}: server running on ${NOMAD_IP_http} with port ${NOMAD_PORT_http}",
        ]
      }
    }
  }
}

Note that this job only deploys 1 instance of the Echo web application which I will "load balance" with Traefik in the next few steps. Obviously, you should increase this count to have this make sense... but I only have two LINUX PCs running at the moment and so my "Datacenter" consists of a single minion server.

The job uses tags to configure routing to the web app. Even though the application listens on /, it is possible to define /echo as the route because of the Path option.

I will deploy the web application using the Nomad UI:

Hashicorp Consul Traefik Loadbalancer

Unlike before - when I set a static port for the web app - now it received a dynamic port from Nomad 26137 that is bound to the local IP of my server:

docker ps

CONTAINER ID   IMAGE                        PORTS
367c94939c8e   hashicorp/http-echo:latest   5678/tcp, 192.168.2.111:26137->26137/tcp, 192.168.2.111:26137->26137/udp

You can verify in Consul that the service is up and running:

Hashicorp Consul Traefik Loadbalancer

Create and run a Traefik job

Create a job named:

nano ~/nomad_jobs/traefik.nomad

This job starts an instance of Traefik and configures it to discover its configuration from Consul. This Traefik instance provides routing and load balancing to the sample web application.

job "traefik" {
  region      = "global"
  datacenters = ["instaryun"]
  type        = "service"

  group "traefik" {
    count = 1

    network {
      port "http" {
        static = 8080
      }

      port "api" {
        static = 8081
      }
    }

    service {
      name = "traefik"

      check {
        name     = "alive"
        type     = "tcp"
        port     = "http"
        interval = "10s"
        timeout  = "2s"
      }
    }

    task "traefik" {
      driver = "docker"

      config {
        image        = "traefik:v2.2"
        network_mode = "host"

        volumes = [
          "local/traefik.toml:/etc/traefik/traefik.toml",
        ]
      }

      template {
        data = <<EOF
[entryPoints]
    [entryPoints.http]
    address = ":8080"
    [entryPoints.traefik]
    address = ":8081"

[api]
    dashboard = true
    insecure  = true

# Enable Consul Catalog configuration backend.
[providers.consulCatalog]
    prefix           = "traefik"
    exposedByDefault = false

    [providers.consulCatalog.endpoint]
      address = "127.0.0.1:8500"
      scheme  = "http"
EOF

        destination = "local/traefik.toml"
      }

      resources {
        cpu    = 100
        memory = 128
      }
    }
  }
}
nomad plan nomad_jobs/traefik.nomad
+ Job: "traefik"
+ Task Group: "traefik" (1 create)
  + Task: "traefik" (forces create)

Scheduler dry-run:
- All tasks successfully allocated.

To submit the job with version verification run:

nomad job run -check-index 0 nomad_jobs/traefik.nomad
nomad job run -check-index 0 nomad_jobs/traefik.nomad


Deployed
Task Group  Desired  Placed  Healthy  Unhealthy  Progress Deadline
traefik     1        1       1        0          2021-09-03T13:12:15+08:00

This configuration uses a static port for the load balancer to 8080. This allow you to query the service under the configured path /echo:

curl http://192.168.2.111:8080/echo

debian: server running on 192.168.2.111 with port 26137

You can see that the service is still running on port 26137 but is now proxied through Traefik on port 8080 and - in theory - would also be loadbalanced, once you start more than 1 instance of the web service.

The Traefik Dashboard is now running on port 8081 on my minion - Make sure that both ports are opened in your minions firewall:

Hashicorp Consul Traefik Loadbalancer