У докер сварм кластера есть один важный момент. Если сервиса сервиса не существует, то DNS запрос будет отправлен во внешний интернет. Чтобы это исправить нужно выполнить следующую инструкцию.

Настройка DNS для Docker Swarm

В настройках в файле /etc/docker/daemon.json Docker пропишите:

_x000D_{_x000D_ "log-driver": "json-file",_x000D_ "log-opts": {_x000D_ "labels":"com.docker.swarm.service.name",_x000D_ "max-size": "10m",_x000D_ "max-file": "1"_x000D_ },_x000D_ "dns": ["172.17.0.1"]_x000D_}

В yaml файле сервиса нужно прописать:

_x000D_dns:_x000D_ - 172.18.0.1

Внимание!

ip адреса 172.18.0.1 и 172.17.0.1 не просто так. Выполните команду:

_x000D_ip a

ip адрес docker0 нужно прописать в файле /etc/docker/daemon.json обычно это 172.17.0.1 .

ip адрес docker_gwbridge нужно прописать в yaml файле. Обычно это 172.18.0.1 .

Поэтому будьте внимательно, иначе в контейнерах не будет работать DNS

Для тестирования ДНС выполните команду в контейнере:

_x000D_nslookup ya.ru 172.18.0.1

и проверьте работает ли dnsmasq на ip адресе 172.18.0.1

_x000D_sudo netstat -anp | grep 53

Если IP адрес docker_gwbridge другой

1) Удалите ноду из swarm

_x000D_docker swarm leave --force

2) Выполните команду на той же ноде:

_x000D_docker network rm docker_gwbridge_x000D_docker network create --subnet=172.18.0.0/16 -o com.docker.network.bridge.enable_icc=false -o com.docker.network.bridge.name=docker_gwbridge docker_gwbridge

3) Добавьте ноду в swarm

_x000D_docker swarm join --token TOKEN IP-АДРЕС-ГЛАВНОГО-СЕРВЕРА

Посмотреть токен можно командой, выполнив на leader ноде

_x000D_docker swarm join-token manager

4) Перезапустите dnsmasq

_x000D_service dnsmasq restart

Настройка DNS резолвера

Выполните

_x000D_sudo rm /etc/resolv.conf_x000D_sudo nano /etc/resolv.conf

Выполните команду и узнайте на каком порту у вас настроен DNS резолвер. Он должен работать на 53 порту

_x000D_sudo netstat -anp | grep 53

Укажите следующие настройки

_x000D_nameserver 127.0.0.53_x000D_options edns0 trust-ad_x000D_ndots:1_x000D_search .

127.0.0.53 — это systemd. Обычно он установлен по умолчанию

127.0.0.1 — это ip адрес dnsmasq. Используйте его если у вас он установлен

Можете установить другой ip адрес днс сервера, которому вы доверяете

Альтернативный способ для облачной ОС

Если это не помогает, то нужно в yaml добавить несколько DNS адресов:

_x000D_dns:_x000D_ - 172.18.0.1_x000D_ - 172.19.0.1

Либо установить модификатор сервиса для облачной ОС:

_x000D_<?xml version="1.1" encoding="UTF-8" ?>_x000D_<modificator>_x000D_ <uid>org.bayrell.modificator.dns.docker</uid>_x000D_ <name>DNS docker</name>_x000D_ <version>1.0</version>_x000D_ <operations>_x000D_ <operation type="replace">_x000D_ <path>/template/yaml/services/*/dns</path>_x000D_ <value>_x000D_ <dns array="true">172.18.0.1</dns>_x000D_ </value>_x000D_ </operation>_x000D_ <operation type="add">_x000D_ <path>/template/yaml/services/*</path>_x000D_ <value>_x000D_ <dns array="true">172.19.0.1</dns>_x000D_ </value>_x000D_ </operation>_x000D_ </operations>_x000D_</modificator>

Настройка iptables

В /etc/iptables/rules.v4 укажите до строчки -A ALLOW-INPUT -j RETURN

_x000D_# Разрешаем входящие соединения DNS_x000D_-A ALLOW-INPUT -i docker0 -p udp -m udp --dport 53 -j ACCEPT_x000D_-A ALLOW-INPUT -i docker0 -p tcp -m tcp --dport 53 -j ACCEPT_x000D_-A ALLOW-INPUT -i docker_gwbridge -p udp -m udp --dport 53 -j ACCEPT_x000D_-A ALLOW-INPUT -i docker_gwbridge -p tcp -m tcp --dport 53 -j ACCEPT

Установка dnsmasq

На серверах можно обойтись без dnsmasq

_x000D_apt install dnsmasq_x000D_

Скопируйте конфиг dnsmasq:

_x000D_cp /etc/dnsmasq.conf /etc/dnsmasq.conf.example_x000D_echo "" > /etc/dnsmasq.conf

Создайте файл /etc/resolv.dnsmasq

_x000D_nameserver 8.8.8.8_x000D_nameserver 8.8.4.4_x000D_nameserver 1.1.1.1

В /etc/dnsmasq.conf пропишите:

_x000D_port=53_x000D_#listen-address=0.0.0.0_x000D_no-dhcp-interface=_x000D_bind-interfaces_x000D_expand-hosts_x000D_local-ttl=1_x000D_no-negcache_x000D__x000D_# Настройки DNS по умолчанию_x000D_resolv-file=/etc/resolv.dnsmasq_x000D__x000D_conf-dir=/etc/dnsmasq.d_x000D_cache-size=150_x000D_max-cache-ttl=600_x000D_min-cache-ttl=60_x000D__x000D_# Одновременный запрос ко всем DNS серверам_x000D_# all-servers_x000D__x000D_# Запрещаем резолвить домены без точки (нужно для Docker Swarm)_x000D_domain-needed_x000D__x000D_# Для отладки_x000D_#log-queries

Раскоментируйте строку в файле /etc/default/dnsmasq

_x000D_IGNORE_RESOLVCONF=yes

Пропишите ip адреса для домена .local в файле /etc/dnsmasq.d/local

_x000D_address=/.local/127.0.0.1

Выключите резолвер из внешней сети интернет. Создайте файл /etc/dnsmasq.d/disable-external-network

_x000D_bind-interfaces_x000D_except-interface=enp*_x000D_except-interface=wlp*_x000D_except-interface=wlan*_x000D_except-interface=eth*

Создайте файл /etc/NetworkManager/dispatcher.d/99-dnsmasq

_x000D_#!/bin/bash_x000D__x000D_if [[ "$1" = "eth0" || "$1" = "enp2s0" || "$1" = "docker0" || "$1" = "docker_gwbridge" ]]; then_x000D_ if [ "$2" = "up" ]; then_x000D_ kill -9 `cat /var/run/dnsmasq/dnsmasq.pid`_x000D_ sleep 1_x000D_ systemctl start dnsmasq_x000D_ fi_x000D_fi

Удалите файл /etc/resolv.conf и заново его создайте, потому что остается симлинк от днс резолвера systemd, который не дает создать новый файл.

_x000D_rm -f /etc/resolv.conf_x000D_touch /etc/resolv.conf

В /etc/resolv.conf укажите локальный IP адрес

_x000D_nameserver 127.0.0.1

Отключите резолвер systemd

_x000D_systemctl stop systemd-resolved_x000D_systemctl disable systemd-resolved_x000D_systemctl stop resolvconf_x000D_systemctl disable resolvconf

Можно также удалить лишние сервисы:

_x000D_apt-get purge ifupdown resolvconf connman cmst

Перезапустите dnsmasq

_x000D_systemctl restart dnsmasq