Docker Engine REST API: включение, безопасность и практическое использование

Быстрые ссылки
- Включение Docker Engine API
- Важная заметка по безопасности
- Использование API: примеры curl
- Часто используемые эндпоинты
- Практические чеклисты, тесты и сценарии инцидентов
- Заключение
Введение
Docker Engine открывает полноценный REST API, позволяющий управлять контейнерной платформой вне CLI. Все команды, которые выполняет docker CLI, по сути отправляют те же запросы к демону. API удобно использовать для автоматизации, интеграции с системами мониторинга и удалённого управления хостами.
Опишем принципы подключения, часто используемые эндпоинты, варианты защиты и практические методики — когда и как безопасно открывать доступ и что делать при инциденте.
Кратко: «демон» — это процесс dockerd, обрабатывающий запросы к Docker Engine; «сокет» — канал (unix или tcp) для связи с демоном.
Включение Docker Engine API
Любой работающий Docker-хост уже поддерживает API через Unix-сокет по пути /var/run/docker.sock. Если нужно принимать HTTP-запросы по сети, нужно привязать демон к TCP-порту.
Запуск демона с прослушиванием и Unix-сокетом одновременно:
sudo dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375Этот пример открывает порт 2375 на всех интерфейсах (0.0.0.0). Порт 2375 — общепринятый для Docker без TLS; при включённом TLS обычно используют 2376.
Чтобы постоянно применять настройки, создайте/отредактируйте системный фрагмент systemd:
sudo mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/options.conf <<'EOF'
[Service]
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
EOF
sudo systemctl daemon-reload
sudo systemctl restart dockerПосле этого API доступен по адресу http://127.0.0.1:2375/v1.41 (в примерах используется v1.41 — обратите внимание на версию API).
Важно: открывать TCP-порт без защиты крайне не рекомендуется. Читайте следующий раздел.
Важная заметка по безопасности
Открытый TCP-порт Docker API без аутентификации даёт полный контроль над демоном. Это означает запуск контейнеров от имени демона, удаление образов, доступ к файловой системе хоста (через bind-mount) и т. д. Возможности злоумышленника эквивалентны правам root в большинстве конфигураций.
Рекомендации по защите:
- Не открывайте порт на 0.0.0.0 без крайней необходимости. Ограничьте доступ списком разрешённых IP.
- Настройте TLS (mTLS) для демона: включите проверку клиентских сертификатов, используйте собственный CA.
- Включите брандмауэр (ufw/iptables/firewalld) и разрешайте доступ только с доверенных адресов.
- По возможности используйте Unix-сокет вместе с инструментами, которые поддерживают его (curl, SDK).
- Рассмотрите rootless Docker, Namespaces и SELinux/AppArmor для дополнительной изоляции.
Пример настройки брандмауэра для локальной сети (ufw):
sudo ufw allow from 192.168.1.0/24 to any port 2376 proto tcpНастройка TLS для демона (общее описание)
- Сгенерируйте CA, серверный ключ/сертификат и клиентские ключ/сертификаты.
- Запустите dockerd с опциями TLS:
sudo dockerd --tlsverify --tlscacert=/path/ca.pem --tlscert=/path/server-cert.pem --tlskey=/path/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock- Для
curlиспользуйте параметры:
curl https://127.0.0.1:2376/v1.41/containers/json --cacert ca.pem --cert client-cert.pem --key client-key.pemTLS и mTLS обеспечивают проверку подлинности и конфиденциальность. Однако сами по себе они не решают вопрос с правами контейнеров — даже авторизованный клиент может исполнить вредоносные команды, поэтому сочетайте TLS с ограничениями сети и аудитом.
Когда вместо TCP лучше использовать Unix-сокет
Если ваш клиент выполняется на том же хосте, где работает Docker, используйте Unix-сокет — нет риска сетевого доступа. Пример с curl:
curl --unix-socket /var/run/docker.sock http://localhost/v1.41/containers/jsonUnix-сокет обычно проще и безопаснее при локальных интеграциях.
Использование API: основы
Все эндпоинты начинаются с версии API. Пример базового адреса:
http://127.0.0.1:2375/v1.41Эндпоинты сгруппированы по объектам: /containers, /images, /volumes и т.д. Взаимодействие идёт через JSON: запросы и ответы используют JSON-формат.
Замечание: v1.41 упомянута как пример; убедитесь, что используемая версия поддерживается вашей установкой Docker. Вы можете посмотреть версию по /version.
curl http://127.0.0.1:2375/v1.41/versionПравильная передача фильтров в URL
Фильтры в query-параметре filters должны быть JSON-строкой. В shell важно экранировать кавычки или URL-кодировать значение.
Пример (используя одинарные кавычки для оболочки):
curl "http://127.0.0.1:2375/v1.41/containers/json?filters={\"name\":[\"demo\"]}"Или удобный вариант с URL-кодированием:
filters=%7B%22name%22%3A%5B%22demo%22%5D%7D
curl "http://127.0.0.1:2375/v1.41/containers/json?filters=$filters"Ошибки с ковычками — частая причина неверных ответов.
Часто используемые эндпоинты с примерами
Ниже — наиболее типичные операции с примерами curl и описаниями.
Список контейнеров
По умолчанию возвращаются запущенные контейнеры:
curl http://127.0.0.1:2375/v1.41/containers/json
Чтобы получить все контейнеры, добавьте all=true:
curl "http://127.0.0.1:2375/v1.41/containers/json?all=true"Параметр limit=10 вернёт 10 самых свежих по созданию. Для фильтрации по статусу или имени используйте filters.
Примеры фильтров:
- По имени:
filters={"name":["demo"]} - По статусу:
filters={"status":["running","paused"]} - По здоровью:
filters={"health":["healthy"]}
Создание и запуск контейнера
Сначала создаём контейнер командой POST /containers/create, затем запускаем /containers/:id/start.
Пример создания (минимальный):
curl http://127.0.0.1:2375/v1.41/containers/create \
-X POST \
-H "Content-Type: application/json" \
-d '{"Image": "example-image:latest"}'Ответ содержит Id контейнера. Запуск:
curl http://127.0.0.1:2375/v1.41/containers/abc123/start -X POSTСоздание контейнера через API позволяет программно формировать конфигурацию, объемы, сетевые настройки и переменные окружения.
Очистка контейнеров
Удаление остановленных контейнеров:
curl http://127.0.0.1:2375/v1.41/containers/prune -X POSTОтвет содержит ContainersDeleted (массив идентификаторов) и SpaceReclaimed (освобожденные байты).
Параметры: until (например, until=10m или until=2022-03-01) и label (например, label=demo=example).
Список образов
curl http://127.0.0.1:2375/v1.41/images/jsonФильтры те же, что и для контейнеров. Параметр filters={"reference":"hello-world:latest"} отберёт образ по тегу.

Сборка образов
Стенограмма сборки отправляется как tar-архив контекста на /build.
cat context.tar | curl "http://127.0.0.1:2375/v1.41/build?t=example-image:latest" -X POST --data-binary @-Параметры: dockerfile=path/to/Dockerfile, rm=true, pull=true. Важно — клиент должен сохранять соединение до конца сборки, иначе сборка прервётся.
События демона
Поток событий доступен через /events и может фильтроваться:
curl http://127.0.0.1:2375/v1.41/eventsФильтрация по типу событий (например, контейнеры):
curl "http://127.0.0.1:2375/v1.41/events?filters=%7B%22type%22%3A%5B%22container%22%5D%7D"Можно ограничить временнóй диапазон since и until.

Информация о системе
Эндпоинт /info возвращает состояние Docker и хоста:
curl http://127.0.0.1:2375/v1.41/infoВозвращаемые данные: количество контейнеров по состоянию, путь установки Docker, данные о железе/ОС и сведения о Swarm (если используется).
Практические рекомендации и трюки
- Всегда проверьте версию API (
/version) перед массовыми изменениями. - Для сложных фильтров полезно сначала экспериментировать в jq для форматирования:
curl http://127.0.0.1:2375/v1.41/containers/json | jq '.[] | {Id: .Id, Names: .Names, State: .State}'- При регулярной интеграции используйте официальные SDK (Go, Python, Java и т. д.), они упрощают работу с сериализацией и ошибками.
- Для CI/CD запускайте долгие операции (build/push) в изолированном окружении и отслеживайте таймауты соединений.
Роли и чеклисты
Ниже — краткие контрольные списки для трёх типичных ролей.
Разработчик
- Использовать Unix-сокет для локальной разработки.
- Экспортировать минимально необходимые переменные окружения в контейнер.
- Тестировать фильтры и формат JSON через jq.
SRE / Оператор
- Настроить TLS и ограничить доступ брандмауэром.
- Проводить аудит доступа к портам / выдачу сертификатов.
- Настроить метрики и логирование запросов к API (audit).
Инженер по безопасности
- Проверить использование rootless-режима и профилей AppArmor/SELinux.
- Регулярно перевыпускать клиентские сертификаты и отзывной список (CRL).
- Провести тесты на проникновение и ревью конфигурации dockerd.
Мини-методология: как безопасно подключить удалённый сервис к Docker API
- Оцените необходимость: может ли сервис работать через Unix-сокет (локально) или нужен удалённый доступ.
- Если нужен TCP, определите список доверенных хостов/подсетей.
- Настройте TLS/mTLS и используйте собственный CA.
- Ограничьте доступ брандмауэром и настройте лимиты по попыткам подключения (rate limiting) в сетевом периметре.
- Настройте аудит и мониторинг: логируйте вызовы важных эндпоинтов.
- Проводите периодический ревью сертификатов и доступов.
Сценарий инцидента: что делать при подозрительной активности API
- Немедленно заблокировать сетевой доступ (например, остановить интерфейс или отключить порт в FW).
- Остановить dockerd локально:
sudo systemctl stop docker. - Снимите образовавшиеся контейнеры/процессы в отдельной изолированной среде для анализа.
- Перевыпустите серверные и клиентские сертификаты (если используется TLS).
- Проведите форензик логов и аудита (journalctl, Docker daemon logs).
- Восстановите систему из проверенной резервной копии, если есть признаки компрометации.
Критерии приёмки API-интеграции
- Подключение с заданным методом (Unix/TCP+TLS) проходит успешно.
- Запросы к
/version,/infoи/containers/jsonвозвращают корректный JSON и HTTP 200. - Наличие мониторинга количества ошибок 4xx/5xx и роста времени ответа.
- Доступ дозволён только с доверенных IP (проверено firewall).
- Журналы аудита фиксируют вызовы критичных эндпоинтов.
Тест-кейсы и приёмочные критерии
- Тест подключений: curl к
/version— получить 200 и валидный JSON. - Создание контейнера: POST
/containers/create+ start — контейнер должен появиться в/containers/json. - Очистка контейнеров: POST
/containers/prune— проверитьContainersDeletedиSpaceReclaimed. - Сборка образа: отправить context.tar на
/buildи убедиться, что образ появился в/images/json. - TLS-авторизация: подключиться клиентским сертификатом и получить ответ; без сертификата — доступ запрещён.
Риск-матрица и смягчения
- Открытый TCP без TLS — риск: полный контроль над демоном. Смягчение: не открывать 0.0.0.0, применять ACL и TLS.
- Неправильная конфигурация сертификатов — риск: отказ в обслуживании или ложное чувство защиты. Смягчение: автоматические тесты на подключение и ротация сертификатов.
- Длительные сборки через сеть — риск: разрыв соединения приведёт к отмене сборки. Смягчение: выполнять сборки в надёжной сети/CI и предусматривать retry-механику.
Совместимость и миграция версий
API версионируется: адреса содержат префикс версии (/v1.41). При обновлении Docker версия API на хосте может отличаться — проверяйте /version и используйте минимальную поддерживаемую версию в приложениях. SDK обычно абстрагируют версионирование, но проверка на стороне CI необходима.
Лайфхаки и сниппеты (cheat sheet)
Unix-сокет (локально):
curl --unix-socket /var/run/docker.sock http://localhost/v1.41/containers/jsonСоздать + запустить контейнер:
# create
curl http://127.0.0.1:2375/v1.41/containers/create -X POST -H "Content-Type: application/json" -d '{"Image":"busybox","Cmd":["echo","hello"]}'
# start
curl http://127.0.0.1:2375/v1.41/containers//start -X POST Build из tar:
cat context.tar | curl "http://127.0.0.1:2375/v1.41/build?t=myimage:latest" -X POST --data-binary @-Prune:
curl http://127.0.0.1:2375/v1.41/containers/prune -X POSTTLS curl:
curl https://docker.example.com:2376/v1.41/containers/json --cacert ca.pem --cert client-cert.pem --key client-key.pemФакто-бокс
- По умолчанию Unix-сокет: /var/run/docker.sock
- Порт без TLS: 2375 (обычно только для локальной отладки)
- Порт с TLS: 2376 (общепринято использовать для защищённого доступа)
- Пример версии API в статье: v1.41
1‑строчный глоссарий
- Демон: dockerd — серверная часть Docker, выполняющая операции.
- Unix-сокет: локальный IPC-файл /var/run/docker.sock.
- TLS: протокол защиты соединения; mTLS — взаимная авторизация сертификатами.
- Контейнер: изолированный процесс, созданный из образа.
Заключение
Docker Engine API — мощный инструмент для автоматизации и удалённого управления контейнерной платформой. Его удобство требует аккуратного подхода к безопасности: чаще всего достаточно использовать Unix-сокет для локальных задач, а при необходимости открыть TCP — обязательно применять TLS/mTLS, брандмауэр и аудит. Для производственных интеграций отдавайте предпочтение проверенным SDK и автоматическим тестам, покрывающим все критичные сценарии.
Краткие рекомендации: минимизируйте поверхность атаки, автоматизируйте ротацию сертификатов и держите процессы сборки под контролем мониторинга.
Короткое сообщение для рассылки (анонс, 100–200 слов):
Docker Engine предоставляет REST API, который позволяет управлять контейнерами, образами и событиями демона через HTTP. Эта статья описывает, как включить API локально или по сети, приводит примеры запросов (создание, запуск, очистка, сборка образов), и подробно рассказывает про риски безопасности. Вы узнаете, когда стоит использовать Unix-сокет вместо TCP, как настроить TLS/mTLS для демона и какие шаги предпринимать при инциденте. Включены чеклисты для разработчиков, SRE и инженеров по безопасности, мини-методология по внедрению и тест-кейсы приёмки. Статья полезна тем, кто автоматизирует DevOps-процессы и хочет выстроить безопасный и поддерживаемый доступ к Docker API.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента