DEV Community

Bartłomiej Danek
Bartłomiej Danek

Posted on • Originally published at bard.sh

Consul service discovery with Nomad and Fabio

Consul service discovery with Nomad and Fabio

the problem

When you run multiple containers of the same image, each gets a random port. Consul solves this - services register themselves and clients query by name instead of host:port.

run Consul

asdf plugin-add consul
asdf install consul 1.19.0
asdf local consul 1.19.0
Enter fullscreen mode Exit fullscreen mode

Or through Nomad using raw_exec:

job "consul" {
  datacenters = ["dc1"]

  group "consul" {
    task "consul" {
      driver = "raw_exec"

      config {
        command = "consul"
        args    = ["agent", "-dev"]
      }

      artifact {
        source = "https://releases.hashicorp.com/consul/1.19.0/consul_1.19.0_linux_amd64.zip"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

UI at http://127.0.0.1:8500/ui

register a service

Add a service block to any Nomad task:

task "server" {
  driver = "docker"

  service {
    name = "http-echo"
    port = "http"
    tags = ["http-echo", "urlprefix-/echo"]

    check {
      name     = "alive"
      type     = "http"
      path     = "/"
      interval = "10s"
      timeout  = "2s"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

internal load balancing with Fabio

Fabio reads urlprefix-/path tags from Consul and routes traffic automatically.

job "fabio" {
  datacenters = ["dc1"]

  group "fabio" {
    network {
      port "lb" { static = 9998 }
      port "ui" { static = 9999 }
    }

    task "fabio" {
      driver = "docker"

      config {
        network_mode = "host"
        image        = "fabiolb/fabio:1.6.3"
        args         = ["-proxy.strategy=rr"]
      }

      resources {
        cpu    = 200
        memory = 128
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Routes dashboard: http://localhost:9998/routes

Once Fabio is running and your service has urlprefix-/echo, requests to :9999/echo are load balanced across all healthy instances.

# watch round-robin in action
watch -n 0.2 "curl -s http://localhost:9999/echo"
Enter fullscreen mode Exit fullscreen mode

Consul KV for environment variables

Store config in Consul KV and inject it into tasks via the template block:

template {
  data = <<EOH
DB_HOST="{{ key "config/db_host" }}"
DB_PASS="{{ key "config/db_pass" }}"
EOH

  destination = "secrets/file.env"
  env         = true
}
Enter fullscreen mode Exit fullscreen mode

Set values at http://127.0.0.1:8500/ui/dc1/kv or via CLI:

consul kv put config/db_host "db01.example.com"
consul kv put config/db_pass "secret"
Enter fullscreen mode Exit fullscreen mode

Originally published at https://bard.sh/posts/consul-service-discovery/

Top comments (0)