В этом посте вы узнаете, как предоставить 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 и добавьте значение, как показано ниже.
1 |
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. Для этого выполните следующие команды.
1 2 |
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, как показано ниже.
1 2 |
curl http://localhost:4243/version curl http://35.225.233.5:4243/version |
Приведенная выше команда выведет все изображения на вашем хосте docker в формате JSON.
Тест с использованием REST-клиента
Вы можете протестировать API с помощью REST-клиента, такого как Postman. Если вы используете следующий URL в своем REST-клиенте, вы получите вывод JSON в улучшенном виде, как показано на рисунке ниже.
1 |
http://192.168.5.5:4243/images/json |
В этом руководстве вы узнали, как включить Docker remote API. Для повышения безопасности вы можете использовать сертификаты с запросами REST. Об этом мы расскажем в другом подробном посте, если у вас возникнут какие-либо проблемы с этой настройкой, сообщите нам в разделе комментариев.
Помимо настроек в файле docker.service, доступ к порту можно закрыть с помощью настроек iptables, кроме того для максимальной безопасности, защитить Docker API можно с помощью SSL/TLS.
Подписывайтесь на наш телеграмм канал, вопросы можно задать в комментариях или в группе.
Docker Engine API
Теперь, когда мы настроили удаленный доступ, давайте поработаем с API.
Мы рассмотрим лишь несколько основных функций, но вы всегда можете проверить полную документацию, чтобы узнать больше.
Получение статуса контейнера по API:
1 |
(alpine) $ curl -s http://172.17.0.1:2375/containers/"$(hostname)"/json | jq '.' |
В результате получим JSON:
1 2 3 4 5 6 7 8 |
{ "Id": "45f13902b710f7a5f324a7d4ec7f9b934057da4887650dc8fb4391c1d98f051c", "Created": "2020-07-29T18:10:07.261589135Z", "Path": "/bin/sh", "Args": [], "State": { "Status": "running", ... |
Здесь мы используем URL-адрес /containers/{идентификатор-контейнера}/json для получения подробной информации о нашем контейнере.
В этом случае мы запускаем команду hostname, чтобы получить идентификатор контейнера.
Просмотр журнала событий Docker daemon
Далее давайте послушаем события в демоне Docker:
1 |
(alpine) $ curl -s http://172.17.0.1:2375/events | jq '.' |
Теперь в другом терминале давайте запустим контейнер hello-world :
1 2 3 4 5 |
$ docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. ... |
Вернувшись в наш контейнер alpine, мы получаем множество событий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "status": "create", "id": "abf881cbecfc0b022a3c1a6908559bb27406d0338a917fc91a77200d52a2553c", "from": "hello-world", "Type": "container", "Action": "create", ... } { "status": "attach", "id": "abf881cbecfc0b022a3c1a6908559bb27406d0338a917fc91a77200d52a2553c", "from": "hello-world", "Type": "container", "Action": "attach", ... |
До сих пор мы делали что-то ненавязчивое. Пора немного встряхнуться.
Создание контейнера
Давайте создадим и запустим контейнер. Сначала мы определим его манифест:
1 2 3 4 5 6 |
(alpine) $ cat > create.json << EOF { "Image": "hello-world", "Cmd": ["/hello"] } EOF |
Теперь давайте вызовем конечную точку /containers/create, используя манифест:
1 2 3 |
(alpine) $ curl -X POST -H "Content-Type: application/json" -d @create.json http://172.17.0.1:2375/containers/create {"Id":"f96a6360ad8e36271cc75a3cff05348761569cf2f089bbb30d826bd1e2d52f59","Warnings":[]} |
Запуск контейнера
Затем мы используем идентификатор для запуска контейнера:
1 |
(alpine) $ curl -X POST http://172.17.0.1:2375/containers/f96a6360ad8e36271cc75a3cff05348761569cf2f089bbb30d826bd1e2d52f59/start |
Просмотр журнала событий контейнера
Наконец, мы можем изучить журналы:
1 2 3 4 5 6 7 8 |
(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 при создании контейнера:
1 |
(alpine) $ cat create.json |
1 2 3 4 5 |
{ "Tty":true, "Image": "hello-world", "Cmd": ["/hello"] } |