Разворачиваем сеть на RHEL8-based хостах
Развертывание ИТ-инфраструктуры с нуля — задача интересная и трудозатратная. Особенно, когда речь не о постепенном развитии (как это часто случается при поступательно-линейном росте бизнеса и, соответственно, его потребностей), а о куда более сжатых сроках, например, при открытии филиала или обособленного подразделения (другой вариант — необходимость в короткие сроки развернуть инфраструктуру для тестирования), где важную роль играет организация сети.
Конечно, первоначальная установка и настройка — это всегда полевая работа: монтаж СКС, сетевого оборудования и серверов; конфигурирование DHCP и организация удалённого доступа; иногда — заведение VLAN-ов.
2. Описание задачи
Итак, представим, что первичная настройка сети проведена: монтаж СКС осуществлён, DHCP выдал всем устройствам IP-адреса, удалённый доступ до сети филиала (или обособленного подразделения) в наличии, на одни сервера заведены 2 (или более) физических соединения для организации BOND-ов, на другие поданы транковые соединения с несколькими VLAN-ами и т.д.
Список IP-адресов серверов сведён в таблицу и доступ по SSH в наличии. Если размер списка невелик (например, до 3-5 единиц), то ручная настройка покажется неплохим вариантом, хоть и отнимет какое-то время.
А если список содержит, например, 10 (или более) хостов, на части из которых необходима уникальная сетевая конфигурация (разделение trunk-соединения на vlan-ы, виртуальные bridge-ы, etc)? Тут уж временные затраты существенно возрастают.
Но нет необходимости тратить время на рутину, если готовое решение есть и ожидает вас ниже (со ссылкой на guthub-репозиторий в конце публикации).
3. Стек технологий
1) Ansible. Весьма популярен (хотя кому-то ближе Puppet, Chef или Salt). Применяется для доставки контента/команд на целевые хост-системы.
2) Командная оболочка Bash. Присутствует во всех linux-системах. В рамках решения используется как для создания оболочки над Ansible, так и для отложенного выполнения операций (если конкретнее — отката сетевых настроек по таймеру) на целевых хостах.
3) Perl 5. Отличный инструмент в умелых руках. С помощью этого ЯП написан функционал генерации ifcfg-файлов на основе текстового конфига (т.е. Perl задействован только на ansible-хосте).
4) Network-scripts. Хоть и не включён в минимальный вариант установки ОС семейства RHEL8, но является проверенным средством настройки сетевой подсистемы.
4. Концепция приложения
Приложение «conf_int_ipv4_via_network_scripts» (ansible-приложение) представляет собой набор perl/bash-скриптов и файлов конфигурации (inventory-file, etc). Хотя и является составной частью репозитория «ansible_helpers», но имеет автономный характер.
5. Описание приложения
5.1. Структура директорий
1. Корневой раздел (условно обозначим «../»). Содержит все основные скрипты поддиректории.
2. Директория с дополнительными конфигами («../additional_configs»). Содержит дополнительные файлы конфигурации, с помощью которых возможно задать содержание resolv.conf (указать NS-сервера), таймаут отката конфигурации и опцию удаления неиспользуемых ifcfg-файлов на стороне целевых хостов.
3. Директория с playbook-ами («../playbooks), которая в свою очередь имеет свои подразделы:
3.1) dyn_ifcfg_playbooks. Тут динамически генерируеются уникальные для каждого хоста плейбуки, ifcfg-файлы и настройки dns (resolv.conf).
3.2) ifcfg_backup_from_remote. Содержит резервные копии сетевых настроек с привязкой к дате («history»), текущую конфигурацию до изменения («now») и полную информацию о сетевых интерфейсах («network_data»).
3.3) ifcfg_tmplt. Как следует из названия, хранит шаблоны ifcfg-конфигураций, на основе которых формируются уникальные для каждого inventory-хоста настройки сети.
3.4) scripts_for_local. Хранит скрипты для исполнения на ansible-хосте. В данном случае подразумевается скрипт преобразования сырых данных в файлы c информацией о сетевых интерфейсах (размещаются в директории «../ifcfg_backup_from_remote/network_data»).
3.5) scripts_for_remote. Скрипты для исполнения на удалённых хостах. В данном случае он один — rollback_ifcfg_changes.sh (скрипт отката к предыдущим настройкам сетевой подсистемы).
6) tasks. Используемые в плейбуках файлы задач.
4. «../run_history». Логи запуска/исполнения сценариев приложения.
5.2. Файлы конфигурации
1. «../conf_network_scripts_hosts» — inventory-файл приложения.
2. «../config» – основной файл конфигурации приложения. Также имеется файл «config_examples» с примерами настроек. Для получения имён сетевых интерфейсов и соответствующих им MAC-адресов, требуемых при заполнении файла «config», необходимо запустить скрипт «just_run_ifcfg_backup.sh» и ознакомиться с файлом «../playbooks/ifcfg_backup_from_remote/network_data/inv_hosts_interfaces_info.txt».
3. «../additional_configs/config_del_not_configured_ifcfg» — задаёт действие относительно тех ifcfg-файлов, которые не сконфигурированы в «../config». Если в «config_del_not_configured_ifcfg» вписать адрес хоста, то ansible-приложение удалит на remote-хосте все ifcfg-файлы, выключит соответствующие интерфейсы («ifdown») и удалит линки (через «ip link delete»), но только те, которые относятся к bond/bridge и vlan-интерфейсам (например, eth0.100). Настройка будет полезна в случая, когда, например, требуется переименовать какое-либо bond/bridge-соединение.
4. «../additional_configs/config_temporary_apply_ifcfg» — тут возможно задать таймаут (как общий, так и для различных inventory-хостов индивидуально) отката к предыдущим настройкам.
5. «../additional_configs/dns_settings». Предоставляет возможность выставить настройки dns индивидуально для каждого inventory-хоста.
5.3. Скрипты и их назначение
1. «install_network_scripts_and_configure_network.sh» — производит бэкап ifcfg-файлов, устанавливает «network-scripts» (если функционал не установлен ранее), проверяет статус сервиса «network.service» (если не запущен, то стартует), исполняет скрипт «generate_dynamic_ifcfg.pl» и применяет изменения сетевых настроек (заданных в файле «config») на удалённых хостах (если, конечно, настройки корректны).
2. «just_install_network_scripts.sh» устанавливает «network-scripts» (если функционал не установлен ранее).
3. «just_run_ifcfg_backup.sh» — производит бэкап ifcfg-файлов.
4. «check_network_scripts_serv_is_started.sh» — проверяет статус сервиса «network.service» (если не запущен, то стартует).
5. «check_ifcfg_without_apply.sh» — проверяет корректность сетевых настроек (файл «config»).
6. «apply_temporary_ifcfg.sh» — временно применяет сетевые настройки. Таймаут отката задается в конфиге «../additional_configs/config_temporary_apply_ifcfg».
7. «apply_immediately_ifcfg.sh» — немедленно применяет новые сетевые настройки, если, конечно, они изменились с момента предыдущего запуска (в т.ч. если были внесены какие-либо изменения вручную на удалённых хостах).
5.4. Описание основного файла конфигурации (UPD 2022-12-19)
Каждая строка в файле представляет собой набор параметров, разделённых символами «пробел/табуляция»:
1) INV_HOST. Должен соответствовать одному из хостов inentory-файла «conf_network_scripts_hosts».
2) CONF_ID. Уникальный идентификатор сетевого интерфейса (или набора сетевых интерфейсов) в рамках каждого inventory-хоста.
3) CONF_TYPE. Определяет тип конфигурации для конкретных сетевых интерфейсов. Возможные значения:
3.1) just_interface (обычный интерфейс);
3.2) interface-vlan (интерфейс, поднимаемый в рамках транкового соединения, из которого каждый vlan возможно выделить по vlan-идентификатору);
3.3) virt_bridge (виртуальный мост);
3.4) just_bridge (обычный мост);
3.5) bridge-vlan (мост поверх vlan-интерфейса);
3.6) just_bond (конфигурация агрегированного канала, состоящего из 2-х и более физических соединений);
3.7) bond-vlan (vlan-итерфейс поверх bond-соединения);
3.8) bond-bridge (соединение типа «мост» поверх bond-соединения);
3.9) bond-bridge-vlan (соединение типа «bridge-vlan» поверх bond-соединения).
Каждому из этих значений соответствует свой набор шаблонов ifcfg-файлов (директория «ifcfg_tmplt»).
4) INT_LIST. Список сетевых интерфейсов (разделённых запятой), используемых в рамках конкретного типа конфигурации (CONF_TYPE).
5) HWADDR_LIST. Список MAC-адресов, соответствующих сетевым интерфейсам из INT_LIST. Для CONF_TYPE=virt_bridge параметру необходимо присвоить значение «no».
6) VLAN_ID. Идентификатор VLAN. В случае, если речь не про vlan, то должен иметь значение «no».
7) BOND_NAME. Используется только для CONF_TYPE, равных «just_bond, bond-vlan, bond-bridge, bond-bridge-vlan». В остальных случаях необходимо выставлять значение «no».
8) BRIDGE_NAME. Используется только для CONF_TYPE, равных «virt_bridge, just_bridge, bridge-vlan, bond-bridge-vlan». В остальных случаях необходимо выставлять значение «no».
9) IPv4_ADDR_OPTS. Опции IPv4. Возможные значения: строка вида «ipv4,gateway,netmask» (для использования статической адресации) или «dhcp» (для получения ip-адреса и прочих параметров через DHCP).
10) BOND_OPTS. Настройки агрегирования для bond-соединения. Возможные значения: «def» («mode=4,xmit_hash_policy=2,lacp_rate=1,miimon=100») или иное сочетание параметров, разделённых запятой.
11) DEFROUTE. Флаг «маршрут по умолчанию». Для конкретного inventory-хоста должен быть только один.
Чтение и обработка файла «config» происходит посредством Perl-скрипта «generate_dynamic_ifcfg.pl», который осуществляет ряд проверок конфигурации (в т.ч. и используя информацию, полученную посредством «just_run_ifcfg_backup.sh»), инициирует приостановку исполнения сценариев на удалённых хостах, если данные в «config» некорректны, формирует необходимые наборы ifcfg-файлов для каждого inventory-хоста, а также создаёт персональные для каждого хоста ansible-playbook-и (в директории «dyn_ifcfg_playbooks»), если сгенерированные файлы интерфейсов отличаются от текущих.
6. Постскриптум
В README-файле перечислены как уже готовые приложения, так и те, статус которых варьируется от «в процессе» до «есть в планах».
Спокойного кодинга всем причастным!