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

Назначение документа#

Этот документ описывает базовый и проверенный способ настройки Docker и Docker Swarm для установки SmartCPD.

Основной сценарий рассчитан на инженера, которому нужен рабочий результат без ручной сборки всех настроек Docker Swarm.

Если инфраструктура готовится по собственным корпоративным правилам, этот документ можно использовать как краткий ориентир по минимально необходимым требованиям к Docker-окружению.

Предварительные требования#

Для подготовки окружения требуется:

  • сервер на Linux из семейств Debian-compatible или RHEL-compatible;
  • установленный Docker Engine версии 26+;
  • установленный containerd версии 1.7+;
  • пользователь с доступом к Docker daemon;
  • сетевая связность между узлами, которые будут входить в Docker Swarm cluster;
  • синхронизированное системное время на всех нодах, участвующих в установке SmartCPD;
  • заранее выбранный диапазон (рекоммендуется /16) адресов Docker-сетей, который не пересекается с существующими сетями инфраструктуры.

Для всех нод одного Docker Swarm cluster требуется:

  • одинаковая версия Docker Engine;
  • одинаковая или максимально близкая версия containerd;
  • одинаковые сетевые настройки Docker. Это крайне рекомендуется, чтобы избежать различий в поведении overlay networks, ingress и сервисного трафика между нодами.

Требования к сетевой доступности между ролями нод, balancer-контуром и внутренними сервисами SmartCPD описаны в разделе Матрица сетевых взаимодействий.

Требования к синхронизации времени описаны в разделе Синхронизация времени.

Рекомендуемый способ установки Docker Engine: официальный сайт Docker

Если в дистрибутиве уже используется собственный способ установки Docker, его тоже можно применять, если итоговая версия и поведение Docker соответствуют требованиям.

Скрипт smartcpd-docker-setup.sh#

В поставку SmartCPD входит скрипт smartcpd-docker-setup.sh.

Использование этого скрипта не является обязательным, но рекомендуется, поскольку он содержит отлаженные настройки для продуктивной системы.

Скрипт выполняет следующее:

  • для новой инсталляции позволяет создать типовое и одинаковое Docker-окружение со всеми необходимыми настройками для всех нод кластера;
  • для существующей инсталляции собирает текущие актуальные параметры уже подготовленного окружения;
  • генерирует единый скрипт docker/smartcpd-docker-node-setup.sh, который затем запускается на всех нужных нодах кластера для унификации настроек.

Если Docker и Docker Swarm подготавливаются вручную или по внутренним стандартам Заказчика, итоговая конфигурация должна соответствовать требованиям этого документа.

Для существующей инсталляции скрипт должен запускаться на ноде Docker Swarm с ролями manager и service для SmartCPD.

На действующей инсталляции запуск скрипта перезапускает Docker daemon и может привести к деградации сервисов. Выполнение таких операций требует планирования окна работ.

Скрипт должен запускаться от имени обычного пользователя с доступом к sudo и Docker daemon.

Добавление пользователя в группу docker (при необходимости):

sudo usermod -aG docker <user>
newgrp docker

Запуск для новой инсталляции#

  • Docker Swarm cluster еще не должен быть создан;
  • скрипт должен запускаться на ноде, которая будет иметь роль service в SmartCPD и одновременно станет manager в Docker Swarm.

Исключение: если в инфраструктуре требуется нестандартный Docker Swarm data-path-port из-за конфликтов с VXLAN/VMware NSX, Docker Swarm нужно создать вручную до запуска smartcpd-docker-setup.sh. Текущий bootstrap-сценарий smartcpd-docker-setup.sh не задает --data-path-port при docker swarm init.

Подробности и пример такого сценария приведены в разделе Типовые проблемы overlay network.

При запуске новой инсталляции smartcpd-docker-setup.sh запрашивает:

  • директорию хранения данных Docker runtime;
  • директорию хранения данных containerd;

Для Docker и containerd рекомендуется использовать отдельный раздел хранения, допускается один общий для обоих. Это позволяет уменьшить влияние Docker runtime на root fs, поскольку в этих директориях хранятся настройки, Docker images, созданные контейнеры и локальные логи.

  • базовый IPv4-адрес подсети класса /16 кластера Docker Swarm;
    • выделение единого сегмента гарантирует отсутствия пересечения любых docker подсетей с LAN
    • скрипт автоматически вычисляет и задает все необходимые сетевые настройки для docker
  • количество Docker log files, сохраняемых для каждого контейнера;
    • размер одного файла фиксированный 50MB
    • выключена компрессия
    • это дает достаточный объем данных для мониторинга/анализа текущего/недавнего состояния
    • не перегружает CPU и диски для оперативной работы
  • включать ли mTLS для Docker daemon
    • настройка mTLS в автоматический сценарий не входит
    • выводит рекомендации по настройке mTLS с указанием корректных сетевых настроек

Запуск для существующей инсталляции#

  • должен запускаться на ноде, которая уже имеет роль service в SmartCPD и является Docker Swarm manager;
  • автоматически собирает текущие параметры ноды, включая директории данных Docker и containerd, сетевые настройки Docker и параметры Docker Swarm;
  • показывает собранные параметры перед изменением конфигурации;
  • позволяет при необходимости изменить сохраняемый объем Docker logs;
  • выводит рекомендации по настройке mTLS;
  • пересобирает актуальный docker/smartcpd-docker-node-setup.sh для унификации остальных нод кластера;
  • перед применением на текущей ноде уже сохраняет сгенерированные файлы и позволяет отказаться от локального применения изменений.

Сценарий generate-only#

Этот сценарий используется, если:

  • не требуется применять изменения на ЭТОЙ ноде прямо сейчас;
  • нужно только пересобрать docker/smartcpd-docker-node-setup.sh для остальных нод;
  • старый manager больше не используется, и нужен новый актуальный адрес manager-ноды для подключения новых нод кластера.

Порядок действий:

  1. Запустить smartcpd-docker-setup.sh на текущей ноде с ролями service и manager.
  2. Дождаться генерации файлов и итоговой сводки параметров.
  3. На вопрос Apply generated files? ответить No.
  4. Скопировать docker/smartcpd-docker-node-setup.sh на нужные ноды и выполнить его там.

В этом случае:

  • изменения на текущей ноде применены не будут;
  • сгенерированные файлы останутся в каталоге docker/;
  • docker/smartcpd-docker-node-setup.sh будет содержать актуальные параметры Docker Swarm, включая текущий адрес manager-ноды и join token для новых нод.

Сценарий обновления service + manager для параметров вне setup#

Некоторые параметры действующей service + manager-ноды не изменяются через smartcpd-docker-setup.sh. К таким изменениям относятся, например:

  • перенос директории данных Docker;
  • перенос директории данных containerd;
  • другие host-level изменения, которые нужно выполнить до запуска setup-скрипта.

В таком случае рекомендуется следующий порядок:

  1. Оценить, приведет ли остановка текущей service + manager-ноды к потере manager quorum.
  2. Если при остановке этой ноды quorum будет потерян, заранее остановить контур SmartCPD:
./smartcpd-setup.sh down
  1. Выполнить ручную переконфигурацию ноды, включая перенос данных и обновление host-level настроек Docker и containerd.
  2. Запустить Docker и containerd, убедиться, что нода снова работает как Docker Swarm manager и кластер находится в рабочем состоянии.
  3. После этого запустить smartcpd-docker-setup.sh, чтобы он собрал новое фактическое состояние ноды и пересобрал docker/smartcpd-docker-node-setup.sh для остальных нод.
  4. Выполнить сгенерированный docker/smartcpd-docker-node-setup.sh на остальных нодах, которым нужно передать эти изменения.

Если после ручной переконфигурации требуется только обновить скрипт для остальных нод, можно использовать сценарий generate-only и ответить No на вопрос Apply generated files?.

Скрипт docker/smartcpd-docker-node-setup.sh#

  • генерируется скриптом smartcpd-docker-setup.sh;
  • запускается на остальных нодах кластера для приведения их Docker-настроек к единому состоянию;
  • не должен запускаться на той ноде, на которой был выполнен основной smartcpd-docker-setup.sh;
  • обновляет конфигурацию Docker и containerd;
  • при необходимости переподключает ноду к Docker Swarm cluster;
  • на действующей инсталляции его запуск требует планирования, поскольку перезапуск Docker daemon может вызвать деградацию сервисов на этой ноде.

Запуск на других manager#

При запуске на других нодах Docker Swarm manager с целью синхронизации настроек следует руководствоваться инструкциями самого скрипта.

Системные изменения, выполняемые скриптами#

smartcpd-docker-setup.sh#

До подтверждения на вопрос Apply generated files? скрипт только собирает текущее состояние, генерирует файлы в каталоге docker/ и показывает итоговую сводку параметров.

Системные изменения на текущей ноде выполняются только после ответа Yes на этот вопрос.

После подтверждения Apply скрипт может:

  • создать или перезаписать /etc/containerd/config.toml;
  • создать или перезаписать /etc/docker/daemon.json;
  • создать новые root-директории для Docker и containerd;
  • перезапустить сервисы containerd и Docker;
  • создать Docker Swarm cluster для новой инсталляции;
  • перенастроить подсеть docker_gwbridge через удаление и повторное создание сети;
  • собрать актуальные параметры Docker Swarm и пересобрать docker/smartcpd-docker-node-setup.sh для остальных нод.

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

docker/smartcpd-docker-node-setup.sh#

Этот скрипт применяется на остальных нодах кластера и сразу вносит системные изменения на целевой ноде.

Скрипт может:

  • создать или перезаписать /etc/containerd/config.toml;
  • создать или перезаписать /etc/docker/daemon.json;
  • создать новые root-директории для Docker и containerd;
  • перезапустить сервисы containerd и Docker;
  • перенастроить подсеть docker_gwbridge через удаление и повторное создание сети;
  • добавить ноду в Docker Swarm cluster;
  • при необходимости вывести ноду из Docker Swarm cluster и затем подключить ее повторно с актуальными параметрами.

Для выполнения этих действий скрипт должен запускаться от root или через sudo.

Ручная настройка Docker daemon#

Если smartcpd-docker-setup.sh не используется, Docker daemon должен быть настроен вручную одинаково на всех нодах одного Docker Swarm cluster.

Минимально необходимая конфигурация Docker daemon для базового production-сценария должна включать:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "2",
    "compress": "false"
  },
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Soft": 1048576,
      "Hard": 1048576
    }
  },
  "userland-proxy": false
}

Этот фрагмент не заменяет полную настройку Docker, но задает минимальный набор обязательных настроек для рабочей эксплуатации SmartCPD.

Рекомендуется дополнительно учитывать:

  • default-ulimits.nofile=1048576 как минимально необходимый лимит открытых файлов;
  • userland-proxy=false для исключения лишнего потребления памяти и лишнего proxy-механизма на хосте;
  • data-root, если Docker runtime должен хранить данные не в root fs, а на отдельном разделе;
  • одинаковую конфигурацию daemon.json на всех нодах одного кластера.

После изменения /etc/docker/daemon.json требуется перезапуск Docker daemon.

Прокси и host-level ограничения#

Если в окружении используются proxy, firewall, дополнительные сетевые фильтры или другие host-level ограничения, их нужно проверить отдельно.

Для рабочей эксплуатации SmartCPD важно, чтобы:

  • Docker daemon не использовал лишние proxy-механизмы, если они не нужны в инфраструктуре;
  • сетевые ограничения не мешали работе Docker Swarm, overlay networks и служебных соединений между нодами;
  • итоговые настройки оставались одинаковыми на всех нодах кластера.

Сетевые настройки Docker#

Все ноды одного Docker Swarm cluster должны иметь одинаковые сетевые настройки Docker.

Рекомендуется заранее выделить отдельный диапазон адресов для Docker-сетей, который не пересекается с LAN, VPN и другими используемыми подсетями инфраструктуры.

Для ручной настройки важно обеспечить:

  • отдельную подсеть для локальных Docker bridge networks;
  • отдельный диапазон для Docker Swarm overlay networks;
  • одинаковую настройку docker_gwbridge и ingress-контуров на всех нодах.

Типовые проблемы overlay network#

Если сервисы запускаются, но трафик между контейнерами в overlay network не проходит, нужно отдельно проверить host-level сетевые ограничения и offload-настройки интерфейсов.

На части виртуализированных инсталляций проблема связана с tx checksum offload на сетевом интерфейсе хоста. В таких случаях помогает отключение tx-checksum-ip-generic, например:

sudo ethtool -K ens192 tx-checksum-ip-generic off

или в общем виде:

sudo ethtool -K <iface> tx-checksum-ip-generic off

Если после этого проблема исчезает, настройку нужно закрепить штатным для конкретной ОС способом.

Если в инфраструктуре используется VMware NSX или другой VXLAN-контур, который конфликтует с Docker Swarm по UDP-порту 4789, при инициализации Docker Swarm следует использовать другой data-path-port, например 9789.

Для такого сценария Docker Swarm нужно создать вручную, например:

docker swarm init \
  --default-addr-pool <overlay_pool_base> \
  --default-addr-pool-mask-length <overlay_pool_mask_length> \
  --data-path-port 9789

После этого smartcpd-docker-setup.sh можно использовать в сценарии существующей инсталляции: для сбора текущего состояния, генерации docker/smartcpd-docker-node-setup.sh и унификации настроек остальных нод. Первичный docker swarm init в таком сценарии выполняется вручную.

Настройка Docker для подключения к нему контейнеров#

Некоторые сервисы SmartCPD должны иметь доступ к Docker API. В текущем setup-контракте это относится к сервисам:

  • license-server;
  • resolver;
  • metrics;
  • docker-health-exporter;
  • log2file.

Для SmartCPD допустимы следующие варианты подключения контейнеров к Docker API:

  • через локальный unix socket;
  • через mTLS-подключение к Docker daemon по TCP.

Подключение по plain TCP без mTLS не используется и не поддерживается как рабочий вариант.

Подключение через unix socket#

Это базовый и рекомендуемый вариант для локальной работы на service-ноде.

По умолчанию используется:

unix:///var/run/docker.sock

При использовании unix socket нужно обеспечить:

  • доступ контейнеров к сокету /var/run/docker.sock;
  • корректный gid группы, имеющей права на чтение и запись сокета;
  • одинаковый gid этой группы на всех service-нодах, где могут запускаться контейнеры, использующие Docker API.

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

Подключение через mTLS#

mTLS используется, когда требуется защищенное TCP-подключение контейнеров к Docker daemon вместо прямого использования unix socket.

Такая схема позволяет:

  • не использовать /var/run/docker.sock внутри контейнеров;
  • предоставить контейнерам доступ к Docker API;
  • не публиковать интерфейс управления Docker без защиты;
  • обеспечить взаимную TLS-аутентификацию Docker daemon и клиентов.

При такой схеме необходимо:

  • добавить в команду запуска dockerd параметры TLS-аутентификации;
  • указать пути к CA, серверному сертификату и серверному ключу;
  • использовать клиентский сертификат и ключ для доступа к Docker API;
  • публиковать Docker API только с взаимной TLS-аутентификацией;
  • выполнить одинаковую настройку на всех manager-нодах, где сервисы могут обращаться к Docker API.

Требования к сертификатам:

Сертификат Docker daemon рекомендуется выпускать с subjectAltName для DNS:docker и IP:127.0.0.1, поскольку обращения могут выполняться как по имени docker из контейнера, так и локально с хоста через 127.0.0.1.

  • ca.pem — файл корневого сертификата, включая intermediate CA, в формате PEM;
  • server-cert.pem — файл сертификата Docker daemon в формате PEM;
  • server-key.pem — файл ключа сертификата Docker daemon в формате PEM без пароля;
  • cert.pem — файл клиентского сертификата в формате PEM;
  • key.pem — файл клиентского ключа в формате PEM без пароля.

Следует учитывать, что сервисы могут мигрировать между нодами, поэтому серверные и клиентские сертификаты должны быть выпущены одной и той же CA-цепочкой.

Для настройки Docker daemon в схеме mTLS необходимо:

  1. Убедиться, что Docker-сети уже настроены и интерфейс docker0 имеет целевую адресацию.
  2. Получить адрес интерфейса docker0, например:
ip a show docker0
# или
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
  1. Настроить запуск dockerd с TLS-сокетами, включая:
    • tcp://127.0.0.1:2376 для локального доступа;
    • tcp://<docker0-ip>:2376 для доступа контейнеров через host-gateway.

Пример:

ExecStart=/usr/bin/dockerd \
  -H tcp://127.0.0.1:2376 \
  -H tcp://172.27.1.1:2376 \
  --tlsverify \
  --tlscacert=/etc/docker/tls/ca.pem \
  --tlscert=/etc/docker/tls/server-cert.pem \
  --tlskey=/etc/docker/tls/server-key.pem \
  --containerd=/run/containerd/containerd.sock
  1. Перезапустить Docker daemon.
  2. Настроить клиентское подключение, например:
export DOCKER_HOST=tcp://127.0.0.1:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/path/to/certificates

Каталог DOCKER_CERT_PATH должен содержать файлы ca.pem, cert.pem и key.pem с указанными именами.

Настройка mTLS в автоматический сценарий smartcpd-docker-setup.sh не входит и выполняется отдельно в соответствии с правилами инфраструктуры Заказчика.

Базовая настройка отказоустойчивости#

Если SmartCPD разворачивается в отказоустойчивой схеме, после настройки Docker и Docker Swarm необходимо:

  1. Подготовить и подключить к Docker Swarm все ноды, которые будут участвовать в отказоустойчивом контуре.
  2. Обеспечить наличие двух нод с ролью service.
  3. Сделать обе service-ноды Docker Swarm manager.
  4. Добавить в кластер еще как минимум один manager, чтобы общее количество manager-нод было не меньше 3 и сохранялся quorum.
  5. Назначить нодам роли service, worker, balancer и при необходимости analyzer через node labels.

Для HA-схемы SmartCPD важно:

  • service-ноды должны быть manager;
  • в кластере должен сохраняться рабочий manager quorum;
  • роли нод должны соответствовать выбранной схеме развертывания;
  • labels должны назначаться с учетом имени stack.

Рекомендуемый кандидат на роль третьего manager — резервная balancer-нода. Если роли service и balancer совмещены, третий manager обычно размещается на одной из worker-нод.

Подробные ограничения, варианты размещения ролей и поддерживаемые HA-схемы описаны в разделе Поддерживаемая HA-конфигурация. Требования к подготовке хранилищ и выбору путей описаны в разделе Требования к хранилищам.

Справочник базовых команд по управлению Docker Swarm#

Полная документация по Docker Swarm.

При работе с node labels важно учитывать, что префикс label зависит от имени stack. По умолчанию используется имя scpd, поэтому типовые labels выглядят как:

  • scpd.node.role.service
  • scpd.node.role.worker
  • scpd.node.role.analyzer
  • scpd.node.role.balancer

Если stack разворачивается с другим именем, то и префикс label будет другим.

  • docker node ls — посмотреть список серверов кластера.
  • docker node inspect --format '{{ json .Spec.Labels }}' <NODE-ID or NODE-HOSTNAME> — посмотреть установленные label.
  • docker node update --label-add label=value <NODE-ID or NODE-HOSTNAME> — установить label.
  • docker node update --label-rm label <NODE-ID or NODE-HOSTNAME> — удалить label.
  • docker swarm join-token worker — получить token для подключения worker-ноды.
  • docker node promote <NODE-ID or NODE-HOSTNAME> — повысить ноду до роли manager.
  • docker node demote <NODE-ID or NODE-HOSTNAME> — снять с ноды роль manager.
  • docker node rm <NODE-ID or NODE-HOSTNAME> — удалить ноду из Docker Swarm cluster.
  • docker stack services <stack_name> — посмотреть все запущенные сервисы стека.
  • docker service ps --no-trunc <stack_name>_<service_name> — посмотреть статус сервиса.
  • docker service logs <stack_name>_<service_name> — посмотреть логи сервиса.
  • docker service scale <stack_name>_<service_name>=0 — временно остановить сервис без удаления его описания.
  • docker service rm <stack_name>_<service_name> — удалить сервис.
  • docker stack rm <stack_name> — удалить стек.

Для docker service logs:

  • флаг -f — смотреть обновление в реальном времени;
  • флаг --since 5m — посмотреть логи за последние 5 минут.

Дата формирования

Powered by Altuera