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
.
Резюме
Конфигурация - это довольно удобная вещь, которая помогает отделить приложение от его конфигурации. Вы используете конфиг в своем приложении?