Частенько приходится разворачивать что-либо локально на ПК, дабы по тестировать новую технологию, естественно держать все общение между разными узлами на IP адресах не удобно. Хочется иметь нормальную возможность обращаться по доменным именам внутри локальной сети.
Эту проблему конечно можно решить заполнением файла /etc/hosts и постоянным копированием его на все ВМ, но это не удобно. Гораздо удобней иметь локальный ДНС сервер настроенный на резолв нужных нам записей, с возможностью простого обновления нужных записей каким-нибудь автоматизированным способом.
Для этого нам понадобится ansible и vagrant.
Vagrant — это по сути CLI обертка над различными провайдерами виртуализации. Лично я использую virtualbox.
Итак, пишем Vagrantfile для развертывания ВМ с dnsmasq.
Vagrant.configure("2") do |config|
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = 1024
vb.cpus = 1
vb.check_guest_additions = false
config.vm.box_check_update = false
config.vm.box = "bento/ubuntu-22.04"
end
config.vm.define "dns" do |node|
node.vm.hostname = "dns"
node.vm.network "public_network", ip: "192.168.10.100", bridge: "wlo1"
node.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/playbook/dnsmasq.yaml"
ansible.limit = "all,localhost"
end
end
end
В этом конфиге мы задаем различные параметры для создание ВМ, думаю они достаточно просты для интуитивного понимания. Также мы указываем, что хотим использовать provision, в данном случае ansible_local.
ansible_local — это значит, что после старта ВМ, ansible будет автоматически установлен на ВМ и будет запущен плейбук, который мы указали для локального хоста. Запущен он будет на внутри нашей созданной ВМ, не на хост машине.
Как выглядит структура каталогов?
Внутри проекта «local_dns» есть директория ansible в которой находятся все конфигурационные файлы для нашей роли. Давайте их рассмотрим.
Playbook:
- name: Install dnsmasql for local env
become: yes
hosts: localhost
roles:
- dnsmasq
Roles/dnsmasq/defaults
dns_port: 53
listen_address: "127.0.0.1,192.168.10.100"
local_domain: "dev.local"
cache_size: 1000
local_domain_list:
- address=/k8s-master.{{ local_domain }}/192.168.10.27
- address=/k8s-worker1.{{ local_domain }}/192.168.10.26
- address=/k8s-worker2.{{ local_domain }}/192.168.10.25
nameservers_list:
- 8.8.8.8
- 192.168.10.254
Тут мы заполняем параметры, которые потом будем «подставлять» в конфигурационные файлы для dnsmasq.
Roles/dnsmasq/templates
Первый конфиг для самого dnsmasq.
port={{ dns_port }}
domain-needed
bogus-priv
listen-address={{ listen_address }}
expand-hosts
domain={{ local_domain }}
cache-size={{ cache_size }}
### dns resolver ###
{% for host in local_domain_list %}
{{ host }}
{% endfor %}
Здесь мы просто подставляем значения используя jinja2 шаблонизацию. Хосты, которые хотим резолвить заполняем через цикл.
Второй конфиг для resolv.conf файла.
{% for ns in nameservers_list %}
nameserver {{ ns }}
{% endfor %}
Roles/dnsmasq/tasks
---
- name: Disable systemd-resolved
ansible.builtin.systemd:
name: systemd-resolved
enabled: no
state: stopped
- name: Remove old resolv.conf
ansible.builtin.file:
path: "/etc/resolv.conf"
state: absent
- name: Upload custom resolv.conf
ansible.builtin.template:
src: "resolv.conf.j2"
dest: "/etc/resolv.conf"
- name: Install dnsmasq
ansible.builtin.apt:
name:
- dnsmasq
- dnsutils
- ldnsutils
- name: Upload configurations
ansible.builtin.template:
src: "dnsmasq.conf.j2"
dest: "/etc/dnsmasq.conf"
- name: Enable dnsmasq
systemd:
name: dnsmasq
enabled: yes
state: restarted
Это основной файл, из которого выполняются все наши таски для установки и настройки dnsmasq. Мы используем ubuntu22.04, следовательно вначале нам нужно отключить дефолтный systemd-resolved, который слушает 53 порт, а также удалить сгенерированный им resolv.conf. Далее мы просто копируем конфиги и включаем dnsmasq.
Также в корень проекта кладем ansible.cfg для правильного определения путей до ролей самим ansible.
[defaults]
host_key_checking = false
roles_path = ./ansible/roles
display_skipped_hosts = no
Запускаем командой
vagrant up --provision
Мы должны увидеть что-то вроде:
Проверяем резолвинг
nslookup k8s-master.dev.local 192.168.10.100
Все корректно от резолвилось. Давайте проверим интернет.
nslookup ya.ru 192.168.10.100
Работает корректно.
Теперь мы можем использовать адрес этого ДНС сервера для работы.
Полный код можно найти на моем github.