
У меня очень странная воспроизводимая проблема с Docker Swarm. Я пытаюсь развернуть кластер серверов Dgraph через Docker Swarm на четырех контейнерах LXD. Для контекста, Dgraph Zero — это управляющий сервер, а каждый сервер Dgraph Alpha выполняет подъем и должен подключаться к серверу Zero при запуске. Ratel — это просто сервер веб-интерфейса для запросов к базе данных и мутаций. Топография выглядит так:
- Хост: рабочая станция KDE Neon
- Контейнер LXD: ноль
- Узел Docker: dg-zero
- Docker-контейнер: dgraph_zero
- Docker-контейнер: dgraph_ratel
- Узел Docker: dg-zero
- Контейнер LXD: alpha1
- Узел Docker: dg-alpha1
- Docker-контейнер: dgraph_alpha1
- Узел Docker: dg-alpha1
- Контейнер LXD: alpha2
- Узел Docker: dg-alpha2
- Docker-контейнер: dgraph_alpha2
- Узел Docker: dg-alpha2
- Контейнер LXD: alpha3
- Узел Docker: dg-alpha3
- Docker-контейнер: dgraph_alpha3
- Узел Docker: dg-alpha3
- Контейнер LXD: ноль
Все они развертываются как swarm с docker stack deploy
использованием следующей конфигурации docker-compose.yml:
version: "3"
networks:
dgraph:
services:
zero:
image: dgraph/dgraph:latest
hostname: "zero"
volumes:
- data-volume:/dgraph
ports:
- "5080:5080"
- "6080:6080"
networks:
- dgraph
deploy:
placement:
constraints:
- node.hostname == dg-zero
command: dgraph zero --my=zero:5080 --replicas 3 --bindall=true
alpha1:
image: dgraph/dgraph:latest
hostname: "alpha1"
volumes:
- data-volume:/dgraph
ports:
- "8080:8080"
- "9080:9080"
networks:
- dgraph
deploy:
placement:
constraints:
- node.hostname == dg-alpha1
command: dgraph alpha --my=alpha1:7080 --lru_mb=1024 --zero=zero:5080 --bindall=true
alpha2:
image: dgraph/dgraph:latest
hostname: "alpha2"
volumes:
- data-volume:/dgraph
ports:
- "8081:8081"
- "9081:9081"
networks:
- dgraph
deploy:
placement:
constraints:
- node.hostname == dg-alpha2
command: dgraph alpha --my=alpha2:7081 --lru_mb=1024 --zero=zero:5080 -o 1 --bindall=true
alpha3:
image: dgraph/dgraph:latest
hostname: "alpha3"
volumes:
- data-volume:/dgraph
ports:
- "8082:8082"
- "9082:9082"
networks:
- dgraph
deploy:
placement:
constraints:
- node.hostname == dg-alpha3
command: dgraph alpha --my=alpha3:7082 --lru_mb=1024 --zero=zero:5080 -o 2 --bindall=true
ratel:
image: dgraph/dgraph:latest
hostname: "ratel"
ports:
- "8000:8000"
networks:
- dgraph
command: dgraph-ratel
volumes:
data-volume:
Все службы развернуты и работают правильно. Проблема в том, что они не могут общаться друг с другом, поскольку имена хостов не преобразуются в правильный IP.
У меня в данный момент запущен Swarm, и когда я запускаю его docker container inspect
на работающем контейнере Zero, я получаю следующий вывод для конфигурации сети:
"NetworkSettings": {
"Bridge": "",
"SandboxID": "4548013a15833d086b281a8c2dd61ced6ea5c92f815a305f7337effe9b04a13a",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": null,
"9080/tcp": null
},
"SandboxKey": "/var/run/docker/netns/4548013a1583",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"dgraph_dgraph": {
"IPAMConfig": {
"IPv4Address": "10.0.9.3"
},
"Links": null,
"Aliases": [
"8b48711ab0cd"
],
"NetworkID": "lve3kr9vm42rwu1nci897zey7",
"EndpointID": "056ae62475da805ec212d9ec2b2e4a5c9e09e2405c15ad6e8b298e90669b512d",
"Gateway": "",
"IPAddress": "10.0.9.3",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:0a:00:09:03",
"DriverOpts": null
},
"ingress": {
"IPAMConfig": {
"IPv4Address": "10.0.0.157"
},
"Links": null,
"Aliases": [
"8b48711ab0cd"
],
"NetworkID": "vjhpbsc1766lbvtu169fmh81l",
"EndpointID": "29bbc4de97e98b2e05a46dd42020dd1fbb75ff07d8c08a00b8ba6f2f4e00ec2a",
"Gateway": "",
"IPAddress": "10.0.0.157",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:0a:00:00:9d",
"DriverOpts": null
}
}
}
Как можно увидеть, IP-адрес моего контейнера Zero — 10.0.9.3. Однако если я войду в оболочку любого из моих контейнеров Alpha и запущу его, ping zero
он попытается выполнить ping 10.0.9.2. Это постоянно воспроизводится путем уничтожения и повторного развертывания стека. Последний октет в IP-адресе моего контейнера Zero всегда будет на единицу больше IP-адреса, в который zero
разрешается имя хоста в трех других контейнерах. Я могу выполнить ping всех моих контейнеров друг из друга, используя правильные IP-адреса, но я должен использовать имена хостов, потому что я не знаю, какими будут адреса других контейнеров до создания роя, и мне нужно настроить кластер серверов для общения друг с другом.
Правила брандмауэра отсутствуют. Все мои контейнеры LXD могут взаимодействовать. Все IP-адреса контейнеров LXD указаны как одноранговые узлы в сетевой конфигурации Docker. Я не знаю, связано ли это или нет, но я не могу получить доступ к своим сервисам из контейнеров хоста, хотя я опубликовал порты. Если это возможно, я могу предоставить больше информации, которую нашел, но пока я опущу это.
Как выяснить, почему мой рой не преобразует правильные имена хостов в правильные контейнеры?
Версия Docker — 19.03.5 из официального репозитория. Контейнеры LXD — официальные облачные контейнеры 18.04 из сервера образов LXD Ubuntu. Хост — KDE Neon на базе Ubuntu 18.04.