Опубликовано 28 мая 2019Обновлено 1 окт 2025 17:13

Docker secrets – безопасное хранилище для чувствительных данных

docker
docker
контейнеры
контейнеры
виртуализация
виртуализация
News Title Block Picture
Содержание
Содержание
Поделиться

В данной статье будет рассмотрена работа чувствительными данными в Docker кластере такими как ключи, пароли и т.д.

Безопасное приложение невозможно создать, не имея безопасного способа для взаимодействия ваших контейнеров как друг с другом, так и с другими приложениями и системами. А для этого, в свою очередь, нужен безопасный способ управления учетными записями, токенами, паролями, ключами и другими чувствительными данными (которые в приложении обычно называются просто «секретами»). Начиная с версии 1.13, Docker поддерживает безопасный способ работы с такими чувствительными данными — Docker secrets. Он реализуется в кластере Docker, работающем в режиме Swarm mode.

Предполагается, что у вас уже есть Docker кластер, работающий в Swarm mode. А если еще нет, вы легко можете установить его, воспользовавшись инструкциями из статьи «Установка отказоустойчивого Docker Swarm кластера в K2 Cloud», или же вы можете обновить свой Docker Engine до версии 1.13 и переведя его в этот режим работы, чтобы посмотреть на работу технологии и не устанавливать отдельный кластер:

$ docker swarm init

План

Мы запустим в контейнере простое Flask приложение (похожее на то, что описывалось в статье «Упаковка простого Flask приложения в Docker контейнер»), которое будет считывать переданный ему пароль и выводить его в ответ на http запросы. Если же «секрета» с паролем не будет, приложение будет выдаваться сообщение об ошибке. 

Создание приложения

Прежде чем переходить к описанию работы с «секретами», давайте создадим демонстрационное приложение. Для этого создайте директорию docker_secrets_example:

$ mkdir docker_secrets_example
$ cd docker_secrets_example

Создайте в нем файл requirements.txt, содержащий следующую информацию:

click==6.7
Flask==0.12
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==0.23
Werkzeug==0.11.15
wheel==0.24.0

Создайте и активируйте виртуальное окружение, а затем установите зависимости

$ virtualenv venv
$ source venv/bin/activate
$ pip install -r requirements.txt

Создайте файл app.py, который будет содержать код нашего приложения

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route('/')
def index():
  try:
    db_password = None
    f = open('/run/secrets/db-password', 'r')
    db_password = f.readline()
  except IOError:
    pass
  finally:
    return render_template('index.html', password=db_password)

if __name__ == '__main__':
  app.run(debug=True,host='0.0.0.0')

А также необходимо создать директорию templates и поместить внутрь файл index.html со следующим содержимым:

Docker secrets demo
{% if password %}
Your secret password: 
{% else %} No password specified! {% endif %}

Внутри рабочей директории создайте файл Dockerfile со следующим содержимым, чтобы иметь возможность собирать ваш Docker образ:

FROM python:2.7
MAINTAINER Andrey Maksimov 'maksimov.andrei@gmail.com'
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]

Структура вашего приложения на текущий момент без учета виртуального окружения (venv) будет следующей:

$ tree -I venv docker_secrets_example
docker_secrets_example
├── Dockerfile
├── app.py
├── requirements.txt
└── templates
    └── index.html

1 directory, 4 files

Проверка работоспособности приложения

Если на текущий момент вы все сделали правильно, вы можете запустить демонстрационное приложение и проверить его работоспособность, открыв в браузере адрес :

$ python app.py
 * Running on  (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 237-318-490
127.0.0.1 - - [13/Feb/2017 19:02:46] 'GET / HTTP/1.1' 200 -
127.0.0.1 - - [13/Feb/2017 19:02:47] 'GET /favicon.ico HTTP/1.1' 404 -

При этом в браузере будет отображаться:

Сборка образа

После того, как приложение заработало, его необходимо упаковать в контейнер. Для этого необходимо выполнить команду:

$ docker build -t amaksimov/docker_secrets_example:v0.1 .

Для корректной работы сервисов в Docker Swarm кластере, опубликуйте ваш собранный образ в вашем репозитории:

$ docker push amaksimov/docker_secrets_example:v0.1

Важно: если этого не сделать, в процессе запуска сервиса команда docker service createбудет выдавать сложно интерпретируемую ошибку.

Работа с “секретами” (Docker secrets)

После того, как демонстрационный образ создан, можно переходить непосредственно к работе с «секретами».

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

Docker Swarm кластер использует Raft Consensus Algorithm для того, чтобы гарантировать, что узлы, участвующие в управлении кластером, договариваются о состоянии кластера. Часть этого процесса включает в себя репликацию состояния всех управляющих узлов кластера при помощи журнала.

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

В процессе запуска нового сервиса в кластере, если в процессе создания ему предоставлена возможность доступа к тому или иному «секрету», происходит монтирование текстового содержимого «секретов» в директорию /run/secrets всем задачам (контейнерам) этого сервиса.

Команда docker secret позволяет нам задать «секреты», которые могут быть использованы сервисами, запущенными в Docker Swarm кластере. Есть два способа создания «секрета». 

Создание “секрета” из файла

Создайте в рабочей директории файл password.txt который будет содержать секретную информацию, например, пароль к базе данных this-is-my-super-secret-password. Чтобы дать возможность вашим приложениям использовать этот секретный пароль, выполните коману:

	 $ docker secret create db-password password.txt

Эта команда создаст «секрет» с именем db-password, используя содержимое файла password.txt

Создание “секрета” со стандартных потоков вводавывода

Также вы можете создавать «секреты», используя информацию со стандартного потока вводавывода:

	 $ LC_ALL=C < /dev/urandom tr -dc '_A-Z-a-z-0-9' | head -c 32 | docker secret create db-password -

Эта команда также создаст «секрет» db-password, но уже используя сгенерированную информацию из /dev/urandom.

Просмотр “секретов” кластера

Все созданные в кластере секреты могут быть просмотрены при помощи команды:

$ docker secret ls
ID                          NAME                CREATED             UPDATED
iokqhuhj7ix9a57joiarivv8n   db-password         3 hours ago         3 hours ago

Удаление “секретов” из кластера

Удаление «секретов» также осуществляется достаточно просто:

	 $ docker secret rm db-password

Управление сервисом с “секретом”. Запуск

Для того, чтобы запустить ваш сервис и передать ему информацию о «секрете», необходимо выполнить команду:

	 $ docker service create --name docker_secrets_example -p 5000:5000 --secret db-password amaksimov/docker_secrets_example:v0.1

После чего можно будет убедиться в том, что ваше приложение прочитало файл с секретом:

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

	 $ docker service create --name docker_secrets_example -p 5000:5000 amaksimov/docker_secrets_example:v0.1

То, как и ожидается, ваше приложение об этом сразу же сообщит:

Добавление “секрета” к уже работающему сервису

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

	 $ docker service rm docker_secrets_example

Обновление “секретов” для сервиса

Также к сожалению, для того, чтобы обновить секрет у сервиса, его придется пересоздать.

В этой статье мы рассмотрели еще одну возможность Docker, предназначенную для безопасной работы с чувствительными данными ваших приложений. Если у вас возникли какие-либо вопросы, буду рад ответить на них в комментариях в конце статьи.

Узнай, кто стоит за технологиями в K2 Cloud — и стань одним из них

Переходи на карьерную страницу, знакомься с нашими подходами и найди команду, подходящую именно тебе.

Другие новости

Продолжая использовать сайт k2.cloud, Вы соглашаетесь на обработку персональных данных, собираемых с использованием файлов cookie, а также посредством метрических программ «Яндекс Метрика», «ВК Реклама». Более подробная информация – в политике обработки и использования cookie-файлов.