Комментарии 8
При вводе нового узла в кластер, нам необходимо знать адрес любого узла в кластере. Выполнив команду:Лучше в конфиг файле прописать список всех серверов, используя start_join:
consul join node_ip_address
"start_join": ["10.x.x.1", "10.x.x.2", "10.x.x.3"]
Вообще, настройку лучше не ручками делать. У нас, к примеру, всё это через Ansible. Используем плейбук вроде этого.
Получается, каждый сервис должен знать IP, по которому доступен?
Нет, не совсем так. Каждый сервис регистрируется в консуле, как раз для того, чтобы не знать свой IP. Агент консула запускается рядом с каждым сервисом и берет на себя всю работу по распространению информации по кластеру.
Строго говоря, часто ip этого сервиса должен знать тот, кто его регистрирует, а это не обязательно сам сервис. Вот запускается у меня сервис в своём netns, где у него на условном eth0 ip 172.17.0.22, стучится в консул на бридже 172.17.0.1. В netns, где работает консул есть три адаптера: eth0 (внешний с условным ip 203.0.113.12), tap0 (vpn с условным 10.8.0.33) и бридж с 172.17.0.1. Если что, описанный setup — модель хоста с сервисом, запущенным в docker/systemd.
Какой из ip адресов должен быть указан в консуле? Каким образом он его выберет? Тот же registrator решает эту проблему явным указанием адреса, на который надо регистрировать сервисы.
Какой из ip адресов должен быть указан в консуле? Каким образом он его выберет? Тот же registrator решает эту проблему явным указанием адреса, на который надо регистрировать сервисы.
Да, вы правы. Прелесть консула в его децентрализованности, то есть нужды держать discovery на бридже у вас нет, агент консула всегда доступен для вашего сервиса на локальном интерфейсе. Если вы запускаете сервис в контейнере, то там будет всего два интерфейса — локальный и внешний, консул успешно разместится на обоих:
Посмотрите на Cludter Addr — это именно тот интерфейс, который будет доступен для кластера Consul извне
Теперь попробуем запустить консул на хост-машине, там явно больше двух интерфейсов
Не стартует. Необходимо явно указать адрес, на который будет биндиться интерфейс кластера
Вот теперь все ок.
Дальше кейс использования очень простой. Ваш сервис (или то, что его запускает :) ) всегда знает, что на локальном интерфейсе есть API консула, а консул дальше распространяет эту информацию по кластеру
root@2bc788f155da:~# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1156 (1.1 KB) TX bytes:578 (578.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@2bc788f155da:~# ./consul agent -data-dir /tmp/consul/
==> Starting Consul agent...
==> Starting Consul agent RPC...
==> Consul agent running!
Node name: '2bc788f155da'
Datacenter: 'dc1'
Server: false (bootstrap: false)
Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
Cluster Addr: 172.17.0.2 (LAN: 8301, WAN: 8302)
Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas: <disabled>
Посмотрите на Cludter Addr — это именно тот интерфейс, который будет доступен для кластера Consul извне
Теперь попробуем запустить консул на хост-машине, там явно больше двух интерфейсов
docker@consul:/mnt/sda1/tmp$ ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:7A:86:C8:9D
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:7aff:fe86:c89d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:536 (536.0 B) TX bytes:648 (648.0 B)
eth0 Link encap:Ethernet HWaddr 08:00:27:89:88:DF
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe89:88df/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:883 errors:0 dropped:0 overruns:0 frame:0
TX packets:573 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:128760 (125.7 KiB) TX bytes:104274 (101.8 KiB)
eth1 Link encap:Ethernet HWaddr 08:00:27:A2:68:2C
inet addr:192.168.99.100 Bcast:192.168.99.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fea2:682c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:165 errors:0 dropped:0 overruns:0 frame:0
TX packets:112 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:21390 (20.8 KiB) TX bytes:22364 (21.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:16 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1376 (1.3 KiB) TX bytes:1376 (1.3 KiB)
veth01e9663 Link encap:Ethernet HWaddr 6A:0F:14:E9:35:D2
inet6 addr: fe80::680f:14ff:fee9:35d2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:1296 (1.2 KiB)
docker@consul:/mnt/sda1/tmp$ ./consul agent -data-dir=/tmp/cns
==> Starting Consul agent...
==> Error starting agent: Failed to get advertise address: Multiple private IPs found. Please configure one.
Не стартует. Необходимо явно указать адрес, на который будет биндиться интерфейс кластера
docker@consul:/mnt/sda1/tmp$ ./consul agent -data-dir=/tmp/cns -bind=172.17.0.1
==> Starting Consul agent...
==> Starting Consul agent RPC...
==> Consul agent running!
Node name: 'consul'
Datacenter: 'dc1'
Server: false (bootstrap: false)
Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
Cluster Addr: 172.17.0.1 (LAN: 8301, WAN: 8302)
Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
Atlas: <disabled>
Вот теперь все ок.
Дальше кейс использования очень простой. Ваш сервис (или то, что его запускает :) ) всегда знает, что на локальном интерфейсе есть API консула, а консул дальше распространяет эту информацию по кластеру
Этот подход имеет четыре недостатка:
Мне больше импонирует подход с вынесением этого счастья на уровень инфраструктуры (вышеупомянутый registrator, подход с systemd unit'ом с BindsTo.
- не работает, если у вас больше одного хоста (или требует ручного геморроя с подсетями для бриджа), т. к. адрес сервиса 172.17.0.22 абсолютно не говорит о том, как к этому сервису обращаться, если он реально на другом хосте;
- требует ухода от SRP, модификации образов контейнеров и запуска связки супервизор+консул+сервис в каждом контейнере;
- резко увеличивает поверхность атаки, т. к. статические ключи для serf'овского gossip'а и ключи+сертификаты для tls будут присутствовать в каждом контейнере;
- требует внесения изменений во все сервисы, что трудоёмко и не всегда возможно.
Мне больше импонирует подход с вынесением этого счастья на уровень инфраструктуры (вышеупомянутый registrator, подход с systemd unit'ом с BindsTo.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Consul.io Часть 1