Apps: "Bash", "Docker" & etc.
Задача: автоматизировать процедуры развёртывания тестовых стендов для простейшей проверки функциональности web-сайтов, работающих на стеке из приложений "Nginx + PHP + NodeJS + Memcached + MySQL". Практически описываемая схема эксплуатировалась в процессе разработки сайтов, которые публиковались посредством web-серверов, сделанных следуя инструкции по сборке и развёртыванию "LNPMM + Multisite" на этом же сайте.
Ради интереса я пробовал сделать схему тестирования с помощью "Docker Compose". В начале возможность описать конфигурацию в одном YAML-файле выглядела заманчиво, но с ростом сложности необходимость генерирования неопределённого количества отличающихся конфигураций, компоновки их, подсовывания "композеру", отслеживания результатов выполнения операций, изменения конфигураций и повторения предыдущих процедур свела на нет преимущества этой технологической прослойки для тестовой площадки - оказалось эффективнее пошагово собирать нужную схему, с поэтапным контролем запуска компонентов.
Особо отмечаю - здесь опубликована по сути лабораторная работа процесса познания малой толики того, что уже имеется в "Kubernetes"!
Последовательность дальнейших действий:
1. Подготовка несущего сервера docker-контейнеризации.
2. Создание конфигурационного файла тестового стенда (одного из неограниченного множества).
3. Написание скриптов развёртывания тестовых стендов и последующего ими управления.
4. Примеры использования развёрнутым сервисом.
5. Автоматизация запуска фронтальной точки приёма подключений извне.
2. Создание конфигурационного файла тестового стенда (одного из неограниченного множества).
3. Написание скриптов развёртывания тестовых стендов и последующего ими управления.
4. Примеры использования развёрнутым сервисом.
5. Автоматизация запуска фронтальной точки приёма подключений извне.
Суть дела более полно изложена в заметке первого этапа подготовки несущего сервера. Там немного лирических отступлений и последовательность подготовительных операций, в основном касаемых системного окружения, а так же рассмотрена подготовка специализированных под наши нужны docker-образов.
Немного основных положений автоматизации:
1. Прежде всего на входе в среду тестирования запускается контейнер фронтального web-прокси на базе "Nginx", принимающий все подключения и распределяющий их в соответствии с заданной конфигурацией, динамически изменяемой в зависимости от текущей ситуации, по тестовым стендам доступным только через промежуточную связующую виртуальную сеть "vianet" - этот контейнер не выключается никогда.
2. В группе контейнеров тестового стенда всегда запускается как минимум один web-сервер "Nginx", которому перенаправляются запросы извне через фронтальный web-прокси; этот контейнер служит связующим звеном между почти внешней промежуточной связующей виртуальной сетью "vianet" web-прокси и полностью изолированной от внешнего мира подсетью тестового стенда.
3. Режим запуска остальных контейнеров тестового стенда регламентируется выделенным этому стенду конфигурационным файлом; внутри тестового стенда количество контейнеров и связь между ними не ограничивается.
4. Все управляющие скрипты и конфигурационные файлы располагаются в директории "/usr/local/etc/devops/".
5. Динамически формируемое файловое окружение контейнеров тестовых стендов создаётся автоматически в директории "/var/opt/devops/".
2. В группе контейнеров тестового стенда всегда запускается как минимум один web-сервер "Nginx", которому перенаправляются запросы извне через фронтальный web-прокси; этот контейнер служит связующим звеном между почти внешней промежуточной связующей виртуальной сетью "vianet" web-прокси и полностью изолированной от внешнего мира подсетью тестового стенда.
3. Режим запуска остальных контейнеров тестового стенда регламентируется выделенным этому стенду конфигурационным файлом; внутри тестового стенда количество контейнеров и связь между ними не ограничивается.
4. Все управляющие скрипты и конфигурационные файлы располагаются в директории "/usr/local/etc/devops/".
5. Динамически формируемое файловое окружение контейнеров тестовых стендов создаётся автоматически в директории "/var/opt/devops/".
Логика исполнения блоков в описываемых далее управляющих скриптах:
start(-bunch):
если тестовый стенд не запущен:
загрузка данных,
запуск контейнеров.
если тестовый стенд запущен:
обновление данных,
перезапуск контейнеров.
refresh:
только если тестовый стенд запущен:
обновление данных.
restart:
только если тестовый стенд запущен:
перезапуск контейнеров.
stop:
безусловная остановка контейнеров,
удаление данных тестового стенда.
если тестовый стенд не запущен:
загрузка данных,
запуск контейнеров.
если тестовый стенд запущен:
обновление данных,
перезапуск контейнеров.
refresh:
только если тестовый стенд запущен:
обновление данных.
restart:
только если тестовый стенд запущен:
перезапуск контейнеров.
stop:
безусловная остановка контейнеров,
удаление данных тестового стенда.
Скрипты и шаблоны автоматизации.
Все исполняемые скрипты, подключаемые библиотеки функций и конфигурационные файлы размещаются в трёх директориях одной иерархии:
# mkdir -p /usr/local/etc/devops/ /usr/local/etc/devops/conf/ /usr/local/etc/devops/lib/
Скрипты писались быстро, слегка даже небрежно, дорабатывались в процессе и на отвлечённые рассуждения у меня не хватало времени - потому без подробных описания я из просто прикреплю к публикации, перечислив по отражающим функционал названиям:
1. Конфигурационный файл тестового стенда.
2. Управляющий скрипт развёртывания, актуализации и удаления тестовых стендов.
3. Библиотека функций управления фронтальным web-прокси.
4. Библиотека функций управления контейнерами тестовых стендов.
5. Шаблон конфигурации проксирования запросов извне внутрь тестового стенда.
6. Шаблон конфигурации web-сервера тестового стенда.
7. Библиотека функций визуализации состояния и журналов событий тестовых стендов.
8. Шаблон демонстрационного web-приложения на "NodeJS".
9. Библиотека функций поддержки выделенного IP для фронтального web-прокси.
2. Управляющий скрипт развёртывания, актуализации и удаления тестовых стендов.
3. Библиотека функций управления фронтальным web-прокси.
4. Библиотека функций управления контейнерами тестовых стендов.
5. Шаблон конфигурации проксирования запросов извне внутрь тестового стенда.
6. Шаблон конфигурации web-сервера тестового стенда.
7. Библиотека функций визуализации состояния и журналов событий тестовых стендов.
8. Шаблон демонстрационного web-приложения на "NodeJS".
9. Библиотека функций поддержки выделенного IP для фронтального web-прокси.
Закрываем к скриптам и конфигурационным файлам доступ посторонним:
# chown -R root:docker /usr/local/etc/devops
# chmod -R o-rwx /usr/local/etc/devops
# chmod -R o-rwx /usr/local/etc/devops
Примеры использования и диагностики неисправности.
Запуск фронтального web-прокси (будет автоматизировано посредством "Systemd"):
# /usr/local/etc/devops/docker-ctrl.sh start-front
Запуск тестового стенда сайта "site.example.net" (повторный вызов команды повлечёт актуализацию данных и перезапуск контейнеров):
# /usr/local/etc/devops/docker-ctrl.sh start-bunch ./test-site.example.net.conf
Загрузка изменений данных с исходных серверов, без перезапуска контейнеров:
# /usr/local/etc/devops/docker-ctrl.sh refresh-bunch ./test-site.example.net.conf
Перезапуск контейнеров тестового стенда, без изменения данных:
# /usr/local/etc/devops/docker-ctrl.sh restart-bunch ./test-site.example.net.conf
Остановка тестового стенда (при этом будет зачищены все созданные при его запуске и в процессе работы файлы):
# /usr/local/etc/devops/docker-ctrl.sh stop-bunch ./test-site.example.net.conf
Остановка всех запущенных в данный момент тестовых стендов:
# /usr/local/etc/devops/docker-ctrl.sh stop-bunch-all
Остановка фронтального web-прокси (возможна только если не запущен ни один тестовый стенд):
# /usr/local/etc/devops/docker-ctrl.sh stop-front
Просмотр перечня подключённых к контейнеру "томов":
# docker inspect -f '{ { json .Mounts } }' bunch-site.example.net-nginx | jq
Вход внутрь контейнера в среде исполнения Bash-интерпретатора:
# docker exec -ti bunch-site.example.net-nginx /bin/bash
Подключение к СУБД "MySQL" через локальный файловый сокет, созданный для группы контейнеров тестового стенда:
# mysql --socket=/var/opt/devops/bunch/group0/test-site.example.net/var/run/mysqld/mysqld.sock -u root -p
Подключение к NoSQL "Memcached" через локальный файловый сокет, созданный для группы контейнеров тестового стенда:
# echo "stats" | socat -v "UNIX-CONNECT:/var/opt/devops/bunch/group0/test-site.example.net/var/run/memcached/memcached.sock" STDIN
Проверка доступности СУБД "MySQL" в контейнере из PHP в соседнем контейнере тестового стенда:
# docker exec -ti bunch-test-site.example.net-php /bin/bash
$ php -r '$c = mysqli_connect("bunch-test-site.example.net-mysql", "root", "rootPassword", "", "3306"); if (!$c) { echo "Cannot connect"; } else { $result = $c->query("SELECT User from mysql.user"); print_r($result->fetch_all()); }'
$ php -r '$c = mysqli_connect("bunch-test-site.example.net-mysql", "root", "rootPassword", "", "3306"); if (!$c) { echo "Cannot connect"; } else { $result = $c->query("SELECT User from mysql.user"); print_r($result->fetch_all()); }'
Проверка доступности web-сервера тестового стенда извне:
$ curl -i test-site.example.net:80
Наладка автозапуска фронтального web-прокси.
Создаём файл описания сервиса "Systemd", запускающего при старте операционной системы скрипт управления с указанием развернуть фронтальный web-прокси:
# vi /etc/systemd/system/docker-ctrl.service
[Unit]
Description=Test Platform Control Script
After=syslog.target network.target
[Service]
User=root
ExecStart=/usr/local/etc/devops/docker-ctrl.sh start-front
ExecStop=/usr/local/etc/devops/docker-ctrl.sh stop-bunch-all
[Install]
WantedBy=multi-user.target
Description=Test Platform Control Script
After=syslog.target network.target
[Service]
User=root
ExecStart=/usr/local/etc/devops/docker-ctrl.sh start-front
ExecStop=/usr/local/etc/devops/docker-ctrl.sh stop-bunch-all
[Install]
WantedBy=multi-user.target
Указываем "Systemd" перечитать и принять новую конфигурацию, а также явно активируем и запускаем новый сервис:
# systemctl daemon-reload && systemctl enable docker-ctrl
# systemctl start docker-ctrl
# systemctl start docker-ctrl
С первого раза редко что-то получается, так что наверняка придётся ознакомиться с журналом событий процесса запуска скрипта:
# journalctl -u docker-ctrl.service