Перейти к содержимому
Главная страница » Свой DNS сервер в Docker

Свой DNS сервер в Docker

Docker — это контейнерная платформа, которая приобрела популярность в последние годы. Она широко используется для ускорения процесса разработки и развёртывания, имитируя локальную производственную среду.

The Domain Name System (DNS) — это сервис, который преобразует доменные имена в IP-адреса. В этой статье мы вкратце рассмотрим, как запустить DNS-сервер в контейнере Docker.

Резолвинг имен (The name resolution) в Linux описан в файле /etc/nsswitch.conf. По умолчанию в нем есть запись с files dns, что означает, что сначала будет проверяться файл /etc/hosts, а затем DNS-сервер.

Для DNS-серверов на базе Docker можно рассмотреть следующие варианты:

  • BIND9: Очень гибкий и мощный, подходит для сложных настроек DNS.
  • dnsmasq: Простой и понятный, идеально подходит для небольших и средних сетей, а также для локальной разработки.
  • CoreDNS: современный и расширяемый, часто используется с Kubernetes для обнаружения сервисов.
Рассмотрим два разных варианта установки и настройки DNS сервера BIND9, сначала более сложный и более простой с помощью webmin.

Установка DNS-сервера BIND9 в Docker

Для начала давайте настроим наш DNS-сервер. Мы будем использовать BIND 9 в качестве DNS-сервера, предоставляемого бесплатно Консорциумом Интернета. Он доступен в виде образа Docker на DockerHub.

Настройка сети Docker

Давайте создадим сеть docker.

docker network create --name dockerhosting --subnet 172.24.0.0/16

Для нашей сети мы используем /16 подсеть.

Настройка DNS-сервера

Сначала создайте каталог для хранения конфигурации BIND 9 и новый файл с именем named.conf.options для начала настройки сервера BIND 9.

mkdir -p /opt/bind9/configuration
vim /opt/bind9/configuration/named.conf.options

2. Скопируйте приведенное ниже содержимое в файл.

options {    
directory "/var/cache/bind";    
recursion yes;    
listen-on { any; };    
forwarders {            
8.8.8.8;            
8.8.4.4;    
};};

Данная настройка гарантирует, что BIND прослушивает все интерфейсы для DNS-запросов, и любые запросы доменных имён, которые не могут быть выполнены сервером BIND (за пределами файла доменной зоны), будут отправлены переадресаторам для резолвинга. Например, google.com, docker.com, и т. д.

3. Далее мы определим зону под названием dockerhosting.lan, которая указывает на /etc/bind/zones/db. файл доменной зоны.

Давайте создадим файл, который будет определять нашу зону.

vim /opt/bind9/configuration/named.conf.local

Скопируйте приведенное ниже содержимое в файл.

zone "dockerhosting.lan" {    
type master;    
file "/etc/bind/zones/db.dockerhosting.lan";
};

Файл зоны под названием db.dockerhosting.lan содержит доменные имена, которыми будет управлять наш DNS-сервер BIND. Мы назначим каждому доменному имени IP-адрес. Указывайте IP-адрес контейнера во время его работы, чтобы доменные имена могли указывать на соответствующие IP-адреса.

Теперь мы добавим несколько доменных имён в наш файл доменной зоны. Создайте файл доменной зоны dockerhosting:

vim /opt/bind9/configuration/db.dockerhosting.lan

4. Скопируйте приведенное ниже содержимое в файл доменной зоны.

$TTL    1d ; 
default expiration time (in seconds) of all RRs without their own 
TTL value@       IN      SOA     

ns1.dockerhosting.lan. root.dockerhosting.lan. 
(                  3      ; 
Serial  1d; 
Refresh 1h; 
Retry 1w; 
Expire 1h); 
Negative Cache TTL;

name servers - NS records     IN      NS      
ns1.dockerhosting.lan.; 

name servers - A records
ns1.dockerhosting.lan.          IN      A      172.24.0.2 
nginx.dockerhosting.lan.        IN      A      172.24.0.3 
httpd.dockerhosting.lan.        IN      A      172.24.0.4

В приведенном выше примере добавлен один сервер имен ns1.dockerhosting.lan и два хоста nginx.dockerhosting.lan и httpd.dockerhosting.lan.

Создание Docker образа

Мы будем использовать официальный образ Docker BIND 9 в качестве базового образа и установим на него некоторые дополнительные зависимости. Наконец, мы скопируем наши файлы конфигурации непосредственно в образ Docker.

  1. Создайте Dockerfile.
vim /opt/bind9/Dockerfile.bind9

2. Скопируйте приведенное ниже содержимое в Dockerfile.

#Base Bind9 Image
FROM internetsystemsconsortium/bind9:9.18

#Install required tools and dependencies
RUN apt update && apt install -y \  
        bind9-doc \  
        dnsutils \  
        geoip-bin \  
        mariadb-server \  
        net-tools

#Copy configuration files
COPY configuration/named.conf.options /etc/bind/
COPY configuration/named.conf.local /etc/bind/
COPY configuration/db.dockerhosting.lan /etc/bind/zones/

# Expose Ports
EXPOSE 53/tcp
EXPOSE 53/udp
EXPOSE 953/tcp

# Start the Name Service
CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"]

Содержимое файла Dockerfile образа BIND 9

3. Создайте и пометьте образ BIND с помощью приведенной ниже команды.

docker build -t dns-master . -f Dockerfile.bind9

Запуск контейнер Docker с BIND9

После успешного создания нашего контейнера мы запустим его в нашей сети dockerhosting с указанным IP-адресом.

docker run -d -p 53:53/tcp -p 53:53/udp -p 127.0.0.1:953:953/tcp --rm --name=dns-master --net=dockerhosting --ip=172.24.0.2 internetsystemsconsortium/bind9:9.18

Проверка конфигурации сервера:

docker exec -ti dns-master /bin/bash 
named-check
confnamed-checkzone dockerhosting.lan /etc/bind/zones/db.dockerhosting.lan
zone dockerhosting.lan/IN: loaded serial 3
OK

Демонстрационная настройка

Теперь мы можем использовать ранее запущенный контейнер DNS в качестве нашего DNS-сервера. Любые службы, для которых нам нужно сопоставление доменов, можно просто перестроить с использованием необходимых доменных имён.

docker run -d --rm --name=nginx --net=dockerhosting --ip=172.24.0.3 --dns=172.24.0.2 nginx:latest
sudo docker run -d --rm --name=httpd --net=dockerhosting --ip=172.24.0.4 --dns=172.24.0.2 httpd:latest

Как вы можете видеть, все контейнеры теперь работают в одной сети.

docker network inspect dockerhosting

[{        
"Name": "dockerhosting",        
"IPAM": 
{            
"Config": 
[{                    
"Subnet": "172.24.0.0/16"                
}            
]},        
"Containers": 
{            "12hbd7e3b3a033fd643d36fff787c123adlkda485dc5f3d4468212568b8ff4498e776993": 
{                
"Name": "dns-master",                
"IPv4Address": "172.24.0.2/16"            
},            "14deb32e260d15ff8543571f2c5fd1d99eeb9ba97042a97c34d9b933525ca8aa": 
{                
"Name": "service2",                
"IPv4Address": "172.24.0.4/16"            },            "cb6840cfd76d360dfe4cefc96486a11cd4b73f405d114c2830fd792c4883dd8b": 
{                
"Name": "service1",                
"IPv4Address": "172.24.0.3/16"            
}},    
}]

Вывод Docker network inspect dockerhosting

Мы можем проверить, правильно ли работает сопоставление доменного имени, выполнив команду nslookup . С помощью команды nslookup мы сможем определить IP-адрес доменного имени и DNS-сервер, предоставляющий нам эти данные.

docker exec -it nginx nslookup httpd.dockerhosting.lan 

Server:         127.0.0.11
Address:        127.0.0.11:53

Name:   httpd.dockerhosting.lan
Address: 172.24.0.4

Использование nslookup для проверки IP-адреса службы httpd

Чтобы проверить, работает ли переадресация, мы можем выполнить nslookup для домена, например google.com, который находится за пределами нашей внутренней зоны DNS. Если наш запрос будет успешным, мы сможем увидеть IP-адрес домена Google.

docker exec -it nginx nslookup google.com                             Server:         127.0.0.11
Address:        127.0.0.11:53

Non-authoritative answer:
Name:   google.com
Address: 142.250.182.110

Использование nslookup для проверки IP-адреса службы nginx

Как видите, в полученном ответе есть строка Non-authorative. Это означает, что DNS-сервер, предоставивший нам сведения о домене google.com, не находится под нашим контролем. Мы получили такой результат, потому что добавили переадресацию в нашу конфигурацию BIND. Доменное имя, сведения о котором мы запросили, не было доступно в файле локальной зоны, поэтому сервер BIND не смог предоставить его сведения.

Так же BIND9 позволяет управлять DNS записями, а конкретно добавлять и удалять их с помощью API, на GitHub, есть готовая библиотека.

Запуск Webmin + Bind DNS server в Docker

В данном примере упростим задачу управления DNS записями и установим Webmin GUI панель управления сервером в Docker. Для этого будем использовать готовый образ Docker sameersbn/bind:latest.

Создадим каталог для тома

mkdir -p /home/docker_v/bind/data

Создадим и запустим контейнер с Webmin + Bind DNS server

docker run --name bind -d --restart=always \
--publish 53:53/tcp \
--publish 53:53/udp \
--publish 10000:10000/tcp \
-v /etc/localtime:/etc/localtime \
-v /home/docker_v/bind/data/:/data \
--env='WEBMIN_INIT_SSL_ENABLED=false'  \
--env='ROOT_PASSWORD=GuoLian@2021'  \
sameersbn/bind:latest

Проверим запущенный контейнер:

Перейдем по адресу сервера http://IPсервера:10000

Панель позволяет в настройках установить русский язык интерфейса, но я предпочитаю оставить английский.

Перейдем к настройкам DNS сервера

Создадим главный домен.

Используемые материалы:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *