Во-первых, извините за длинный пост, но я не знаю, как свести его к минимуму. Я уже вырезал много ненужной информации о конфигурации, чтобы получить базовую информацию.
Я настраиваю пару рекурсоров DNS, ns1 и ns2, каждую на отдельном сервере. Каждый сервер содержит пару powerdns из фронта и рекурсора dnsdist, работающих в отдельных контейнерах, по одному для каждого, под управлением docker-compose на основе tcely / dnsdist из Docker Hub.
ns1: 192.168.0.1
ns2: 192.168.0.2
Моя цель - сделать так, чтобы dnsdist мог запрашивать оба рекурсора в своей функции балансировки нагрузки, поэтому у меня есть файл dnsdist.conf, который, по сути, выглядит так:
newServer{address='192.168.0.1:5300', order=1}
newServer{address='192.168.0.2:5300', order=2}
setServerPolicy(firstAvailable)
setLocal('0.0.0.0')
В основном то же самое для обоих серверов, но с обратным порядком, поэтому первичный рекурсор должен быть «локальным».
Я не буду путать вещи с recursor.conf, достаточно сказать, что он разрешает 0.0.0.0/0, поэтому на данном этапе рекурсор не блокирует никого от запроса.
Наконец мы подошли к делу:
Когда я запускаю модуль, dnsdist выдает следующие ошибки журнала:
...
Marking downstream 192.168.0.1:5300 as 'down'
Marking downstream 192.168.0.2:5300 as 'up'
...
Когда я пытаюсь выяснить, почему он считает, что локальный рекурсор не работает, зайдя в контейнер dnsdist и запустив оттуда команду "dig", я получаю следующее:
/ # dig @192.168.0.2 -p 5300 a.root-servers.net. +short
198.41.0.4
/ # dig @192.168.0.1 -p 5300 a.root-servers.net. +short
;; reply from unexpected source: 172.20.0.1#5300, expected 192.168.0.1#5300
Итак - кажется, когда я запрашиваю внешний IP-адрес другого контейнера, он отвечает внутренним IP-адресом. Если бы я мог запросить внутренний IP-адрес других контейнеров, то есть в данном случае 172.20.0.1, я бы сделал это, но этот IP-адрес является локальным для контейнера и изменяется каждый раз при его перезапуске.
Итак, вопрос в том, как мне обойти это? Есть ли способ в Docker жестко закодировать используемые внутренние IP-адреса или заставить контейнер / dnsdist игнорировать тот факт, что он получает ответ с другого IP-адреса, чем ожидалось?
РЕДАКТИРОВАТЬ - для пояснения: Docker автоматически назначает сетевые имена, поэтому, например, я могу «пинговать рекурсор», и он разрешит частный IP-адрес контейнера-резолвера. Я просто не могу использовать это ни для чего, потому что dnsdist.conf принимает только IP-адреса, и, как я начал объяснять, IP-адреса устанавливаются случайным образом докером при запуске контейнера.
Решение (или хотя бы одно) - создать локальную сеть для модуля (пары контейнеров):
version: '3'
services:
dnsdist:
image: 'tcely/dnsdist'
container_name: powerdns-dnsdist
restart: 'unless-stopped'
tty: true
stdin_open: true
command: ["--disable-syslog", "--uid", "dnsdist", "--gid", "dnsdist", "--verbose"]
volumes:
- /data/docker/volumes/dnsdist-recursor/dnsdist:/etc/dnsdist
expose:
- '53'
- '53/udp'
ports:
- '53:53'
- '53:53/udp'
networks:
dnsnet:
ipv4_address: 172.28.1.10
recursor:
image: 'tcely/powerdns-recursor'
container_name: powerdns-recursor
restart: 'unless-stopped'
command: ["--disable-syslog=yes", "--log-timestamp=no", "--local-address=0.0.0.0", "--setuid=pdns-recursor", "--setgid=pdns-recursor"]
volumes:
- /data/docker/volumes/dnsdist-recursor/pdns-recursor:/etc/pdns-recursor
ports:
- '5300:53'
- '5300:53/udp'
networks:
dnsnet:
ipv4_address: 172.28.1.11
networks:
dnsnet:
ipam:
driver: default
config:
- subnet: '172.28.1.0/24'
Теперь вы можете настроить dnsdist.conf следующим образом
newServer{address='172.28.1.11:53', order=1}
newServer{address='192.168.0.2:5300', order=2}
setServerPolicy(firstAvailable)
setLocal('0.0.0.0')
начать сначала
повторить и промыть.