От Docker-Composer к Docker Swarm: Configs
Docker Configs давайте Docker Swarm управлять нашей (статической) конфигурацией, хранение на общем томе не требуется.

У вас есть приложение, состоящее из нескольких проектов Docker-Compose, и вы используете Docker-Compose для сборки, запуска и развертывания.
Теперь вы хотите сделать еще один шаг вперед и переместить некоторые из проектов Docker-Compose на другой сервер. Наиболее очевидным выбором для этого, который стоит попробовать в первую очередь, является Docker Swarm. Вы изучаете еще несколько команд Docker - и все готово. Действительно ли это так просто?
Предупреждение о спойлерах. Нет, это не так просто, если у вас есть контейнеры, использующие тома, например, для конфигурационных данных, высокопроизводительных данных, постоянных данных. Многие примеры в Интернете полностью обходят этот вопрос, либо вскользь упоминают об использовании общих хранилищ типа NFS (без шифрования) или GlusterFS, либо используют решения для хранения от облачных провайдеров. Все эти решения имеют одну и ту же особенность: Они работают по сети и очень медленны по сравнению с собственным хранилищем. Да, можно работать быстрее, но за это придется платить больше.
Прежде чем рассматривать Docker Swarm, я рекомендую прочитать об этом вопросе, чтобы понять, подходит ли ваш сценарий использования для Docker Swarm. Например, вот обсуждение этого вопроса, 'Data(base) persistence in docker swarm mode', см. ссылки ниже. А из этого Stackoverflow ответ "How does Docker Swarm implement volume sharing?", см. ссылки ниже:
Swarm Режим сам по себе не делает ничего другого с томами, он выполняет любую команду монтирования тома, которую вы предоставляете на узле, где запущен контейнер. Если монтирование тома локально для этого узла, то данные будут сохранены локально на этом узле. Встроенная функциональность для автоматического перемещения данных между узлами отсутствует.
Это означает, что можно подготовить структуру каталогов на рабочем узле и обеспечить запуск контейнера только на этом узле с помощью параметров deploy placement. Параметры ...
В этом посте мы используем Docker Swarm Configs для передачи (статических) конфигурационных данных контейнерам на рабочих узлах. Это немного антипаттерн, но хорошо то, что мы устраняем необходимость в хранении данных.
Как обычно, я работаю на Ubuntu 22.04. В данный момент я не использую Docker Desktop. Я использовал VirtualBox для создания Ubuntu сервера VM и использования его в качестве рабочего.
Docker Swarm не управляет данными тома!
Docker Swarm - это менеджер сервисов, а сервисы - это контейнеры (основанные на images), а не объемные данные. Это означает, что вы должны сами управлять данными тома.
В качестве примера рассмотрим контейнер DSN-сервера. По умолчанию он подключается к DNS-сервису A в Интернете, никаких внешних данных здесь нет. С помощью Docker Swarm мы можем развернуть этот контейнер, указать реплики, все просто.
Теперь мы хотим, чтобы тот же контейнер DSN-сервера подключался к DNS-сервису B в Интернете. Следуем инструкциям сопровождающего контейнера, создаем два (конфигурационных) файла, создаем сопоставление томов, и готово.
Часть файла Docker-Compose:
...
services:
dns_service:
image: ...
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
...
Но теперь у нас возникла проблема с Docker Swarm , поскольку он не управляет данными нашего тома! Если мы развернем службу на рабочем узле, то данных, конфигурационных файлов, там не будет!
'Запекание' конфигурационных данных в службу
При использовании Docker Swarm у нас нет данных в наших томах... если мы ничего не делаем. Существует способ обойти это, называемый 'Configs', недоступный в Docker-Compose. Мы можем использовать его для указания файлов, которые будут монтироваться в контейнер, подобно тому, как это делается с томами. Сначала мы рассмотрим решение Docker-Compose, а затем изменим его на Docker Swarm.
Использование Docker-Compose
При использовании Docker-Compose файл 'docker-compose.yml' для нашего проекта DNS-сервера, см. выше,
использует тома и выглядит примерно так:
# docker-compose.yml, using volumes
version: '3.7'
services:
app:
image: busybox_volumes
build: .
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
Добавляем 'Dockerfile':
# Dockerfile
FROM busybox
И собираем образ:
docker-compose build
И запускаем его:
docker-compose up
На экран выводится текст:
app_1 | total 8
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions1.conf
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions2.conf
app_1 | definitions=1
app_1 | definitions=2
Как и ожидалось. Но если Docker Swarm развернет этот сервис на другом узле, рабочем, то наши файлы будут отсутствовать.
Использование Docker Swarm
Здесь мы удалим секцию 'volumes' и добавим новую секцию 'configs' :
# docker-compose.yml, using configs
version: '3.7'
services:
app:
image: busybox_configs
build: .
configs:
- source: definitions1
target: /opt/dns_server/config/definitions1.conf
- source: definitions2
target: /opt/dns_server/config/definitions2.conf
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
configs:
definitions1:
file: ./config/definitions1.conf
definitions2:
file: ./config/definitions2.conf
Собираем образ:
docker-compose build
И затем выполняем развертывание:
docker stack deploy -c docker-compose.yml configs
Результат команды deploy показывает создание 'configs':
Creating network configs_default
Creating config configs_definitions2
Creating config configs_definitions1
Creating service configs_app
На экран ничего не выводится, чтобы понять, что происходит, заглянем в журнал этой службы:
docker service logs configs_app
Результат:
configs_app.1.vqumgq21leq8@myra | total 8
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions1.conf
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions2.conf
configs_app.1.vqumgq21leq8@myra | definitions=1
configs_app.1.vqumgq21leq8@myra | definitions=2
Это означает, что менеджер Docker Swarm правильно добавил наши файлы.
В моем случае служба была развернута на узле менеджера Docker Swarm , а не на рабочем узле. Чтобы запустить его на рабочем узле, добавим в файл 'docker-compose.yml' следующее:
deploy:
placement:
constraints:
- node.role == worker
replicas: 1
Пометить образ и поместить его в реестр Docker .
Только если вы используете частный реестр
Если вы используете частный, небезопасный реестр, вы должны сообщить всем узлам Docker , что он небезопасен, добавив эту информацию:
{
"insecure-registries":[
"<your registry ip address>:<your registry port>"
],
}
в файл:
/etc/docker/daemon.json
После этого перезапустите Docker :
sudo systemctl restart docker
Важно: это необходимо сделать на всех узлах.
Теперь отредактируйте файл 'docker-compose.yml', чтобы указать Docker Swarm , где он может получить ваш образ.
From:
...
services:
app:
image: busybox_configs:latest
...
To:
...
services:
app:
image: <registry host>:<registry port>/busybox_configs:latest
...
Разверните службу на рабочем узле
Удалите службу с этого узла, если она еще там находится:
docker stack rm configs_app
И разверните снова:
docker stack deploy -c docker-compose.yml configs
Теперь можно проверить, что служба запущена на рабочем узле:
docker service ps configs_app
Результат содержит узел, см. 'NODE':
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xotczxp65lub configs_app.1 ... vmubs2204a Running Running 9 minutes ago
Более подробную информацию можно получить, например, с помощью команды:
docker service inspect --pretty configs_app
И самое главное, что же конкретно сделал наш сервис? На экран ничего не выводится, надо смотреть логи:
docker service logs configs_app
Результат точно такой же, как и раньше. Это означает, что Docker Swarm не только развернул наш сервис (контейнер), но и сделал наши файлы 'configs' доступными для нашего контейнера, запущенного на рабочем узле. Готово.
Резюме
В этой заметке мы использовали Docker Configs для передачи контейнерам (статических) конфигурационных данных. В файле 'docker-compose.yml' мы удалили секцию 'volumes' и заменили ее на секцию 'configs' . Теперь Docker Swarm управляет этими данными, и нам не нужен для этого общий том хранения. Неприятным моментом является то, что 'configs' не работает в Docker-Compose, что означает уход от единого 'docker-compose.yml', который может быть использован Docker-Compose и Docker Swarm.
Ссылки / кредиты
Data(base) persistence in docker swarm mode
https://forums.docker.com/t/data-base-persistence-in-docker-swarm-mode/20665
Deploy a stack to a swarm
https://docs.docker.com/engine/swarm/stack-deploy
Docker - configs
https://docs.docker.com/compose/compose-file/compose-file-v3/#configs
Docker Swarm Tutorial | Code Along | Zero to Hero under 1 Hour
https://takacsmark.com/docker-swarm-tutorial-for-beginners
How does Docker Swarm implement volume sharing?
https://stackoverflow.com/questions/47756029/how-does-docker-swarm-implement-volume-sharing
Подробнее
Docker Docker-compose
Недавний
- График временного ряда с Flask, Bootstrap и Chart.js
- Использование IPv6 с Microk8s
- Использование Ingress для доступа к RabbitMQ на кластере Microk8s
- Простая видеогалерея с Flask, Jinja, Bootstrap и JQuery
- Базовое планирование заданий с помощью APScheduler
- Коммутатор базы данных с HAProxy и HAProxy Runtime API
Большинство просмотренных
- Использование PyInstaller и Cython для создания исполняемого файла Python
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Подключение к службе на хосте Docker из контейнера Docker
- График временного ряда с Flask, Bootstrap и Chart.js
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb