Установка

Требования к серверам#

  • OS Linux с версией ядра не ниже 5
  • SELinux и AppArmor (при необходимости) со стандартными профилями docker: https://docs.docker.com/engine/security/seccomp/, https://docs.docker.com/engine/security/apparmor/
  • ПО, осуществляющее функциональность сетевых экранов (firewalld, ufw, …) должно быть отключено
  • установленное ПО docker версии не ниже 26
  • пользователь, с правами выполнения команд docker
  • доступ в репозиторий артефактов Altuera cr.repo.altuera.ru

Все серверы должны иметь доступ к docker репозиторию cr.repo.altuera.ru (доступ запрашивается у аккаунт менеджера Altuera. Если это не возможно, то необходимо вручную (используя команду docker load) загрузить образы на ВСЕ серверы

Требования к настройке БД Postgres#

Версия postgresSQL 14+

Это не означает, что решение не будет работать на версиях 12 или 13, но решение тестируется и разрабатывается только на поддерживаемых версиях.

Параметры настройки БД для платформы SmartCPD:

  • Отдельная БД
  • Пользователь-владелец этой БД, со схемой по-умолчанию public
  • Пользователь для grafana со схемой по-умолчанию grafana, имеющий права на все объекты данной схемы

Пример скрипта инициализации БД для SmartCPD:

-- create smartcpd user and database
CREATE USER $DB_SMARTCPD_USER WITH PASSWORD '$DB_SMARTCPD_PASSWORD';
CREATE DATABASE $DB_SMARTCPD_NAME OWNER $DB_SMARTCPD_USER;

-- default schema for smartcpd user
ALTER ROLE $DB_SMARTCPD_USER SET search_path TO public;

-- create grafana user and schema (owned by grafana)
CREATE USER $DB_GRAFANA_USER WITH PASSWORD '$DB_GRAFANA_PASSWORD';

-- switch to DB to create schema
\c $DB_SMARTCPD_NAME
CREATE SCHEMA grafana AUTHORIZATION $DB_GRAFANA_USER;

-- enforce access for grafana user
GRANT ALL ON SCHEMA grafana TO $DB_GRAFANA_USER;
ALTER ROLE $DB_GRAFANA_USER SET search_path TO grafana;

Дополнительные пользователи#

Если необходимо, то можно создать отдельные УЗ для доступа в БД для каждого сервиса.

  • для доступа сервиса billing-server: полные права на схему public (включая создание сущностей)
CREATE USER $DB_BILLING_USER WITH PASSWORD '$DB_BILLING_PASSWORD';
GRANT ALL ON SCHEMA public TO $DB_BILLING_USER;
GRANT ALL ON ALL TABLES IN SCHEMA public TO $DB_BILLING_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_BILLING_USER;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO $DB_BILLING_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_BILLING_USER;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO $DB_BILLING_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO $DB_BILLING_USER;
ALTER ROLE $DB_BILLING_USER SET search_path TO public;
  • для доступа amd контейнеров в бд: права на select, update, insert в схему public
CREATE USER $DB_AMD_USER WITH PASSWORD '$DB_AMD_PASSWORD';
GRANT USAGE ON SCHEMA public TO $DB_AMD_USER;
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO $DB_AMD_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE ON TABLES TO $DB_AMD_USER
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $DB_AMD_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO $DB_AMD_USER;
ALTER ROLE $DB_AMD_USER SET search_path TO public;
  • для доступа компонента grafana к данным: права на select в схему public
CREATE USER $DB_GRAFANA_DS_USER WITH PASSWORD '$DB_GRAFANA_DS_PASSWORD';
GRANT USAGE ON SCHEMA public TO $DB_GRAFANA_DS_USER;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO $DB_GRAFANA_DS_USER;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO $DB_GRAFANA_DS_USER;
ALTER ROLE $DB_GRAFANA_DS_USER SET search_path TO public;
  • управления компонентом markup-api своими сущностями в схеме public
CREATE USER $DB_MARKUP_USER WITH PASSWORD '$DB_MARKUP_PASSWORD';
GRANT USAGE, CREATE ON SCHEMA public TO $DB_MARKUP_USER;
ALTER ROLE $DB_MARKUP_USER SET search_path TO public;

Чеклист для установки#

Эти данные необходимо собрать к моменту начала установки продукта.

ПараметрКомментарий
ИНННе может быть изменен в дальнейшем, на него будет выписана лицензия
email администратораМожет быть изменен через портал, пользователь по-умолчанию
пароль администратораМожет быть изменен через портал
доменное имя (адрес) для веб порталаесли подключение без внешнего балансировщика
файл TLS сертификата сервера для веб порталаформат PEM, должен включать все intermediateCA (сначала сертификат сервера, потом все CA в очередности цепочки)
файл ключа TLS сертификата сервера для веб порталаформат PEM, без пароля
хост или ip адрес сервера Postgresполное доменное имя или ip адрес
порт сервера Postgres
имя базы данных на сервере Postgres
логин основного (portal) пользователя БДпользователя с ролью owner указанной выше БД
пароль основного (portal) пользователя БД
логин пользователя конфигурационной БД для grafana
пароль пользователя конфигурационной БД для grafana
путь к директории node_recordsпо-умолчанию /opt/scpd/node_records
путь к директории node_resultsпо-умолчанию /opt/scpd/node_results
путь к директории node_promptsпо-умолчанию /opt/scpd/node_prompts
путь к директории metrics_dataпо-умолчанию /opt/shared_data/metrics_data
путь к директории config-server_dataпо-умолчанию /opt/shared_data/config-server_data
путь к директории redis_dataпо-умолчанию /opt/scpd/redis_data
часовой пояспо-умолчанию Europe/Moscow
срок хранения статистических метрик в месяцахпо-умолчанию 6
срок хранения статистики SmartCPD в месяцахпо-умолчанию 6
логин и пароль к репозиторию cr.repo.altuera.ru(если есть доступ) запросить у аккаунт менеджера
лицензионный файлзапросить у аккаунт менеджера
облачные файлы моделейдоступ запросить у аккаунт менеджера Альтуэра (см. ниже)

Облачные модели определения автоответчиков и роботов автоматически обновляются сервисом cloud-connector, из облака Altuera по адресу: https://scpd.altuera.ru:5000/. Для успешной работы детекции роботов эти модели необходимо регулярно обновлять. Если доступ к облаку Altuera отсутствует, то это нужно делать вручную.

Дополнительные данные для установки#

Дополнительные опциональные параметры необходимы при расширенной настройке безопасности контура.

ПараметрКомментарий
id пользователя, под которым будут запущены контейнеры сервисовпо-умолчанию 0, необходимо выдать права на запись в соответствующие директории для данного uid
id группы, под которой будут запущены контейнеры сервисовпо-умолчанию 0
адрес сокета dockerпо-умолчанию unix:///var/run/docker.sock
группа (или gid) с правами чтения и записи в сокетпо-умолчанию docker, gid ДОЛЖЕН быть одинаковым на всех service нодах
файл CA TLS сертификатов docker daemonформат PEM, должен включать все CA, включая root и intermediate
файл клиентского TLS сертификата docker daemonформат PEM
файл ключа клиентского TLS сертификата docker daemonформат PEM, без пароля
логин пользователя БД для сервиса billing-server
пароль пользователя БД для сервиса billing-server
логин пользователя БД для сервиса trunksyncможно read only
пароль пользователя БД для сервиса trunksync
логин пользователя БД для сервиса amd
пароль пользователя БД для сервиса amd
логин пользователя БД для доступа к данным из grafanaможно read only
пароль пользователя БД для доступа к данным из grafana
адрес HTTPS прокси для обновления моделей
файл CA TLS сертификата HTTPS проксиформат PEM

Настройка дополнительных параметров tls для веб интерфейса портала#

Доступны при ответе y или yes на вопрос Setup extended portal https settings.

Позволяют настроить параметры подключения ssl для nginx в контейнере portal-frontend. Названия параметров соответствуют параметрам nginx, как и синтаксис значений. ; в конце значений ставить НЕ нужно.

Внимание: некорректные настройки могут привести к неработоспособности контейнера или невозможности клиентов подключиться. Для сброса парамеров в значения по-умолчанию удалить из setup.env все переменные VAR_NGINX_*, после этого заново запустить setup.sh и ответить n или no на этот вопрос.

Установка и запуск SmartCPD#

Должна выполняться пользователем, имеющим права на выполнение команд docker.

Установка должна происходить на сервере, которому назначена роль service.

  1. выполнить настройку docker
  2. инициализировать docker swarm кластер
  3. выполнить настройки service ноды
  4. добавить серверу роль service: docker node update --label-add scpd.node.role.service=true <node_name>

node_name можно узнать из вывода команды docker node ls

  1. скопировать файлы установки нужной версии релиза из репозитория https://raw.repo.altuera.ru/_/smartcpd/prod/release/
  2. разместить файлы setup/compose.tmpl и setup/setup.sh на сервере с ролью service, сюда же положить файлы сертификата и ключа сертификата сервера (при необходимости)

Рекомендуется сделать это в сетевой директории (например /opt/shared_data/setup), доступной со всех manager, чтобы сохранить возможность управления инсталляцией при выходе из строя одного из manager-серверов.

скрипт setup/download-images.sh позволяет скачать нужные образы в локальную директорию, для последующей ручной загрузки через docker load. Перед запуском скрипта, возможно, потребуется авторизация в репозитории: docker login cr.repo.altuera.ru

  1. назначить права выполнения файлу setup.sh: chmod +x ./setup.sh
  2. залогиниться в репозиторий (если есть доступ) cr.repo.altuera.ru командой docker login cr.repo.altuera.ru

Если доступа к репозиторию нет, то импортировать все образы командой docker load

  1. запустить исполняемый файл: ./setup.sh

При переносе инсталляции на другой swarm cluster необходимо заново указать все сертификаты

  • указать необходимые параметры настройки в процессе установки
  • настройки будут сохранены в файле setup.env и могут быть переиспользованы при повторном запуске скрипта (для переконфигурации)
  • дождаться окончания установки

Окончание установки - когда появляется сообщение overall progress: waiting for new tasks. После этого выполнение команды нужно остановить Ctrl+C. Это нормально, потому что пока не все сервисы могут запуститься из-за отсутствия нод с другими ролями.

  1. Дождаться запуска сервисов. Старт может занять некоторое время - должны скачаться и развернуться образы, запуститься сервисы, развернуться схемы БД. Контролировать процесс можно командой: docker stack services smartcpd. Список запущенных сервисов в результате успешной установки должен включать (количество реплик 1/1):
NAME                       MODE         REPLICAS
smartcpd_cloud-connector   replicated   1/1
smartcpd_config-server     replicated   1/1
smartcpd_billing-server    replicated   1/1
smartcpd_grafana           replicated   1/1
smartcpd_license-server    replicated   1/1
smartcpd_markup-api        replicated   1/1
smartcpd_metrics           replicated   1/1
smartcpd_portal-api        replicated   1/1
smartcpd_portal-frontend   replicated   1/1
smartcpd_resolver          replicated   1/1
smartcpd_redis             global       1/1
smartcpd_redis-sentinel    replicated   2/3

Если какой-то из сервисов не стартует, проанализировать причину можно командой docker service ps --no-trunc <service_name>.

Если что-то пошло не так, то можно начать установку “с нуля”:

  • удалить развернутый стек docker stack rm smartcpd
  • удалить созданные тома docker compose down --volumes
  • очистить или пересоздать БД
  • удалить setup.env
  • запустить ./setup.sh заново

Загрузка необходимых для работы файлов#

  1. если портал установлен за внешним балансировщиком/reverse-proxy, то настроенному там адресу
    • если портал установлен с поддержкой https, то по указанному адресу при установке
  2. Залогиниться, используя логин и пароль администратора, указанные при установке.
  3. Загрузить файл лицензии в разделе Глобальные настройки
  4. Загрузить файлы облачных моделей в разделе Глобальные настройки (только если не используется cloud-connector)

Добавление остальных нод#

После загрузки необходимых файлов необходимо добавить в решение оставшиеся серверы и назначить им соответствующие роли.

Образы SmartCPD достаточно большие, поэтому их загрузка может занимать время, которое может быть критично при восстановлении сервисов в случае отказа ноды. Поэтому для резервных нод (service,analyzer) рекомендуется выполнить предварительную загрузку образов (рекомендуется чтобы директория инсталляции была примонтирована на все ноды):

docker login cr.repo.altuera.ru
cd /path/to/directory/with/compose.yml
docker compose pull

Это существенно ускорит разворачивание сервисов при их миграции. То же требуется выполнять после обновлений ПО (версий образов)

Добавление серверов с ролью service#

Решение не требует наличия более 2-х нод с ролью service.

На добавляемом сервере:

  1. выполнить настройку docker
  2. выполнить настройки service ноды
  3. добавить сервер в swarm кластер

На manager сервере:

  1. Сделать новый сервер manager кластера (service ноды ДОЛЖНЫ быть manager): docker node promote <node_name>
  2. Установить новому серверу роль service: docker node update --label-add scpd.node.role.service=true <node_name>

Добавление серверов с ролью analyzer#

Решение не требует наличия более 2-х нод с ролью analyzer, в большинстве случаем достаточно одного сервера

На добавляемом сервере:

  1. выполнить настройку docker
  2. добавить сервер в swarm кластер

На manager сервере:

Установить новому серверу роль analyzer: docker node update --label-add scpd.node.role.analyzer=true <node_name>

Добавление серверов с ролью balancer#

Решение не требует наличия более 2-х нод с ролью balancer, для отказоустойчивой работы требуется 2 таких ноды.

На добавляемом сервере:

  1. выполнить настройку docker
  2. добавить сервер в swarm кластер

На manager сервере:

Установить новому серверу роль balancer: docker node update --label-add scpd.node.role.balancer=true <node_name>

Добавление серверов с ролью worker#

Можно добавлять любое количество серверов с этой ролью.

На добавляемом сервере:

  1. выполнить настройку docker
  2. выполнить настройки worker ноды
  3. добавить сервер в swarm кластер

На manager сервере:

Установить новому серверу роль worker: docker node update --label-add scpd.node.role.worker=true <node_name>

Контроль запуска всех сервисов#

На manager ноде выполнить команду docker stack services smartcpd

Убедиться, что в столбце REPLICAS отображается корректное число запущенных сервисов: значения до и после / совпадают.

Настройка отказоустойчивости кластера#

При необходимости выполнить настройку отказоусточивости swarm кластера

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

В портале в разделе Настройки компании указать необходимые параметры подключения.

SmartCPD готов к работе!


Дополнительные материалы#

Индивидуальные настройки нод для ролей#

Настройки service ноды#

На сервере с ролью service должны быть созданы следующие директории:

  • metrics_data путь по-умолчанию /opt/shared_data/metrics_data. В этой директории хранятся собранные статистические метрики. При наличии более одного сервера с ролью service эта директория должна быть расположена в отказоустойчивом сетевом хранилище, и быть доступна по одинаковому пути на всех серверах с ролью service. Даже если сервер один, отказоустойчивое расположение рекомендуется, в противном случае необходимо настроить регулярное резервное копирование.

  • config-server_data путь по-умолчанию /opt/shared_data/config-server_data. В этой директории хранится активная конфигурация решения. При наличии более одного сервера с ролью service эта директория должна быть расположена в отказоустойчивом сетевом хранилище, и быть доступна по одинаковому пути на всех серверах с ролью service. Даже если сервер один, отказоустойчивое расположение рекомендуется, в противном случае необходимо настроить регулярное резервное копирование.

  • redis_data путь по-умолчанию /opt/scpd/redis_data. В этой директории хранится текущее состояние БД Redis и она требуется для восстановления при рестарте сервиса redis. Локальная директория на всех серверах с ролью service. Резервное копирование не требуется.

При настройке (setup.sh) запуска ПО под uid/gid пользователя, отличного от 0 (root), НЕОБХОДИМО выдать для указанных uid/gid права на запись в вышеуказанные директории: sudo chown -R uid:gid /path/to/dir.

Настройки worker ноды#

На сервере с ролью worker должны быть созданы следующие директории:

  • node_records путь по-умолчанию /opt/scpd/node_records. На всех серверах этой роли пути к директории должны быть одинаковыми. Резервное копирование не требуется.

  • node_results путь по-умолчанию /opt/scpd/node_results. На всех серверах этой роли пути к директории должны быть одинаковыми. Резервное копирование не требуется.

  • node_prompts путь по-умолчанию /opt/scpd/node_prompts. На всех серверах этой роли пути к директории должны быть одинаковыми. Резервное копирование не требуется.

При настройке (setup.sh) запуска ПО под uid/gid пользователя, отличного от 0 (root), НЕОБХОДИМО выдать для указанных uid/gid права на запись в вышеуказанные директории: sudo chown -R uid:gid /path/to/dir.

Изменение месторасположения директорий для docker volumes#

При необходимости изменить месторасположение директорий (metrics_data, config-server_data, redis_data, node_records, node_results, node_prompts) :

  1. Остановить нужный сервис (docker service rm)
  2. на всех серверах, где был запущен этот сервис удалить соответствующие volumes (docker volume rm, список можно получить docker volume ls)
  3. скопировать содержимое старой директории в новую с сохранением прав доступа
  4. Запустить сервис через setup.sh, указав новое расположение директории

Для рабочих (scpd.node.role.worker=true) можно это делать последовательно без глобальной остановки сервиса:

  • через setup.sh заменить целевую директорию
  • для каждой worker ноды (по-очереди)
    • снять лейбл с одной ноды
    • выполнить пп. 2 и 3 на этой ноде
    • вернуть лейбл на ноду

Настройка docker для SmartCPD#

На всех серверах, необходимо выполнить одинаковую настройку docker daemon для работы в режиме swarm.

Настройка сервиса docker#

Выполняются на каждом хосте.

Настройки записываются в файл /etc/docker/daemon.json и требуют перезапуск docker после его изменения. Если файл отсутствует, его необходимо создать.

Настройка директории хранения данных Docker#

По-умолчанию docker хранит даннные (образы, тома, слои контейнеров, логи) в директории /var/lib/docker, которая находится на основном разделе /.

Если основной раздел имеет достаточный размер (20 GB свободного места), то этот параметр можно не менять.

Если места на основном разделе не достаточно, или хочется избежать возможного отказа сервера из-за переполнения основного раздела, то директорию docker необходимо перенести на другой раздел ОС.

Для этого в файле настройки /etc/docker/daemon.json указываем необходимую директорию на другом разделе:

{
  "data-root": "/opt/lib/docker"
}
Настройка сетей docker#

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

Также важно, чтобы сетевой пул docker не пересекался с сетями в локальной сети.

Для этого выделяем подсеть приватных ip адресов, например 172.27.0.0/16 и разделяем её на 2 сегмента:

  • 172.27.0.0/17 - для локальных сетей docker
  • 172.27.128.0/17 - для сетей docker swarm

Минимальные требования к пулам адресов:

  • пул /23 и размер одной сети /24 для локальных сетей docker
  • пул /22 и размер одной сети /24 для сетей docker swarm
  • адресные пространства пулов НЕ ДОЛЖНЫ пересекаться

Подсеть для локальных сетей docker используем в конфигурационном файле /etc/docker/daemon.json:

{
  "default-address-pools": [ { "base" : "172.27.0.0/17", "size" : 24 } ],
  "userland-proxy": false
}

Параметр "userland-proxy": false настоятельно рекомендуется добавить в файл конфигурации, чтобы избежать ненужного потребления памяти.

Пример файла с минимальными настройками#
{
    "data-root": "/opt/lib/docker",
    "default-address-pools": [ { "base" : "172.27.0.0/23", "size" : 24 } ],
    "userland-proxy": false
}

Настройка подключения контейнеров к docker API#

Контейнеры сервисов license-server, metrics и resolver ДОЛЖНЫ иметь доступ к docker API.

Детали и общие принципы настройки docker daemon см. ниже

unix socket#

По-умолчанию подразумевается доступ к docker API через стандартный unix сокет: unix:///var/run/docker.sock. В процессе инсталляции также будет запрошена группа (или gid), имеющая право на запись и чтение этого сокета. По-умолчанию это группа docker. gid этой группы ДОЛЖЕН быть одинаковым на всех нодах с ролью service.

plain tcp#

При необходимости подключение к docker API может быть настроено через tcp подключение. Для этого docker daemon ДОЛЖЕН быть запущен на ip адресе интерфейса docker0.

Важно: Если меняется, пул адресов docker или адресация сети docker0, то: сначала изменить пул, перезапустить демон docker (чтобы сеть docker0 получила целевую адресацию), а после настраивать ip адрес сокета docker.

mTLS tcp#

Настройка аналогичная plain tcp, только добавляются файлы сертификатов:

  • ca.pem - корневой и промежуточные (при наличии) сертификаты CA в формате pem
  • cert.pem - клиентский TLS сертификат в формате pem
  • key.pem - ключ клиентского TLS сертификата в формате pem без пароля

Настройка docker daemon для предоставления безопасного доступа к docker API из контейнеров#

Это общее описание шагов для настройки docker к использованию mTLS подключения к docker API. Оно может отличаться для различных инсталляций, конфигураций и используемых ОС. Подробная документация на официальном сайте docker.

Данная настройка позволяет:

  • не использовать сокет docker /var/run/docker.sock для доступа к docker API
  • обеспечить доступ контейнеров (metrics, resolver) к docker API
  • не допустить публикацию интерфейса управления docker за пределы сервера
  • обеспечить взаимную аутентификацию (mTLS) докер демона и клиентов

Необходимо выполнить на всех нодах, являющихся manager кластера.

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

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

  • ca.pem файл корневого сертификата, включая промежуточные (intermediate CA) в формате PEM
  • server-cert.pem файл сертификата сервера в формате PEM
  • server-key.pem файл ключа сертификата сервера в формате PEM (без пароля)
  • cert.pem файл клиентского сертификата в формате PEM
  • key.pem файл ключа клиентского сертификата сервера в формате PEM (без пароля)

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

Настройка сокетов для docker API#

Важно: сети docker УЖЕ должны быть настроены (сеть docker0 имеет целевую адресацию). Если меняется, в том числе, пул адресов docker или адресация сети docker0, то: сначала изменить пул, перезапустить демон docker (чтобы сеть docker0 получила целевую адресацию), а после настраивать ip адреса сокетов.

  1. Получить ip адрес интерфейса docker0:
ip a show docker0
# или
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
  1. Настроить запуск сервиса docker в файле docker.service (или альтернативных для различных ОС) В строке ExecStart (команда запуска сервиса) удалить все существующие ключи -H и добавить два:
  • -H tcp://127.0.0.1:2376 - для локального доступа к docker daemon
  • -H tcp://172.27.1.1:2376 - адрес интерфейса docker0 (подставить полученный в п.1)

Пример получившейся строки:

ExecStart=/usr/bin/dockerd -H tcp://127.0.0.1:2376 -H tcp://172.27.1.1:2376 --containerd=/run/containerd/containerd.sock
  1. Настроить взаимную аутентификацию (mTLS) в файле /etc/docker/daemon.json добавить:
{
  "tls": true,
  "tlsverify": true,
  "tlscacert": "/path/to/ca.pem",
  "tlscert": "/path/to/server-cert.pem",
  "tlskey": "/path/to/server-key.pem"
}

где /path/to/ - полный путь к соответствующим файлам.

  1. Перезапустить сервис docker

  2. Настроить подключение клиента docker с авторизацией

Чтобы локальный клиент (команда docker) мог подключаться к сервису, необходимо задать следующие переменные окружения пользователю, выполняющему команду docker:

export DOCKER_HOST=tcp://127.0.0.1:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/path/to/certificates

где /path/to/certificates - путь к папке с файлами ca.pem, cert.pem, key.pem (названия файлов важны)

Попробовать подключение: команда docker info должна отработать без ошибок.

Для применения ко всем пользователям сервера - добавить эти переменные окружения в глобальную конфигурацию сервера (соответственно ОС): например /etc/environment, /etc/profile.d/docker.sh, /etc/bash.bashrc, /etc/zsh/zshrc и т.д.

Режим docker Swarm#

Все команды должны выполняться пользователем, имеющим права для взаимодействия с docker. Обычно для этого достаточно добавить пользователя в группу docker.

Инициализация Docker Swarm#

На одном сервере (который будет иметь роль service) выполнить инициализацию режима swarm:

Подставить сеть, выделенную для режима docker swarm

docker swarm init \
    --default-addr-pool 172.27.128.0/17 \
    --default-addr-pool-mask-length 24

После инициализации, данный сервер получает роль manager в кластере swarm. Все операции по управлению кластером могут совершаться только на серверах с ролью manager.

Посмотреть результат (список нод кластера): docker node ls

Добавление сервера в swarm кластер#

На manager сервере выполнить команду: docker swarm join-token worker

Результатом выполнения будет вывод команды для присоединения сервера к кластеру.

Эту команду необходимо выполнить на целевом сервере, который должен быть подключен к кластеру, например:

    docker swarm join --token SWMTKN-1-01thbgajtlnlkb0efdz4ux2kqd0qienhzlbuwdmtfiwi47z60k-9nk3ya17qvb9qs079thsxnj2a 10.201.10.11:2377

Результат добавления можно посмотреть на manager ноде командой docker node ls.

Настройка отказоусточивости swarm кластера#

Docker swarm кластер работает, пока в активном состоянии находится N/2+1 его серверов с ролью manager. Поэтому для отказоустойчивого решения необходимо иметь:

  • минимум 3 сервера с ролью manager (отказ одного из них не приведет к остановке кластера)
  • 5 серверов - максимальное рекомендованное количество (бОльшее число существенно увеличит нагрузку на серверы с ролью manager)

Также рекомендуется устанавливать роль manager наименее нагруженным серверам, поэтому в решении SmartCPD рекомендуется назначать эту роль следующим серверам:

  • при установке решения на 2 сервера (нет отказоусточивости) - только service ноде
  • при установке решения на 3 сервера - всем серверам
  • в остальных случаях: (выбрать 3 или 5 менеджеров со следующим приоритетом)
    • service ноды (все service ноды должны быть manager)
    • balancer ноды
    • analyzer ноды
  • не рекомендуется назначать worker ноды менеджерами кластера, как наиболее нагруженные

Для добавления (повышения) роли ноды до менеджера, на любом из менеджеров выполнить команду: docker node promote <NODE-ID or NODE-HOSTNAME>

Для снятия (понижения) роли ноды: docker node demote <NODE-ID or NODE-HOSTNAME>

Результат можно посмотреть на manager ноде командой docker node ls.

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

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

  • 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 stack services smartcpd посмотреть все запущенные сервисы стека smartcpd
  • docker service ps --no-trunc smartcpd_<service_name> посмотреть статус сервиса
  • docker service logs smartcpd_<service_name> посмотреть логи сервиса (все запущенные экземпляры)
    • флаг -f смотреть обновление в реальном времени
    • флаг --since 5m за последние 5 минут

Дополнительные скрипты БД#

Смена владельца сущностей для billing-server#

DO $$
DECLARE
    -- <<< CHANGE THESE
    target_owner CONSTANT name := 'billing';
    target_schema CONSTANT name := 'public';

    tbl_name   text;
    parent_oid regclass;
    part_oid   regclass;

    func_rec record;
BEGIN
    ----------------------------------------------------------------------
    -- 1) Tables and their partitions
    ----------------------------------------------------------------------
FOR tbl_name IN
SELECT unnest(ARRAY[
              'flyway_schema_history',
              'billing',
              'cpn_stats',
              'payments',
              'stats',
              'tariff',
              'cdr',
              'cpd_records_links'
                  ])
           LOOP
-- Base table
BEGIN
EXECUTE format(
        'ALTER TABLE %I.%I OWNER TO %I',
        target_schema, tbl_name, target_owner
        );
EXCEPTION
            WHEN undefined_table THEN
                NULL;
END;

        -- Find parent OID
BEGIN
SELECT format('%I.%I', target_schema, tbl_name)::regclass INTO parent_oid;
EXCEPTION
            WHEN undefined_table THEN
                parent_oid := NULL;
END;

        -- Partitions
        IF parent_oid IS NOT NULL THEN
            FOR part_oid IN
SELECT inhrelid::regclass
FROM pg_inherits
WHERE inhparent = parent_oid
    LOOP
                EXECUTE format(
                    'ALTER TABLE %s OWNER TO %I',
                    part_oid, target_owner
                );
END LOOP;
END IF;
END LOOP;

    ----------------------------------------------------------------------
    -- 2) Specific sequences
    ----------------------------------------------------------------------
FOR tbl_name IN
SELECT unnest(ARRAY[
              'payments_id_seq',
              'tariff_id_seq',
              'stats_partitioned_hid_seq'
                  ])
           LOOP
BEGIN
EXECUTE format(
        'ALTER SEQUENCE %I.%I OWNER TO %I',
        target_schema, tbl_name, target_owner
        );
EXCEPTION
            WHEN undefined_table THEN NULL;
END;
END LOOP;

    ----------------------------------------------------------------------
    -- 3) Function(s) named create_partitions in this schema
    ----------------------------------------------------------------------
FOR func_rec IN
SELECT
    n.nspname AS schema_name,
    p.proname AS func_name,
    pg_get_function_identity_arguments(p.oid) AS argtypes
FROM pg_proc p
         JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = target_schema
  AND p.proname = 'create_partitions'
    LOOP
        EXECUTE format(
            'ALTER FUNCTION %I.%I(%s) OWNER TO %I',
            func_rec.schema_name,
            func_rec.func_name,
            func_rec.argtypes,
            target_owner
        );
END LOOP;
END $$;

Вывод владельцев сущностей#

-- tables
SELECT
    c.relname AS table,
    pg_catalog.pg_get_userbyid(c.relowner) AS owner
FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
  AND c.relkind IN ('r','p')
ORDER BY c.relname;

-- sequenses
SELECT
    n.nspname AS schema,
    c.relname AS sequence,
    pg_catalog.pg_get_userbyid(c.relowner) AS owner
FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'S' and n.nspname = 'public'
ORDER BY n.nspname, c.relname;

-- functions
SELECT
    n.nspname AS schema,
    p.proname AS function,
    pg_catalog.pg_get_userbyid(p.proowner) AS owner,
    pg_get_function_identity_arguments(p.oid) AS args
FROM pg_proc p
    JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'public'
ORDER BY n.nspname, p.proname, args;

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