Под секретами подразумеваются: логины, пароли, сертификаты, api ключи, ssh ключи и другие секретные данные. В основном конечно это данные необходимые для подключения к тому или иному сервису.
Конечно на данный момент уже существует куча сервисов сторонних компаний для хранения секретов, например, Hashicorp Vault. Но минус таких сервисов в том, что их еще нужно развернуть и настроить.
С версии Docker 1.13.0 база, которую использует Swarm лежит на диске в зашифрованном виде по умолчанию, которая находится на менеджерах кластера. По умолчанию именно тут хранится вся информация необходимая для коммуникации узлов кластера между собой. Например, tls сертификаты для узлов.
В самом начале необходимо конечно же поместить секреты в саму базу и уже потом передать эти секреты сервисам и соответственно их контейнерам/задачам. Только контейнеры в сервисе могут получить доступ к этим секретам, т.е. контейнеры вне сервиса не смогут получить доступ к ним. Все эти секреты помещаются в оперативную память и доступны внутри контейнера по пути /run/secrets/<имя>. Хранится всё в виде ключ: значение.
В этом конфиг-файле для стека swarm я поместил все пароли в открытом виде. И понятное дело, что это может привести к утечке и последующему взлому, поэтому использовать такой вариант в боевой среде не рекомендуется.
Также если передавать пароли через переменные при создании сервиса или контейнера, то при выполнении команды docker container inspect эти пароли будут выведены.
Создание секрета
Для того, чтобы добавить новый секрет в кластер Swarm используется команда docker secreat create.
Вариант 1️⃣
Для начала создаётся файл, в который помещается секрет. После используется команда docker secreat create для создания секрета со значением из файла.
vim psql_user.txt
app
docker secret create psql_user psql_user.txt
y5jqu91e43jivxje614br60op
После добавления секрета необходимо удалить файл.
rm psql_user.txt
Вариант 2️⃣
Этот вариант не рекомендуется использовать потому что при использовании мониторинга с записью всех команд пользователя в консоли пароль может быть записан в систему мониторинга.
set +o history
echo "secret" | docker secreat create psql_pwd
set -o history
Просмотр секретов
Для того чтобы просмотреть какие секреты есть в базе используется команда docker secret ls.
docker secret ls
ID NAME DRIVER CREATED UPDATED
y5jqu91e43jivxje614br60op psql_user 29 seconds ago 29 seconds ago
После того как секрет был создан я сам уже не смогу получить его содержимое, только сервис (контейнер) может получить к нему доступ.
Передача секретов контейнерам
Для примера я создам сервис с образа postgresql и передам ему секрет psql_user и psql_pwd.
docker service create \
--name db-key \
--secret psql_user \
--secret psql_pwd \
-e POSTGRES_DB=app \
-e POSTGRES_PASSWORD_FILE=/run/secrets/psql_pwd \
-e POSTGRES_USER_FILE=/run/secrets/psql_user \
postgres:16
Проверю что контейнер сервиса запущен и работает:
docker service ps db-key
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
sxe1t1rbeew0 db-key.1 postgres:16 c-stream-9-vm4 Running Running 18 seconds ago
В конфиг файле сервиса это передаётся как:
version: "3.8"
services:
db:
image: postgres:16
environment:
POSTGRES_DB: app
POSTGRES_USER_FILE: /run/secrets/psql_user
POSTGRES_PASSWORD_FILE: /run/secrets/psql_pwd
secrets:
- psql_pwd
- psql_user
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
secrets:
psql_pwd:
external: true # secret уже создан командой `docker secret create`
psql_user:
external: true # secret уже создан командой `docker secret create`
networks:
backend:
driver: overlay
volumes:
db_data:
Обратите внимание если секреты уже созданы еще до создания самого сервиса необходимо указать параметр external: true, если же секреты еще не созданы, то передаём путь к файлу со значением.
secrets:
psql_pwd:
file : ./psql_pwd.txt
psql_user:
file : ./psql_user.txt
Проверка что секреты проброшены
Для проверки я переходу в псевдотерминал контейнера сервиса db и проверяю там файлы в директории /run/secrets.
docker exec -it db-key.1.sxe1t1rbeew0v3yml18zkgfzr bash
ls /run/secrets/
psql_pwd psql_user
cat /run/secrets/psql_pwd
secret
Теперь если я выполню команду docker container inspect в выводе я не увижу само имя пользователя или пароль в открытом виде.
docker container inspect db-key.1.sxe1t1rbeew0v3yml18zkgfzr
"Env": [
"POSTGRES_DB=app",
"POSTGRES_PASSWORD_FILE=/run/secrets/psql_pwd",
"POSTGRES_USER_FILE=/run/secrets/psql_user",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/16/bin",
"GOSU_VERSION=1.19",
"LANG=en_US.utf8",
"PG_MAJOR=16",
"PG_VERSION=16.11-1.pgdg13+1",
"PGDATA=/var/lib/postgresql/data"
],


Комментарии