TL;DR

А как насчет использования конфигурации Docker вместо создания образа со встроенной конфигурацией?

Встраивание конфигурации в изображение?

Мы часто видим такие файлы Dockerfiles, как следующий, где новый образ создается только для добавления конфигурации к базовому образу.

$ cat Dockerfile
FROM nginx:1.13.6
COPY nginx.conf /etc/nginx/nginx.conf

В этом примере локальный файл конфигурации nginx.conf копируется в файловую систему образа NGINX, чтобы перезаписать файл конфигурации по умолчанию, поставляемый в /etc/nginx/nginx.conf.

Одним из основных недостатков этого подхода является необходимость перестроения образа при изменении конфигурации.

Конфигурация Docker входит в изображение

Configs доступны для сервисов с Docker 17.06. Если secrets существует для хранения конфиденциальной информации, config позволяет хранить неконфиденциальную информацию, такую ​​как файлы конфигурации, вне образа службы.

Что касается других примитивов Docker (контейнер, образ, том), config имеет собственный набор команд в интерфейсе командной строки.

$ docker config --help
Usage: docker config COMMAND
Manage Docker configs
Options:
Commands:
 create Create a configuration file from a file or STDIN as content
 inspect Display detailed information on one or more config files
 ls List configs
 rm Remove one or more configuration files
Run ‘docker config COMMAND — help’ for more information on a command.

Создать конфигурацию

Возвращаясь к предыдущему примеру, вместо копирования файла конфигурации NGINX в образ мы создадим конфигурацию Docker.

В этом примере файл nginx.conf содержит следующее содержимое.

Он в основном определяет веб-сервер, который прослушивает порт 8000 и пересылает все HTTP-запросы, поступающие на конечную точку /api, на вышестоящий сервер API.

Используя Docker CLI, мы можем создать config из этого файла конфигурации, мы назовем эту конфигурацию proxy.

$ docker config create proxy nginx.conf
mdcfnxud53ve6jgcgjkhflg0s

Затем мы можем проверить конфигурацию, как и с любыми другими примитивами Docker:

$ docker config inspect proxy
[
  {
    "ID": "x06uaozphg9kbnf8g4az4mucn",
    "Version": {
      "Index": 2723
    },
    "CreatedAt": "2017–11–21T07:49:09.553666064Z",
    "UpdatedAt": "2017–11–21T07:49:09.553666064Z",
    "Spec": {
      "Name": "proxy,
      "Labels": {},
      "Data": "dXNlciB3d3ctZGF0YTsKd29y...ogIgICAgIH0KICAgIH0KfQo="
    }
  }
]

Данные закодированы только в Base64 и могут быть легко декодированы.

По определению, данные в конфигурации не являются конфиденциальными и, следовательно, не зашифрованы.

Использовать конфигурацию

Теперь, когда мы создали конфигурацию proxy, посмотрим, как ее можно использовать в службах. Для этого мы рассмотрим два подхода - использование командной строки и использование стека Docker.

В обоих случаях мы определяем две службы:

  • API: простой HTTP-сервер, прослушивающий порт 80 и отправляющий назад предложение города для посещения каждый раз, когда он получает запрос Get.
  • прокси, использующий созданную выше конфигурацию и отправляющий весь трафик, нацеленный на конечную точку /api, в вышестоящую службу API.

Мы протестируем эту настройку, отправив HTTP-запрос Get на /api endpoint на порту 8000 прокси и убедившись, что мы получаем ответ от API.

Используя командную строку

Начнем с создания оверлейной сети. Мы будем использовать это, чтобы обе службы, API и прокси, могли взаимодействовать друг с другом.

$ docker network create --driver overlay front

Затем мы создаем службу api.

$ docker service create --name api --network front lucj/api

Последний шаг - создать службу proxy.

$ docker service create --name proxy \
  --name proxy \
  --network front \
  --config src=proxy,target=/etc/nginx/nginx.conf \
  --port 8000:8000 \
  nginx:1.13.6

Как только все будет готово, давайте отправим HTTP-запрос на localhost, порт 8000 (порт, опубликованный на хосте службой прокси).

$ curl localhost:8000/api
{“msg”:”c249837f1f58 suggests to visit Emosiba”}

Запрос попадает в прокси-службу, которая перенаправляет его в API. Другими словами, файл конфигурации NGINX, предоставленный как конфигурация Docker, был правильно учтен.

Использование файла Docker Compose

Конечно, более удобно использовать файл Compose для определения приложения и его развертывания как стека Docker. Затем мы создаем stack.yml файл со следующим содержимым.

Примечание: поскольку конфигурация создается до запуска приложения, в этом файле она определяется как external.

Затем приложение можно запустить с помощью следующей команды:

$ docker stack deploy -c stack.yml test
Creating service test_proxy
Creating service test_api

Давайте отправим HTTP-запрос на /api конечную точку прокси-службы.

$ curl localhost:8000/api
{“msg”:”f462d568c0b0 suggests to visit Onitufdu”}

Как и раньше, запрос перенаправляется в службу API.

Обновление службы

Когда содержимое конфигурации необходимо изменить, это общий шаблон для создания новой конфигурации (с использованием docker config create), а затем для обновления порядка обслуживания, чтобы удалить доступ к предыдущей конфигурации и добавить доступ к новой. . Сервисные команды :--config-rm и -- config-add.

Давайте создадим новую конфигурацию из файла nginx-v2.conf.

$ docker config create proxy-v2 nginx-v2.conf
xtd1s1g6b5zukjhvup5vi4jzd

Затем мы можем обновить службу с помощью следующей команды. При этом мы удаляем конфигурацию с именем proxy и добавляем конфигурацию с именем proxy-v2 .

$ docker service update --config-rm proxy --config-add src=proxy-v2,target=/etc/nginx/nginx.conf proxy

Примечание: по умолчанию, когда к службе прикреплен конфиг, он доступен в файле / config_name. Затем нам нужно явно определить местоположение, используя параметр target.

Резюме

Конфигурация - это довольно удобная вещь, которая помогает отделить приложение от его конфигурации. Вы используете конфиг в своем приложении?