Consul - Очередной компонент для поиска контейнеров
Установка
Запуск контейнера
HOSTA=3.3.3.2
docker run --rm -d --name consul -h consul-1 \
-p 8300:8300 -p 8301:8301 -p 8301:8301/udp \
-p 8302:8302 -p 8400:8400 -p 8500:8500 -p $HOSTA:53:8600/udp \
gliderlabs/consul agent -data-dir /data -server \
-client 0.0.0.0 -advertise $HOSTA -bootstrap-expect 2
Подключение к уже существующему
HOSTA=3.3.3.2
HOSTB=3.3.3.3
docker run --rm -d --name consul -h consul-2 \
-p 8300:8300 -p 8301:8301 -p 8301:8301/udp \
-p 8302:8302 -p 8400:8400 -p 8500:8500 -p $HOSTB:53:8600/udp \
gliderlabs/consul agent -data-dir /data -server \
-client 0.0.0.0 -advertise $HOSTB -join $HOSTA
Проверка кластера
docker exec consul consul members
Запись/чтение key/value
$ curl -XPUT http://$HOSTA:8500/v1/kv/hello -d world
true
$ curl -s http://$HOSTA:8500/v1/kv/hello | jq -r '.[].Value' | base64 -d
world
Удаляем ключ
$ curl -XDELETE http://$HOSTA:8500/v1/kv/hello
true
$ curl http://$HOSTA:8500/v1/kv/hello | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Регистрация сервиса
docker run -d -p 6379:6379 --name redis redis:3
HOSTA=3.3.3.2
HOSTB=3.3.3.3
curl -XPUT http://$HOSTA:8500/v1/agent/service/register -d '{"name":"redis", "address":"'$HOSTB'", "port":6379}'
Проверяем что сервис действительно добавился
export HOSTA=3.3.3.2
export HOSTB=3.3.3.3
curl -s http://$HOSTA:8500/v1/agent/services | json_pp
Для отмены регистрации
curl -XPUT http://$HOSTA:8500/v1/agent/service/deregister/redis
Вот тут и начинаются пляски
Для получения адреса нужно использовать конструкцию node.node[.datacenter].domain
В моем случае redis.service.consul
Т.е. получается [название сревиса].service.consul
$ curl -XPUT http://3.3.3.3:8500/v1/agent/service/register -d '{"name":"test-serv", "address":"'127.0.0.1'", "port":1234}'
avis@avisPC2[19:10:27]:~$ dig @3.3.3.2 test-serv.service.consul +short
127.0.0.1
avis@avisPC2[19:11:04]:~$ dig @3.3.3.3 test-serv.service.consul +short
127.0.0.1
PS как нормально сделать пока не понял, хотя можно разрулить на уровне nginx-а...
Самое интересное что консул не хочет отвечать ни на какой другой хост, кроме того на котором запущен
т.е. ни dig @172.17.0.2
(IP докер контейнера), ни dig @127.0.0.1
(он же localhost)
только
$ dig @3.3.3.2 +short redis.service.consul
3.3.3.3
и ни о каких других доменах он не знает...
Добавляем все это поделие в docker daemon
чтобы он при создании контейнера, добавлял в /etc/resolv.conf
адрес консула, dns сервера
$ cat /etc/docker/daemon.json
{
"dns": ["3.3.3.2", "8.8.8.8"],
"dns-search": ["service.consul"]
}
$ sudo service docker restart
$ docker run --rm ubuntu cat /etc/resolv.conf
nameserver 3.3.3.2
nameserver 8.8.8.8
"dns-search": ["service.consul"]
- позволяет обращатся к сервису по имени, без постфикса service.consul
Проверка редиса
$ docker run --rm redis:3 cat /etc/resolv.conf
Запускаем редисон на consul-2
docker run --rm -d -p 6379:6379 --name redis_on_consul2 redis:3
Регистрируем в виртуалке consul-2
HOSTB=3.3.3.3
curl -XPUT http://$HOSTB:8500/v1/agent/service/register -d '{"name":"redis", "address":"'$HOSTB'", "port":6379}'
Пингуем сервис из consul-1
$ docker run --rm redis:3 redis-cli -h redis.service.consul ping
PONG
и наоборот пингуем сервис из consul-2
$ docker run --rm redis:3 redis-cli -h redis.service.consul ping
PONG
т.к. в daemon.json
указан service.consul
можно сократить. Пингуем сервис из consul-1
$ docker run --rm redis:3 redis-cli -h redis ping
PONG
registrator
- регитрация контейнеров при их старте
Чтобы не делать отдельный запрос на регистрацию контейнера, можно поднять рядом контейнер который будет регистрировать при их появлении
1) docker-compose.yml
- консул + регистратор
version: '3'
services:
consul-1:
image: gliderlabs/consul
container_name: consul-1
ports:
- "8300:8300"
- "8301:8301"
- "8301:8301/udp"
- "8302:8302"
- "8400:8400"
- "8500:8500"
- "3.3.3.2:53:8600/udp"
env_file: .env
volumes:
- ./start-consul-agent.sh:/start-consul-agent.sh
entrypoint: /start-consul-agent.sh
registrator:
image: gliderlabs/registrator
container_name: registrator
links:
- "consul-1"
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: consul://consul-1:8500
Консулу говорим что будет всего одна нода
#!/bin/sh
consul agent -data-dir /data -server -client 0.0.0.0 -advertise $HOSTA -bootstrap-expect 1
Список сервисов
$ curl 3.3.3.2:8500/v1/agent/services | json_pp
docker run --name nc-test amouat/network-utils curl localhost
Финалочка
├── consul-1
│ ├── docker-compose.yml
│ ├── .env
│ ├── identiproject
│ │ ├── docker-compose.yml
│ │ ├── identidock
│ │ │ ├── app
│ │ │ │ ├── identidock.py
│ │ │ │ └── tests.py
│ │ │ ├── cmd.sh
│ │ │ └── Dockerfile
│ │ └── identiproxy
│ │ ├── Dockerfile
│ │ └── main.conf
│ ├── install-docker.sh
│ ├── start-consul-agent.sh
│ └── Vagrantfile
├── consul-2
│ ├── docker-compose.yml
│ ├── .env
│ ├── install-docker.sh
│ ├── start-consul-agent.sh
│ ├── start-redis.sh
│ └── Vagrantfile
├── destroy-consuls.sh
├── install-docker.sh
└── start-consul-vb.sh
consul-1-docker-compose
version: '3'
services:
consul-1:
image: gliderlabs/consul
container_name: consul-1
ports:
- "8300:8300"
- "8301:8301"
- "8301:8301/udp"
- "8302:8302"
- "8400:8400"
- "8500:8500"
- "3.3.3.2:53:8600/udp"
env_file: .env
volumes:
- ./start-consul-agent.sh:/start-consul-agent.sh
entrypoint: /start-consul-agent.sh
identiproxy:
build:
context: ./identiproject/identiproxy
dockerfile: Dockerfile
container_name: identiproxy
ports:
- "8000:80"
links:
- "identidock"
identidock:
build:
context: ./identiproject/identidock
dockerfile: Dockerfile
container_name: identidock
volumes:
- ./identiproject/identidock/app:/app
links:
- "dnmonster"
dnmonster:
image: amouat/dnmonster:1.0
container_name: identidnmonster