Управление Secrets в Docker Swarm

Прочтите эту короткую инструкцию и узнайте, как использовать Docker Secrets и встроенные возможности режима Docker Swarm, чтобы защитить контейнеризированный кластер от угроз.

Docker изменился, как только разработка, тестирование и запуск программного обеспечения были обновлены. Поэтому разработчикам ПО и компаниям нужно применять передовую практику. С другой стороны, технологии оркестровки, такие как Docker Swarm, K8S или Mesos, также меняются в зависимости от требований индустрии. Обеспечение безопасности, включая управление чувствительными данными в Docker Swarm, как раз таки и эволюционировало как реакция на изменения.

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

Операционная система Datacenter, Kubernetes и другие технологии оркестровки имеют собственные интегрированные решения для управления чувствительными данными. Из этой статьи вы узнаете, как управлять секретными данными в Docker.

Управление чувствительными данным в режиме Swarm

Из этого раздела вы узнаете, как создавать, подключать и ротировать важные данные в Docker Secrets.

Как работают «секреты» Docker

Начиная с версии 1.13, пользователи Docker могут использовать Docker «секреты» в кластере Swarm. Менеджеры в Docker Swarm выступают как авторитетная делегация для координации управления чувствительными данными.

Секретные данные — пароли, ключи, уязвимые данные или пользовательские данные, которые разработчик хочет скрыть (например, имя базы данных, имя пользователя администратора).

Docker-«секрет» доступен только в режиме Swarm, поэтому автономные контейнеры не могут использовать эту функцию. Режим Swarm позволяет централизованно управлять уязвимыми данными и сообщениями путем шифрования и безопасной передачи контейнерам, которым необходимо получить доступ к этим данным (принцип наименьших привилегий).

Когда пользователь добавляет новые чувствительные данные в кластер Swarm, они отправляются менеджеру с помощью TLS-соединения.

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

Чтобы менеджеры были в курсе всех изменений, все данные, поступающие от узла, сохраняются в хранилище Raft с 256-битным ключом.

Создание «секретов»

Чтобы посмотреть, как это работает, создадим новую Docker-машину:

docker-machine create --driver virtualbox secrets-testing
> Running pre-create checks...
> (secrets-testing) Default Boot2Docker ISO is out-of-date, downloading the latest release...
> (secrets-testing) Latest release for github.com/boot2docker/boot2docker is v17.05.0-ce
> (secrets-testing) Downloading /home/eon01/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.05.0-ce/boot2docker.iso...
> (secrets-testing) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
> Creating machine...
> (secrets-testing) Copying /home/eon01/.docker/machine/cache/boot2docker.iso to /home/eon01/.docker/machine/machines/secrets-testing/boot2docker.iso...
> (secrets-testing) Creating VirtualBox VM...
> (secrets-testing) Creating SSH key...
> (secrets-testing) Starting the VM...
> (secrets-testing) Check network to re-create if needed...
> (secrets-testing) Waiting for an IP...
> Waiting for machine to be running, this may take a few minutes...
> Detecting operating system of created instance...
> Waiting for SSH to be available...
> Detecting the provisioner...
> Provisioning with boot2docker...
> Copying certs to the local machine directory...
> Copying certs to the remote machine...
> Setting Docker configuration on the remote daemon...
> Checking connection to Docker...
> Docker is up and running!
> To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env secrets-testing

Вы увидите созданную машину, используя:

docker-machine ls
> NAME              ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
> secrets-testing   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.05.0-ce

Взглянем на машинные переменные:

docker-machine env secrets-testing
> export DOCKER_TLS_VERIFY="1"
> export DOCKER_HOST="tcp://192.168.99.100:2376"
> export DOCKER_CERT_PATH="/home/eon01/.docker/machine/machines/secrets-testing"
> export DOCKER_MACHINE_NAME="secrets-testing"

Если все в порядке, мы можем подключить текущий сеанс оболочки к новой машине:

eval "$(docker-machine env secrets-testing)"

Теперь мы можем запустить кластер Swarm для запуска наших тестов. Используя IP-адрес созданной машины, выполните инициализацию Swarm:

docker swarm init --advertise-addr 192.168.99.100

Вы увидите что-то похожее:

> Swarm initialized: current node (sqd5o5vj5c2r9gn53jd1uc4ig) is now a manager.
>
> To add a worker to this swarm, run the following command:
>
>     docker swarm join \
>     --token SWMTKN-1-0atbw3c3geeyievi62dkgrw03pauh93rhfz41mdveo21ei1fb6-abf6azeaezaea \
>     192.168.99.100:2377
>
> To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Наш менеджер создан. Вы можете создавать новые машины и добавлять новых менеджеров.

Давайте создадим случайные секретные данные и добавим их в Docker-«секрет». Секретные данные будут созданы с помощью команды date |md5sum|awk '{print $1}' и помещены в Docker-«секрет» с помощью команды: docker secret create [OPTIONS] SECRET file|-

Мы можем запустить команду, чтобы создать Decker-«секрет»:

date |md5sum|awk '{print $1}' | docker secret create my_secret -
> qk4k9adgri6b3ubjua9nca5fp

Созданный «секрет» назван my_secret.

При вводе docker secret ls вы получаете информацию об используемых«секретах» :

> ID                                               NAME                CREATED              UPDATED
> qk4k9adgri6b3ubjua9nca5fp   my_secret           About a minute ago   About a minute ago

Qk4k9adgri6b3ubjua9nca5fp – случайный и уникальный идентификатор недавно созданного «секрета».

Если вы хотите получить больше информации о my_secret, используйте:

docker secret inspect  my_secret

И вы увидите вывод JSON с информацией, такой как дата создания или дата обновления.

> [
>     {
>         "ID": "qk4k9adgri6b3ubjua9nca5fp",
>         "Version": {
>             "Index": 10
>         },
>         "CreatedAt": "2017-05-22T13:25:23.815462834Z",
>         "UpdatedAt": "2017-05-22T13:25:23.815462834Z",
>         "Spec": {
>             "Name": "my_secret",
>             "Labels": {}
>         }
>     }
> ]

Использование Docker-«секретов»

Создадим новый сервис, который будет использовать созданный «секрет» ( my_secret ).

docker service create --name my_test_app --secret my_secret eon01/infinite

Eon01 / infin — изображение Docker, созданное для тестов, которые используют Alpine для запуска бесконечного цикла.

Теперь у нас есть работающий сервис с именем my_test_app, использующий «секрет» my_secret. Его можно проверить с помощью docker service ls или docker ps.

docker ps
> CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS               NAMES
> db38ae5f19fa        eon01/infinite:latest   "/bin/sh -c 'tail ..."   10 minutes ago      Up 10 minutes                           my_test_app.1.cc71i2rm0cl6pghn7z5ht7b98

Только что созданный сервис использует пароль, и поскольку сервис работает с одним контейнером, только этот контейнер может видеть «секрет». Другими словами, если «секрет» привязан к сервису, то только этот сервис имеет доступ к чувствительным данным. «Секрет» сохраняется во временную файловую систему (tmpfs) под /run/secrets/my_secret.

Tmpfs — временное хранилище во многих Unix-подобных операционных системах. Файлы хранятся в энергозависимой памяти вместо внешнего устройства хранения данных.

db38ae5f19fa — идентификатор контейнера. Его содержимое можно проверить с помощью:

docker exec -it db38ae5f19fa cat /run/secrets/my_secret
> 21ac8406497dded57ceafb7767e53633

Создавая другие секреты для тех же сервисов, вы найдете в том же каталоге /run/secrets/<secret_name>

Обмен данными в Docker «секрет»

Чтобы узнать, как делятся данные между двумя приложениями, создадим новый сервис с именем и отправим его в созданный «секрет». В нашем случае my_other_test_app will использует тот же пароль, но с другим именем (my_other_secret):

docker service create --name my_other_test_app --secret source=my_secret,target=my_other_secret,mode=0400 eon01/infinite

Мы установили режим для обмена «секретом» (0400). Также можно добавить такие параметры как UID или GID. Внутри контейнера можно проверить содержимое созданного«секрета» :

docker exec -it 51fe104e416b cat /run/secrets/my_other_secret

Получим тот же результат, что и от предыдущей команды docker exec -it db38ae5f19fa cat /run/secrets/my_secret, которая является первым «секретом» 21ac8406497dded57ceafb7767e53633.

Ротация Docker-«секретов»

Ротация чувствительных данных, таких как пароли, — лучшее обеспечение безопасности. Это возможно сделать с помощью функции Docker Swarm Secrets.

Начнем с создания «секрета»:

date |md5sum|awk '{print $1}' | docker secret create my_new_secret -

После этого старый «секрет» должен быть удален и заменен. Все это делается одной командой:

docker service update — secret-rm my_secret — secret-add source=my_new_secret,target=my_secret my_test_app

Если вы захотите проверить, то обнаружите, что старый «секрет» (в моем случае 21ac8406497dded57ceafb7767e53633) теперь имеет другое значение:

docker exec -it 5152ba89ea7f cat /run/secrets/my_secret

Можно проверить новый «секрет» :

docker secret inspect my_new_secret
> [
>     {
>         "ID": "loame64czkbto3z87s37iy2ds",
>         "Version": {
>             "Index": 34
>         },
>         "CreatedAt": "2017-05-22T14:03:46.627206229Z",
>         "UpdatedAt": "2017-05-22T14:03:46.627206229Z",
>         "Spec": {
>             "Name": "my_new_secret",
>             "Labels": {}
>         }
>     }
> ]

Развертывание докеризированных приложений с помощью Semaphore

Для непрерывного развертывания вашего проекта в Docker Swarm используйте сервис развертывания и непрерывной интеграции Semaphore.

Собственная Docker-платформа Semaphore идет с полным предустановленным Docker CLI и имеет полное кэширование тегированных образов Docker. Ознакомьтесь с другими статьями, чтобы узнать о развертывании с помощью Semaphore.

Заключение

Мы провели обзор функции Swarm, которая была представлена в Docker 1.13 после осознания важности управления чувствительными данными.
Все предыдущие релизы Docker CLI и API поддерживали эту функцию, но только в режиме Swarm, где «секреты» хранились в журнале Raft связанного Swarm-кластера во временной файловой системе внутри контейнера.

Управление секретами с помощью Docker полезно: чувствительные данные неизменны, никогда не записывается на диск и никогда не отправляется в текстовом виде в сеть. Другие технологии оркестровки, такие как Kubernetes, имеют разные модели управления безопасностью и «секретами». Если безопасность важна для вас, то следует сравнить все модели и выбрать наиболее подходящую.