Всем доброго времени суток! В этой статье хотел бы кратко в режиме смузи осветить возможности Portainer API и применение в разворачивании проектов.
Рассмотрим несколько задач:
- Управление. Иметь возможность отображать работу всех контейнеров на определенном узле, управлять и отслеживать состояние, читать логи и контролировать ресурсы.
- Разворачивание. Минимизировать участие пользователя и создать благоприятные условия для автоматизированного разворачивания на новом месте.
- Интеграция с gitlab-ci. Упростить процесс разработки.
Управление
Обладая опытом работы с Docker, переход на docker-swarm привлек относительной простотой и скоростью освоения в сравнении с Kubernetes. Для одного менеджер узла (leader node) и нескольких worker-ов предстояло решить, как отобразить в одном окне статус запуска, количество работ, статистику использования памяти и health-чеки. В первую очередь необходимо готовое решение с графическим интерфейсом исходя из потребностей задачи.
Можно найти много статей по сравниванию между собой GUI-интерфейсов для управления Docker-ом. Приведу несколько примеров: тут и тут. Необходимые требования для решения задачи были найдены в Portainer.
Положительные моменты:
- простота разворачивания
- авторизация из коробки
- API
- возможность добавления собственного registry
- возможность подключения к консоли контейнера
- чтение логов
- отслеживание характеристик использованой памяти и сети контейнеров.
Portainer состоит из двух элементов: Portainer Server и Portainer Agent. Оба элемента работают как контейнеры Docker — достаточно задеплоить. Вообще работа Portainer основывается на размещении своих агентов на всех нодах, осуществляя общение через http-запросы. Из документации становится ясно, что Portainer Agent — это обходной путь для ограничений API Docker для управления его средой, так как из коробки взаимодействие с containers, networks, volumes, images ограничено текущим узлом, к которому нацелен запрос Docker API. Решение этому есть, например, открыть порт на каждом узле , а потом защитить сертификатами, наладить схему общения и т.д. Одним словом — не удобно, но вариант. Задача же агента — предоставить возможность общения кластерно-ориентированным ресурсам ранее определенного узла. Достаточно выполнить только один запрос API Docker, чтобы получить все эти ресурсы из каждого узла в кластере.
В целом, улучшается user-experience при управлении кластерами Swarm. Немного больше и со скриншотами можно посмотреть тут или тут.
Разворачивание
(Ссылку на скрипты и стеки оставлю внизу).
Можно привести пару примеров, чтобы убедиться в удобстве разворачивания. Рассмотрим задачу по загрузке и выгрузке стеков в Docker. Тут необходимо заметить, что возможно использовать стандартный метод Docker API командой:
docker stack deploy -c "имя файла стека"
В таком случаем стек загрузится, но в Portainer будет заблокированным для редактирования, что опять же не соответствует потребностям задачи. Тогда на выручку приходит Portainer API с возможностью загрузки стеков. Для удобства рекомендую установить пакеты httpie и jq на manager unix-машину либо использовать классический curl. Передаем скрипту логин и пароль для входа в Portainer и запускаем командой:
sh script.sh Username Password
Для начала получаем ключ авторизации:
key=$(http POST 127.0.0.1:9000/api/auth Username="$1" Password="$2" | jq -r '.jwt')
Получаем swarm_id (адрес, куда полетят стеки):
swarm_id=$(http GET 127.0.0.1:9000/api/endpoints/1/docker/swarm "Authorization: Bearer $key" | jq -c '.ID')
Дальше запускаем процесс загрузки, попутно получаем некоторую второстепенную информацию:
for file in stacks/*
do
dir=$(readlink -f "$file")
filename=$(basename "$file" .yml)
curl -X POST "http://127.0.0.1:9000/api/stacks?method=file&type=1&endpointId=1" -H "Content-Type: multipart/form-data" -H "Accept: application/json" -H "Authorization: Bearer $key" -F "Name=$filename" -F "SwarmID=$swarm_id" -F "file=@$dir"
После этого в Portainer отобразится доступный для редактирования стек. Справедлива и обратная ситуация, когда пользователь вносит изменения в стек через Portainer. Для того чтобы получить эти изменения, необходимо выгрузить и сохранить стек в yml-файле в директорию с другими стеками. Как это можно сделать:
Получаем ключ:
key=$(http POST 127.0.0.1:9000/api/auth Username="$2" Password="$3" | jq -r '.jwt')
Пробегаем по всем стекам и получаем имена и id, сохраняем:
for var in $(http GET 127.0.0.1:9000/api/stacks "Authorization: Bearer $key" | jq -c '.[]?')
do
name=$(echo $var | jq -r '.Name')
id=$(echo $var | jq -r '.Id')
http GET 127.0.0.1:9000/api/stacks/$id/file "Authorization: Bearer $key" | jq -r '.StackFileContent' > $name.yml
done
Каждый может найти свое применение инструменту Portainer API.
Тестирование
Для примера использовался gitlab-runner. Рассмотрим следующий вариант применения gitlab-ci: в скрипт service.sh закладываем выполнение вышеизложенных ситуаций и запускаем.
stages:
- staging
stage-short:
stage: staging
image: [SOME_STAGE]
only:
changes:
- [SOME_PROJECT]/*
refs:
- master
script:
- /scripts/service.sh $PORTAINER_ADMIN $PORTAINER_PASS
Думаю на этом все, прикрепляю ссылку на github.
gibson_dev
Тоже использовал апи для деплоя в docker swarm правда тулзу написал на ноде и в докер упаковал