В этом посте вы узнаете, как предоставить Docker engines API для удаленного выполнения команд docker через REST API
Что такое Docker remote API?
Основное использование Docker remote API заключается в удаленном подключении к движку Docker engine. Допустим, вы запускаете docker host на удаленном сервере и хотите подключиться к нему со своего ноутбука. Для этого сценария вы можете использовать удаленный API и подключаться к нему с помощью REST API, поскольку движок docker принимает запросы REST.
Еще один вариант использования: допустим, у вас есть приложение, и вы хотите получить подробную информацию о контейнерах в docker host. Для этого вы можете использовать функцию удаленного API.
Включить Docker Remote API
Все конфигурации docker присутствуют в файле/lib/systemd/system/docker.service
. В этом файле есть параметр ExecStart.
Откройте файл/lib/systemd/system/docker.service
, найдите ExecStart и добавьте значение, как показано ниже.
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
Приведенная выше команда привяжет сервер docker Engine к сокету Unix, а также к TCP-порту 4243. “0.0.0.0” означает, что docker Engine принимает подключения со всех IP-адресов.
Примечание: Также, пожалуйста, добавьте необходимые правила брандмауэра, чтобы ваш сервер принимал подключение по порту 4243
Теперь, чтобы произошли все изменения, вам необходимо перезапустить демон и службу Docker. Для этого выполните следующие команды.
sudo systemctl daemon-reload
sudo service docker restart
Теперь удаленный API включен на вашем хостинге docker. Чтобы проверить это, есть несколько способов.
Как мне получить доступ к Docker API?
Вы можете использовать утилиту командной строки curl или REST API для доступа к Docker API. Ниже описаны оба способа.
Тест с использованием curl
Получите IP-адрес вашего хоста Docker, на котором вы включили удаленный API, и выполните следующую команду с любого терминала, поддерживающего curl. Вы также можете протестировать с помощью localhost.
Примечание: замените IP-адрес на IP вашего хоста Docker или localhost, как показано ниже.
curl http://localhost:4243/version curl http://35.225.233.5:4243/version
Приведенная выше команда выведет все изображения на вашем хосте docker в формате JSON.
Тест с использованием REST-клиента
Вы можете протестировать API с помощью REST-клиента, такого как Postman. Если вы используете следующий URL в своем REST-клиенте, вы получите вывод JSON в улучшенном виде, как показано на рисунке ниже.
http://192.168.5.5:4243/images/json
В этом руководстве вы узнали, как включить Docker remote API. Для повышения безопасности вы можете использовать сертификаты с запросами REST. Об этом мы расскажем в другом подробном посте, если у вас возникнут какие-либо проблемы с этой настройкой, сообщите нам в разделе комментариев.
Помимо настроек в файле docker.service, доступ к порту можно закрыть с помощью настроек iptables, кроме того для максимальной безопасности, защитить Docker API можно с помощью SSL/TLS.
Подписывайтесь на наш телеграмм канал, вопросы можно задать в комментариях или в группе.
Docker Engine API
Теперь, когда мы настроили удаленный доступ, давайте поработаем с API.
Мы рассмотрим лишь несколько основных функций, но вы всегда можете проверить полную документацию, чтобы узнать больше.
Получение статуса контейнера по API:
(alpine) $ curl -s http://172.17.0.1:2375/containers/"$(hostname)"/json | jq '.'
В результате получим JSON:
{
"Id": "45f13902b710f7a5f324a7d4ec7f9b934057da4887650dc8fb4391c1d98f051c",
"Created": "2020-07-29T18:10:07.261589135Z",
"Path": "/bin/sh",
"Args": [],
"State": {
"Status": "running",
...
Здесь мы используем URL-адрес /containers/{идентификатор-контейнера}/json для получения подробной информации о нашем контейнере.
В этом случае мы запускаем команду hostname, чтобы получить идентификатор контейнера.
Просмотр журнала событий Docker daemon
Далее давайте послушаем события в демоне Docker:
(alpine) $ curl -s http://172.17.0.1:2375/events | jq '.'
Теперь в другом терминале давайте запустим контейнер hello-world :
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Вернувшись в наш контейнер alpine, мы получаем множество событий:
{
"status": "create",
"id": "abf881cbecfc0b022a3c1a6908559bb27406d0338a917fc91a77200d52a2553c",
"from": "hello-world",
"Type": "container",
"Action": "create",
...
}
{
"status": "attach",
"id": "abf881cbecfc0b022a3c1a6908559bb27406d0338a917fc91a77200d52a2553c",
"from": "hello-world",
"Type": "container",
"Action": "attach",
...
До сих пор мы делали что-то ненавязчивое. Пора немного встряхнуться.
Создание контейнера
Давайте создадим и запустим контейнер. Сначала мы определим его манифест:
(alpine) $ cat > create.json << EOF
{
"Image": "hello-world",
"Cmd": ["/hello"]
}
EOF
Теперь давайте вызовем конечную точку /containers/create, используя манифест:
(alpine) $ curl -X POST -H "Content-Type: application/json" -d @create.json http://172.17.0.1:2375/containers/create
{"Id":"f96a6360ad8e36271cc75a3cff05348761569cf2f089bbb30d826bd1e2d52f59","Warnings":[]}
Запуск контейнера
Затем мы используем идентификатор для запуска контейнера:
(alpine) $ curl -X POST http://172.17.0.1:2375/containers/f96a6360ad8e36271cc75a3cff05348761569cf2f089bbb30d826bd1e2d52f59/start
Просмотр журнала событий контейнера
Наконец, мы можем изучить журналы:
(alpine) $ curl http://172.17.0.1:2375/containers/f96a6360ad8e36271cc75a3cff05348761569cf2f089bbb30d826bd1e2d52f59/logs?stdout=true --output -
Hello from Docker!
KThis message shows that your installation appears to be working correctly.
;To generate this message, Docker took the following steps:
3 1. The Docker client contacted the Docker daemon.
...
Обратите внимание, что в начале каждой строки мы видим странные символы. Это происходит потому, что поток, по которому передаются логи, мультиплексируется, чтобы различать стандартный поток ошибок и стандартный поток вывода.
В результате выходные данные нуждаются в дальнейшей обработке.
Этого можно избежать, просто включив опцию TTY при создании контейнера:
(alpine) $ cat create.json
{
"Tty":true,
"Image": "hello-world",
"Cmd": ["/hello"]
}