Если вдруг вы не знаете что такое DNS, то в двух словах это сервис, благодаря которому происходит преобразование доменных имён в IP-адреса и обратно. Т.е. вместо того чтобы обращаться к серверу по IP-адресу 172.19.0.3, можно обратиться по имени some-nginx. Человеческий мозг так устроен, что проще запоминать имена серверов, чем IP-адреса.
Например, я зайду в контейнер и попытаюсь пропинговать другой контейнер по ip-адресу 172.19.0.3 и по имени контейнера some-nginx.
docker container exec -it my-network1-nginx1 ping 172.19.0.3
PING 172.19.0.3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.109 ms
docker container exec -it my-network1-nginx1 ping some-nginx
PING 172.19.0.3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.109 ms
Т.е. благодаря Docker DNS контейнеры могут обращаться друг к другу по именам контейнеров.
DNS псевдоним (alias)
Если вдруг есть необходимость обращения к контейнеру помимо основного имени по какому-то другому, можно воспользоваться псевдонимами. Т.е. если имя контейнера some-nginx и я добавляю псевдоним mynginx, то обращаться к контейнеру можно по обоим именам.
Для того чтобы добавить псевдоним для созданного контейнера:
- Отключаем контейнер от сети
docker network disconnect my-network1 some-nginx - Подключаем контейнер к сети и задаём псевдоним
docker network connect --alias mynginx my-network1 some-nginx - Проверяем что псевдоним есть
docker container inspect -f '' some-nginx{"my-network1":{"IPAMConfig":{},"Links":null,"Aliases":["mynginx","15efdb23bd4c"],"DNSNames":["some-nginx","mynginx","15efdb23bd4c"]}}
Если контейнер еще не создан, то можно указать псевдоним во время его создания.
docker run -d --name web --network my-net -network-alias my-nginx-alias nginx:latest
И да важное замечание в сети, которая создаётся (docker0) по умолчанию DNS не работает.
DNS round robin
С версии 1.11 Docker engine позволяет назначать нескольким контейнерам одни и те же dns имена (псевдонимы). Использовать это можно для балансировки нагрузки. Т.е. при обращении, например, а страницу http://some-nginx трафик поочерёдно будет уходить то но один контейнер то на другой, стало быть оба контейнера обслуживают запросы клиента.
Обратите внимание на то что мы говорим про псевдонимы dns имён, а не про имена контейнеров. Создать несколько контейнеров с одним именем не получится.
- Создаём отдельную сеть
docker network create rr-net - Создаём 2 контейнера с образа nginxdemos/hello с псевдонимом web
docker run -d --name web1 --network rr-net --network-alias web nginxdemos/hello docker run -d --name web2 --network rr-net --network-alias web nginxdemos/hello - Стартуем контейнер с alpine и проверяем работу DNS
docker run -it --rm --network rr-net alpine sh
/ # nslookup web
Non-authoritative answer:
Name: web
Address: 172.20.0.2
Name: web
Address: 172.20.0.3
/ # apk add curl
/ # for i in $(seq 1 6); do curl -s web | grep "Server"; done
<p><span>Server address:</span> <span>172.20.0.2:80</span></p>
<p><span>Server name:</span> <span>ffc51538bca6</span></p>
<p><span>Server address:</span> <span>172.20.0.2:80</span></p>
<p><span>Server name:</span> <span>ffc51538bca6</span></p>
<p><span>Server address:</span> <span>172.20.0.2:80</span></p>
<p><span>Server name:</span> <span>ffc51538bca6</span></p>
<p><span>Server address:</span> <span>172.20.0.3:80</span></p>
<p><span>Server name:</span> <span>727674b9865f</span></p>
<p><span>Server address:</span> <span>172.20.0.3:80</span></p>
<p><span>Server name:</span> <span>727674b9865f</span></p>
<p><span>Server address:</span> <span>172.20.0.3:80</span></p>
<p><span>Server name:</span> <span>727674b9865f</span></p>
Зачем DNS
Во-первых, как я уже говорил, имена серверов проще запоминать, чем IP-адреса. Но если в вашем случае это не так, то тогда еще один повод, к которому претензий не будет ни у кого: IP-адреса контейнеров могут меняться, и в таком случае, обращаясь по DNS имени, вам не нужно узнавать новый IP-адрес контейнера.
Бонсуом скрипт, который выведет все псевдонимы для всех контейнеров.
docker ps -q | xargs docker inspect \
| jq -r '
.[] |
.Name as $n |
.NetworkSettings.Networks? |
if type=="object" then
to_entries[] |
"\($n) → \(.key): \(.value.IPAddress) | Aliases: \((.value.Aliases // []) | join(", "))"
else
"\($n) → no networks"
end
' \
| sed -E \
-e "s/(→)/\x1b[36m\1\x1b[0m/" \
-e "s/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/\x1b[32m\1\x1b[0m/g" \
-e "s/(Aliases: )/\x1b[33m\1\x1b[0m/"
/my-network1-nginx1 → my-network1: 172.19.0.2 | Aliases: 05186ff32ca1
/some-nginx → my-network1: 172.19.0.3 | Aliases: mynginx, 15efdb23bd4c
/some-nginx-2 → bridge: 172.17.0.2 | Aliases:


Комментарии