Using Traefik with Consul
Consul Key/Value Store and Service Catalog
Consul has two functions built in to it: a Key/Value store and a Service Catalog
The Key/Value store is useful for defining variables to be shared in the cluster.
The Service Catalog is useful for integration with tools like Traefik as a service discovery tool to dynamically define hosts.
Service Catalog
The Consul Service Catalog is used as a service discovery tool.
The Service Catalog works byt defining a service by name, port, and healthcheck.
curl \
-v \
-XPUT \
-d '{"service": {
"name": "http-service",
"tags": ["http-service"],
"port": 80
}
}' \
http://consul:8500/v1/agent/service/register
Once the service has been registered, consul will search the host where the consul agent is running for the port and healthcheck.
The service will be listed in the service catalog: consul catalog services
consul
http-service
nomad
nomad-client
Curl can be used to list the services
curl http://localhost:8500/v1/catalog/service/http-service
curl 'http://localhost:8500/v1/health/service/http-service?passing'
The power of the Service Catalog is that it includes a built-in DNS server for all the registered services
dig @127.0.0.1 -p 8600 web.service.consul
dig @127.0.0.1 -p 8600 web.service.consul SRV
Key/Value Store
curl http://0.0.0.0/v1/kv
consul kv put hello "world"
curl http://0.0.0.0:8500/v1/kv/hello
[
{
"LockIndex" : 0,
"Key" : "hello" ,
"Flags" : 0,
"Value" : "ZGFwcA==" ,
"CreateIndex" : 75,
"ModifyIndex" : 75
}
]
VALUE = $( curl http://0.0.0.0:8500/v1/kv/hello 2>/dev/null | jq '.[0].Value' | sed 's/"//g' | base64 -D )
echo "[ $VALUE ]"
world
Bootstrapping the Contents of a new Consul cluster
echo '{
"web-service": {
"name": "web",
"tags": ["apache2"],
"port": 80
},
"tomcat-service": {
"name": "tomcat",
"tags": ["tomcat"],
"port": 8080
},
"webapp-service": {
"name": "webapp",
"port": 5000,
"tags": ["flask", "backend"],
"check": {
"script": "curl http://localhost:5000/healthcheck > /dev/null 2>&1",
"interval": "10s"
}
}
}' | tee /etc/consul.d/web.json | jq '.'
consul agent -dev -config-dir = /etc/consul.d
Storing Traefik configuration in Consul
Traefik defines an entrypoint, a frontend, and a backend.
The entrypoint is a listener , think about it as an http or https point where traffic enters Traefik.
The entrypoint connects to a frontend . A frontend is a rule for connecting the incoming pipe to the backend outgoing pipe.
Consul can be used to store the configuration for Traefik so that a static on-disk config file is not needed.
Define Entrypoints
consul kv put traefik/entryPoints/http/address ":80"
consul kv put traefik/entryPoints/http/compress true
Define Frontends
The frontend is a series of rules which determine how incoming traffic will flow from an entrypoint to the backend.
The rules used by Traefik are called matchers
Naturally a hostname request is the most common matching rule Host:dapp.hubner.org
Rules can be based on the HTTP request method: Method:GET
Regular expressions are supported in the rule so long as a named variable is used and the regex is contained in curly brackets: Method:{m:.*}
Multiple rules can be combined by separating them with a semicolon (;) : Method:GET;Method:POST
consul kv put traefik/frontends/dapp/backend dapp
consul kv put traefik/frontends/dapp/entrypoints http
consul kv put traefik/frontends/dapp/routes/dapp0/rule "Host:dapp.hubner.org"
Define Backends
consul kv put traefik/backends/dapp/servers/server0/url "http://0.0.0.0:80"
consul kv put traefik/backends/dapp/servers/server0/weight 1
IP = ` ip addr | grep -E 'eth0.*state UP' -A2 | tail -n 1 | awk '{print $2}' | cut -f1 -d '/' `
SERVICENAME = "dapp-service"
SERVICEPORT = "5000"
read -r -d '' MSG << EOM
{
"Name": " $SERVICENAME ",
"address": " $IP ",
"port": $SERVICEPORT ,
"Check": {
"http": "http:// $IP : $SERVICEPORT ",
"interval": "5s"
}
}
EOM
curl -v -XPUT -d " $MSG " http://consul:8500/v1/agent/service/register && /app/main " $@ "