Thank you for reading this post, don't forget to subscribe!
Начиная с версии 17.06 — у Docker Swarm появилась поддержка новой концепции хранения и подключения файлов настроек для сервисов — configs
.
А ещё ранее, с версии 1.13 — secrets
, для хранения и передачи зашифрованных данных между менеджерами и нодами.
Ниже — описание и применение secrets
и configs
в Docker Swarm.
Docker configs
Swarm service configs позволяет хранить некритичные данные, такие как файлы конфигурации, вне docker-образа или контейнера: вместо того, что бы подключать файл настроек через volume (-v
) или передавать переменные с параметрами — вы можете создать объект конфига и подключить его напрямую к файловой системе в создаваемом сервисе/контейнере.
Когда вы создаёте такой config
— Docker отправляет его на manager-ноду кластера по TLS, где он хранится в зашифрованных Raft логах (/var/lib/docker/swarm/raft
), которые реплицируются по всем менеджерам swarm-а.
Когда вы даёте доступ к конфигу для нового или уже запущенного сервиса в Swarm — он монтируется в файловую систему контейнера, по умолчанию для Linux это будет /<config_name>
.
Вы можете так же отозвать доступ к конфигу или добавить дополнительный в любой момент.
Создание configs
Создать конфиг очень просто, например — создадим файл настроек виртуалхоста для NGINX:
1 2 3 4 5 6 7 8 9 |
server { listen 80; root /usr/share/nginx/html/; index index.html index.htm index.nginx-debian.html; server_name dc-swarm.local; location / { try_files $uri $uri/ =404; } } |
Создаём объект Docker config
:
docker config create vhost_nginx nginx_vhost.conf
проверяем:
Теперь можно удалить исходный файл, и использовать созданный конфиг.
Применение configs
Обновляем сервис, подключаем конфиг:
src
и target
:Обновление configs
Обновляем настройки виртуалхоста — поменяем индексный файл:
1 2 3 4 5 6 7 8 9 |
server { listen 80; root /usr/share/nginx/html/; index dc_index.html; server_name dc-swarm.local; location / { try_files $uri $uri/ =404; } } |
Создаём конфиг с именем vhost_nginx_v2:
docker config create vhost_nginx_v2 nginx_vhost.conf
Отключаем конфиг от сервиса:
Docker secrets
secrets
— это данные, например пароль или SSH ключ, которые не должны храниться в открытом виде в Dockerfile
и не должны передаваться в таком виде по сети.
Главное отличие secrets
от configs
это то, что configs
подключаются к файловой системе контейнера, тогда как secrets
— монтируются в память (/run/
).
Когда вы явно указываете доступ к секрету для сервиса или контейнера — по умолчанию он будет помещён в /run/secrets/<secret_name>
.
Создание secrets
Создаём новый «секрет»:
echo "password" > pwd.txt
nginx
:/var/run/secrets
в контейнере:Аналогично с configs
— можно указать точку монтирования.
Отключаем секрет от контейнера:
/etc/pwd
:Docker secrets
vs configs
Как говорилось, основная разница в том, что configs
при подключении к контейнеру становится частью файловой системы, тогда как secret
— помещается в памяти.
Проверить это можно сделав новый образ запущенного контейнера.
Сейчас у нас есть сервис nginx
к которому подключен config
dc_index и vhost_nginx_v2, и secret
— pwd:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
docker service inspect nginx | jq '.[0].Spec.TaskTemplate.ContainerSpec.Secrets , .[0].Spec.TaskTemplate.ContainerSpec.Configs' [ { "File": { "Name": "/etc/pwd", "UID": "0", "GID": "0", "Mode": 292 }, "SecretID": "urgibv1kmkz3o3850n8msc0ej", "SecretName": "pwd" } ] [ { "File": { "Name": "/usr/share/nginx/html/dc_index.html", "UID": "0", "GID": "0", "Mode": 292 }, "ConfigID": "4ych3x1inktdkuqfz6q9hklby", "ConfigName": "dc_index" }, { "File": { "Name": "/etc/nginc/conf.d/dc-swarm.local.conf", "UID": "0", "GID": "0", "Mode": 292 }, "ConfigID": "h13yug0d1jfcmdznosttyvqbp", "ConfigName": "vhost_nginx_v2" }, { "File": { "Name": "/etc/nginx/conf.d/dc-swarm.local.conf", "UID": "0", "GID": "0", "Mode": 292 }, "ConfigID": "h13yug0d1jfcmdznosttyvqbp", "ConfigName": "vhost_nginx_v2" } ] |
[/codesyntax]
Создаём новый образ из этого запущенного контейнера:
docker commit $(docker ps | tail -n 1 | awk '{print $1}') nginx_copy
Проверяем образы:
configs
:secret
Docker secrets и configs в Compose
Что бы использовать secrets
и configs
в Compose файле — используем configs
и secrets
:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
version: "3.3" configs: vhost_nginx: file: ./nginx_vhost.conf dc_index: file: ./index_local.html secrets: pwd: file: ./pwd.txt services: nginx: image: nginx secrets: - pwd configs: - source: vhost_nginx target: /etc/nginc/conf.d/dc-swarm.local.conf - source: dc_index target: /usr/share/nginx/html/dc_index.html |
[/codesyntax]
Создаём стек:
[codesyntax lang="php" blockstate="expanded"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
docker service inspect nginx_nginx | jq '.[0].Spec.TaskTemplate.ContainerSpec.Secrets , .[0].Spec.TaskTemplate.ContainerSpec.Configs' [ { "File": { "Name": "pwd", "UID": "0", "GID": "0", "Mode": 292 }, "SecretID": "uxr0m6wib0otfqglnwwwis19s", "SecretName": "nginx_pwd" } ] [ { "File": { "Name": "/usr/share/nginx/html/dc_index.html", "UID": "0", "GID": "0", "Mode": 292 }, "ConfigID": "twcghzoyzxb7j3l4yg15inwil", "ConfigName": "nginx_dc_index" }, { "File": { "Name": "/etc/nginc/conf.d/dc-swarm.local.conf", "UID": "0", "GID": "0", "Mode": 292 }, "ConfigID": "pulxlolcovj6ew4qniruvy3r5", "ConfigName": "nginx_vhost_nginx" } ] |
[/codesyntax]