Хранение секретных данных в Docker Secret
Описание
По умолчанию установка Accelera предполагает конфигурацию подключений к БД Redis, Clickhouse и тд в виде переменных среды. Однако в большинстве случаев, особенно на production-контуре, хранение паролей к БД не является достаточно безопасным.
Система Accelera поддерживает механизм Docker Secret, который позволяет сохранить ключи в защищенном хранилище на сервере, а при запуске сервисов передать их в соответствующие контейнеры.
Для настройки данного функционала допустимо использовать как команды docker service create, так и уже сконфигурированный docker-compose.yml.
Механизм Docker Secrets работает только в режиме Docker Swarm. По информации официальной документации Docker secrets также доступен при обычном использовании docker-compose, однако данная конфигурация оставляет файлы с чувствительным содержимым на диске, что не является достаточным.
Далее приведены шаги для настройки и активации данного функционала.
Активация Docker Swarm
Первым шагом необходимо активировать режим Docker Swarm. Выполните команду
docker swarm initСоздание секретов
Какие секреты поддерживаются
В настоящий момент в Docker Secret можно спрятать следующие переменные (также приведены названия сервисов, где они необходимы)
| Сервис | REDIS_CONNECTION | BROKER_CONNECTION | CLICK_PASS | DB_PASSWORD |
|---|---|---|---|---|
| flows_backoffice | ✅ | ✅ | ✅ | |
| flows_engine | ✅ | ✅ | ||
| flows_actions | ✅ | ✅ | ||
| flows_frontend | ||||
| flows_cache | ✅ | ✅ | ||
| flows_bulk | ✅ | ✅ | ✅ | |
| flows_timers | ✅ | ✅ | ||
| flows_segments | ✅ | ✅ | ✅ |
Новый секрет
Для добавления секрета в Docker Secret создайте файл с любым названием (этот файл будет потом удален). Запишите в него содержимое вашего секрета, сохраните.
Введите команду
docker secret create <название секрета> <путь к файлу>Содержимое файла будет добавлено в хранилище секретов, проверить можно командой
docker secret lsФайл можно удалить.
Редактирование секрета
Секреты являются неизменяемыми, поэтому единственный путь их обновления - удаление и создание нового.
Для удаления секрета используйте команду
docker secret rm <название секрета>ℹ️
При удалении секрета, который используется в запущенном сервиса вы получите ошибку. Остановите сервис перед удалением и созданием нового секрета. Либо создайте секрет с именем, отличным от используемого (например с постфиксом _1 и тд), а затем измените название секрета в .yml файле.
Настройка системы для использования секретов
Мы будем настраивать секреты на примере .yml файла. Для начала необходимо указать более новую версию compose для поддержки секретов, version: ‘3.3’. Затем добавить используемые секреты в нотацию верхнего уровня, пример:
version: '3.3'
services:
flows_backoffice:
...
flows_engine:
...
flows_actions:
...
flows_frontend:
...
flows_cache:
...
flows_bulk:
...
flows_timers:
...
secrets:
redis_connect:
external: true
broker_connect:
external: true
clickhouse_pass:
external: trueНастройка secrets находится на уровне services. Параметр external: true указывает, что секреты не задаются в файле, а берутся из хранилища Docker Secrets.
Названия секретов (redis_connect, broker_connect, clickhouse_pass) соответствуют названиям, которые были установлены командой docker secret create на предыдущем шаге.
Затем необходимо задать соответствующие секреты для каждого сервиса. Дополним предыдущий пример:
version: '3.3'
services:
flows_backoffice:
image: cr.yandex/crpc86n7lgg1287s01rq/flows_backoffice:2.2.0
container_name: flows_backoffice
command: npm run start
...
secrets:
- redis_connect
- broker_connect
- clickhouse_pass
flows_engine:
...
flows_actions:
...
flows_frontend:
...
flows_cache:
...
flows_bulk:
...
flows_timers:
...
secrets:
redis_connect:
external: true
broker_connect:
external: true
clickhouse_pass:
external: trueВ данном примере в сервис flows_backoffice передаются секреты, которые мы подключили заранее. Это необходимо сделать для каждого сервиса, согласно приведенной выше таблицы используемых переменных.
Настройка передачи секретов в систему Accelera
Когда основные настройки .yml файла заданы необходимо сообщить системе, что в перечисленных параметрах используются Docker Secrets. А также указать названия секретов для каждого параметра. Дополним предыдущий пример с flows_backoffice:
version: '3.3'
services:
flows_backoffice:
image: cr.yandex/crpc86n7lgg1287s01rq/flows_backoffice:2.2.0
container_name: flows_backoffice
command: npm run start
environment:
- USE_DOCKER_SECRETS=true
- REDIS_CONNECTION=redis_connect
- BROKER_CONNECTION=broker_connect
- CLICK_PASS=clickhouse_pass
...
secrets:
- redis_connect
- broker_connect
- clickhouse_pass
flows_engine:
...
flows_actions:
...
flows_frontend:
...
flows_cache:
...
flows_bulk:
...
flows_timers:
...
secrets:
redis_connect:
external: true
broker_connect:
external: true
clickhouse_pass:
external: trueПеременные среды USE_DOCKER_SECRETS указывает, что для настройки подключения необходимо использовать секреты docker, а не брать их напрямую из соответствующих переменных.
Далее в переменные REDIS_CONNECTION, BROKER_CONNECTION, CLICK_PASS передаем соответствующие секреты.
На этом настройка завершена.
Запуск, остановка, просмотр логов.
При работе в режиме Docker Swarm команды немного изменяются.
Запуск системы
docker stack deploy -c <путь к docker-compose.yml файлу> acceleraКоманда запустит стек сервисов с префиксом accelera. Проверить запущенные сервисы можно командой
docker service lsПример вывода команды
ID NAME MODE REPLICAS IMAGE PORTS
dxppqx1175jg accelera_flows_actions replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_actions:latest
49vg7dc748q5 accelera_flows_backoffice replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_backoffice:latest *:3002->3002/tcp
za2njzs5b42h accelera_flows_bulk replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_bulk:latest
nr06hzv2xu8d accelera_flows_cache replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_cache:latest
yupdvt6nwx85 accelera_flows_engine replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_engine:latest *:3020->3020/tcp
zdbdm6vebtfx accelera_flows_frontend replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_frontend:latest *:80->3005/tcp
pbwnuyvkzxyj accelera_flows_timers replicated 1/1 cr.yandex/crpc86n7lgg1287s01rq/flows_timers:latestК названиям сервисов из docker-compose прибавился префикс accelera.
Логи каждого сервиса можно просмотреть командой
docker service logs -f -n 100 <имя сервиса>Остановка системы
docker stack rm acceleraКоманда удалит весь стек сервисов accelera, остановив систему.
В примере был рассмотрена очень малая часть функционала Docker Swarm. Данный механизм имеет широкие возможности, подробнее можно ознакомиться в официальной документации.
Обновление конкретного сервиса без перезапуска всей системы
При обновлении/изменении секрета после редактирования compose-файла не обязательно перезапускать всю систему. Вы можете обновить настройку без перезапуска с помощью команды docker service update.
Например, вы поменяли пароль в секрете для переменной среды REDIS_CONNECTION. Для этого вам необходимо либо:
- Остановить всю систему.
- Удалить секрет redis_connect.
- Создать новый секрет redis_connect с новым значением.
- Запустить систему заново.
Либо:
- Создать новый секрет с новым значением, например redis_connect_2
- Указать его значение в переменной REDIS_CONNECT в файле docker-compose.yml.
- Перезапустить систему, удалить старый секрет.
Рекомендуется использовать способ 2, т.к. он исключает долгий простой системы.
Благодаря команде docker service update можно исключить отсюда пункт перезапуска всей системы.
Пример
Посмотрим на примере сервиса segments. Рассмотрим 2 случая:
- Когда меняется параметр MAX_POOL, который не является секретным.
- Когда меняется параметр DB_PASSWORD, который является секретным.
MAX_POOL
Данный параметр является переменной среды, поэтому команду service update нужно использовать с флагом --env-add
docker service update \
--env-add MAX_POOL=100 \
accelera_flows_segmentsТаким образом сервис получит обновление переменной, перезапустив только указанные сервисы (в примере - accelera_flows_segments).
Также можно добавлять в команду обновление других переменных, например вместе с пулом изменить уровень логирования в приложении:
docker service update \
--env-add MAX_POOL=100 \
--env-add LOG_LEVEL=debug \
accelera_flows_segmentsℹ️
Не забудьте зафиксировать внесенные изменения в переменных в файле docker-compose, иначе при полной перезагрузке системы в ней будут содержаться старые параметры.
DB_PASSWORD
При обновлении переменной с секретом к предыдущей команде добавится еще 2 флага —secret-add и —secret-rm.
Например, у вас есть запущенный сервис accelera_flows_segments, в котором указан пароль. Его необходимо обновить, для этого предварительно создайте секрет с новым именем, например db_pass_2. Далее отредактируйте для него файл docker-compose, чтобы сохранить конфигурацию.
Затем выполните команду:
docker service update \
--secret-add source=db_pass_2,target=db_pass_2 \
--secret-rm db_pass \
--env-add DB_PASSWORD=db_pass_2 \
accelera_flows_segmentsКоманда добавит в контейнер новый секрет db_pass_2, удалит старый (db_pass), а также обновит переменную среды DB_PASSWORD, указав в ней новый секрет. После перезапуска удалите секрет db_pass из системы хранения командой docker secret rm db_pass