Назад | Перейти на главную страницу

Как открыть API-интерфейс докеров по TCP?

Я использую portainer и не могу управлять удаленными конечными точками. Я попытался использовать командную строку для подключения к удаленным узлам докеров, но получил сообщение Cannot connect to the Docker daemon at tcp://<remote_ip>:<port>. Is the docker daemon running?.

Да, они работают. Я добавил себя в группу докеров и могу получить доступ к докерам через SSHing в узлы. Однако я не могу получить удаленный доступ к узлам докеров.

Я модифицировал /etc/default добавить / раскомментировать DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"

Я также модифицировал /etc/init.d/docker и /etc/init/docker.conf включать DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock".

Я перезапустил службу докеров, вышел из системы и несколько раз входил в систему, но все еще не могу подключиться к удаленному узлу. Я даже не могу подключиться к локальному узлу, передав IP.

Что я упустил? Какая конфигурация в каком файле предоставляет API через TCP?

user@hostname:~$ docker -H tcp://<REMOTE_IP>:2375 info
Cannot connect to the Docker daemon at tcp://<REMOTE_IP>:2375. Is the docker daemon running?
user@hostname:~$ docker -H tcp://127.0.0.1:2375 info
Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?
user@hostname:~$ docker -H tcp://<LOCAL_IP>:2375 info
Cannot connect to the Docker daemon at tcp://<LOCAL_IP>:2375. Is the docker daemon running?
user@hostname:~$

Редактировать: Бег ps aux | grep -i docker возвращает это -

root      3581  0.1  0.2 596800 41540 ?        Ssl  04:17   0:35 /usr/bin/dockerd -H fd://
root      3588  0.0  0.0 653576 14492 ?        Ssl  04:17   0:18 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc

Я нашел решение благодаря Сообщение Ивана Крижсана.

Мне пришлось отредактировать /lib/systemd/system/docker.service в моей системе Ubuntu 16.04.2 LTS, чтобы изменить строку

ExecStart=/usr/bin/docker daemon -H fd:// -H tcp://0.0.0.0:

затем

sudo systemctl daemon-reload
sudo systemctl restart docker.service

и все заработало :-). Следующим шагом является выяснение того, как защитить форму демона докера от взлома.

В каталог / etc / default разработчики дистрибутива помещают свои файлы конфигурации. Если вы устанавливаете докер непосредственно из репозиториев Docker, этот каталог использоваться не будет.

Каталог / lib / systemd - это место, куда пакеты будут устанавливать свои файлы systemd, и они будут перезаписывать любые изменения в нем при обновлении. Если вы воспользуетесь этим, ваши изменения будут потеряны.

Чтобы внести свои собственные изменения в файл модуля systemd, которые сохранятся, вы можете создать файл модуля в /etc/systemd/system/docker.service.d/, например вот мой стандартный /etc/systemd/system/docker.service.d/override.conf:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

Это переопределение просто снимает все флаги командной строки для демона dockerd из systemd. После этого вы можете переопределить каждый параметр из /etc/docker/daemon.json, который используется докером, и, в зависимости от параметра, его можно перезагрузить без перезапуска демона. Например. вот пример /etc/docker/daemon.json:

{
"debug": false,
"experimental": true,
"hosts": ["fd://", "tcp://0.0.0.0:2376"],
"labels": ["foo=bar", "fez=baz"],
"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"},
"storage-driver": "overlay2",
"tlscacert": "/etc/docker/certs/ca.pem",
"tlscert": "/etc/docker/certs/host-cert.pem",
"tlskey": "/etc/docker/certs/host-key.pem",
"tlsverify": true
}

Для ваших целей вам понадобится только строка для установки хостов.

Одна чрезвычайно важная часть приведенного выше файла конфигурации - это настройки TLS. Если вы не настраиваете взаимный TLS между клиентом и сервером и открываете докер для прослушивания в сети, вы запускаете эквивалент открытого сервера telnet с корневым входом в систему без пароля. Если вы предпочитаете ssh, а не telnet, или если вы предпочитаете иметь пароль для своей учетной записи root, вам необходимо настроить TLS. Порты Docker API часто сканируются в Интернете, и вы вскоре обнаружите, что на вашем хосте установлено вредоносное ПО, если вы когда-нибудь пропустите этот шаг настройки.

Полную информацию о том, как настроить ключи TLS для клиента и сервера, можно найти по адресу: https://docs.docker.com/engine/security/https/


Обратите внимание, что с версиями docker 18.09 и выше на клиенте (где вы запускаете команду и на удаленном узле) вы можете использовать ssh вместо настройки TLS. Это предполагает использование DOCKER_HOST значение ssh://user@host. Например.

docker -H ssh://user@host container ls

Если вы не хотите перенастраивать и перезапускать демон докера, вы можете просто связать сокет unix с сокетом TCP, используя ncat (из nmap пакет):

ncat -lknvp 2375 -c "ncat -U /var/run/docker.sock"

В качестве альтернативы вы можете использовать socat или другие инструменты.

Для тех, кто ищет этот ответ в контексте сервера Ubuntu 20.04, который использует ЩЕЛЧОК:

Этот комментарий проблема github должен дать вам нужный контекст. В моем случае я не нашел набор переменных среды $ SNAP_DATA, поэтому мне пришлось искать все файлы daemon.json в системе и использовать тот, у которого есть /var префикс

$ sudo find / -name daemon.json

В моем случае у него было две несвязанных записи, поэтому я просто добавил свою:

{
  [.....]
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

Вышеупомянутый IP определяет, откуда он будет доступен, и порт может быть любым портом, который вы хотите открыть. В моем конкретном случае мне не удалось заставить его работать с определенным IP, вместо этого мне пришлось использовать 0.0.0.0, иначе при перезапуске произойдет сбой со следующей ошибкой:

aufs aufs_fill_super:918:mount[3724]: no arg
overlayfs: missing 'lowerdir'
aufs aufs_fill_super:918:mount[3772]: no arg
overlayfs: missing 'lowerdir'
aufs aufs_fill_super:918:mount[3820]: no arg
overlayfs: missing 'lowerdir'

Как ни странно, при использовании 0.0.0.0 он фактически выплевывает одну пару вышеуказанных строк ошибки, но после этого работает. В моем случае, поскольку это виртуальная машина, это приемлемо для меня.

Официальная документация описывает, как Настройте, где демон Docker прослушивает подключения.

systemd против daemon.json

Настройка Docker для прослушивания подключений с использованием как файла модуля systemd, так и файла daemon.json вызывает конфликт, который препятствует запуску Docker.

Настройка удаленного доступа с помощью файла systemd unit

  1. Используйте команду sudo systemctl edit docker.service, чтобы открыть файл переопределения для docker.service в текстовом редакторе.

  2. Добавьте или измените следующие строки, подставляя свои собственные значения.

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
    
  3. Сохраните файл.

  4. Перезагрузите конфигурацию systemctl.

    $ sudo systemctl daemon-reload
    
  5. Перезагрузите Docker.

    $ sudo systemctl restart docker.service
    
  6. Убедитесь, что изменение было выполнено, просмотрев вывод netstat, чтобы убедиться, что dockerd прослушивает настроенный порт.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Настройка удаленного доступа с daemon.json

  1. Задайте массив хостов в /etc/docker/daemon.json для подключения к сокету UNIX и IP-адрес, как показано ниже:

    {
    "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
    }
    

    Настройка Docker для прослушивания подключений с использованием как файла модуля systemd, так и файла daemon.json вызывает конфликт, который препятствует запуску Docker.

    1. Добавьте или измените следующие строки, подставляя свои собственные значения.

      [Service]
      ExecStart=
      ExecStart=/usr/bin/dockerd
      
    2. Сохраните файл.

    3. Перезагрузите конфигурацию systemctl.

      $ sudo systemctl daemon-reload
      
  2. Перезагрузите Docker.

  3. Убедитесь, что изменение было выполнено, просмотрев вывод netstat, чтобы убедиться, что dockerd прослушивает настроенный порт.

    $ sudo netstat -lntp | grep dockerd
    tcp        0      0 127.0.0.1:2375          0.0.0.0:*               LISTEN      3758/dockerd
    

Клиент Docker будет учитывать DOCKER_HOST переменная среды, чтобы установить -H флаг для клиента. Используйте одну из следующих команд:

$ docker -H tcp://127.0.0.1:2375 ps

или

$ export DOCKER_HOST="tcp://127.0.0.1:2375"
$ docker ps