← Назад к вопросам

Как docker run находит Daemon

2.0 Middle🔥 201 комментариев
#Docker и контейнеризация#Сети и протоколы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как команда docker run находит Docker Daemon

Процесс поиска и взаимодействия с Docker Daemon при выполнении docker run — это фундаментальный механизм работы Docker CLI. Разберу этот процесс поэтапно, начиная с архитектуры и заканчивая конкретными сетевыми вызовами.

Архитектурный контекст: Клиент-Серверная модель

Docker использует клиент-серверную архитектуру:

  • Docker CLI (клиент): Это утилита командной строки (docker), которую вы выполняете. Её задача — принять команду, разобрать её и отправить корректный запрос демону.
  • Docker Daemon (dockerd, сервер): Это фоновый процесс, который управляет жизненным циклом контейнеров, образами, сетями, томами — всей "тяжелой" работой. Он постоянно работает на хост-машине.

Команда docker run не запускает контейнер сама по себе. Она является клиентским запросом к демону, который и выполняет фактическую работу.

Пошаговый алгоритм поиска демона

Когда вы вводите docker run nginx:alpine, происходит следующее:

  1. Парсинг команды CLI: CLI разбирает аргументы (run, nginx:alpine, флаги вроде -p, -v).

  2. Определение адреса демона (Endpoint Resolution):

    CLI ищет, **куда** отправить запрос. Источники проверяются в порядке приоритета:

    *   **Переменная окружения `DOCKER_HOST`**: Самый приоритетный способ. CLI использует её значение как адрес демона.
    ```bash
    # Пример: подключение к демону на удалённой машине по TCP (небезопасно!)
    export DOCKER_HOST="tcp://192.168.1.100:2375"
    # Пример: использование безопасного TLS-соединения
    export DOCKER_HOST="tcp://docker.example.com:2376"
    export DOCKER_CERT_PATH="/path/to/certs"
    ```
    *   **Контексты Docker (Docker Contexts)**: Современный механизм управления несколькими окружениями (локальный Docker, удалённые кластеры Swarm/Kubernetes). Текущий контекст определяет endpoint.
    ```bash
    # Просмотр доступных контекстов и текущего
    docker context ls
    docker context use my-remote-context
    ```
    *   **Стандартные сокеты по умолчанию**: Если `DOCKER_HOST` не задана и не используется специфичный контекст, CLI пытается подключиться к стандартным Unix-сокетам в следующем порядке:
        *   `unix:///var/run/docker.sock` (основной сокет на Linux)
        *   `unix:///var/run/podman/podman.sock` (для совместимости с Podman)
        *   `npipe:////./pipe/docker_engine` (именованный канал на Windows)
        *   `unix://${HOME}/.docker/run/docker.sock` (пользовательский режим — rootless Docker)

  1. Установка соединения и аутентификация:
    *   Для **Unix-сокета** (`/var/run/docker.sock`) проверяются права доступа текущего пользователя. Обычно требуется членство в группе `docker`. Соединение устанавливается через локальный файловый дескриптор.
    *   Для **TCP-соединения** (часто `2375`/`2376` порт) происходит сетевое подключение. На порту `2376` по умолчанию используется **TLS-аутентификация**. CLI проверяет сертификаты (указанные в `DOCKER_CERT_PATH`), чтобы удостовериться в легитимности демона и сам представиться ему.

  1. Отправка HTTP-запроса по REST API:
    Docker Daemon предоставляет **RESTful API**. CLI формирует HTTP-запрос соответствующего метода.
    Для `docker run` это обычно последовательность вызовов:
    *   `POST /images/create` (если образа нет локально) — скачивание образа.
    *   `POST /containers/create` — создание контейнера с заданной конфигурацией.
    *   `POST /containers/{id}/start` — запуск созданного контейнера.

    **Пример минимального запроса на создание контейнера (в виде curl)**
```bash
# Это то, что Docker CLI делает "под капотом" при подключении к Unix-сокету
curl --unix-socket /var/run/docker.sock \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"Image": "nginx:alpine"}' \
  http://localhost/containers/create
```

5. Получение и обработка ответа:

    Демон выполняет запрос (собирает слои образа, создает namespaces и cgroups, запускает процесс) и возвращает ответ CLI. CLI, в свою очередь, перенаправляет потоки вывода (`STDOUT`, `STDERR`) контейнера в ваш терминал, если не указан флаг `-d` (detached mode).

Ключевые моменты и безопасность

  • Локальный сокет (docker.sock): Фактический файл. Монтирование его в контейнер (-v /var/run/docker.sock:/var/run/docker.sock) дает контейнеру полный контроль над хост-демоном (это мощно, но критично с точки зрения безопасности).
  • Удалённый демон: Включение TCP-порта (-H tcp://0.0.0.0:2375 в настройках демона) без TLS крайне опасно — это эквивалентно выдаче root-доступа к хосту любому в сети. Всегда используйте 2376 порт с настройкой TLS-сертификатов.
  • Rootless-режим: В этом режиме демон запускается от имени обычного пользователя и использует сокет в домашней директории. Это повышает безопасность, изолируя потенциальные компрометации.

Таким образом, docker run находит демона через гибкую систему определения endpoint, которая учитывает переменные окружения, контексты и стандартные пути, после чего устанавливает безопасное соединение (через сокет или TLS) и взаимодействует с ним через HTTP API.