如何通过TCP公开Docker API?


13

我正在使用portainer,并且无法管理远程端点。我尝试使用命令行连接到远程docker节点,但收到一条消息Cannot connect to the Docker daemon at tcp://<remote_ip>:<port>. Is the docker daemon running?

是的,它们正在运行。我已将自己添加到docker组,并且可以通过SSH进入节点来访问docker。但是我无法远程访问任何docker节点。

我修改/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"

我重新启动了docker服务,在此过程中多次注销并登录,但仍然无法连接到远程节点。我什至无法通过传递IP连接到本地节点。

我错过了什么?哪个文件中的什么配置通过TCP公开API?

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

2375在听吗?ss -ntl
jscott

否。在2375上没有任何监听。而且我无法弄清楚哪个文件中的配置会对此产生影响。ps aux如果有帮助,我已将答案的输出包括在内。
卢勋爵。

我尝试过类似的事情,并怀疑在安装了docker-ce的Ubuntu 16.04上,文件/etc/default/docker、/etc/init/docker.conf和/etc/init.d/docker只是被忽略了,任何人都可以确认?我认为当我运行“服务docker status”时,真正发生的是“ systemctl status docker”,这是一个完整的其他管理系统。
chrisinmtown

Answers:


22

感谢Ivan Krizsan的帖子,我找到了解决方案。

我必须/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

并且一切正常:-)。下一步是弄清楚如何保护被劫持的docker daemon表单。


1
我确认此更改会导致Dockerd使用docker-ce版本17.06在Ubuntu 16.04上侦听HTTP请求。直接修改服务脚本只是感觉不对。
chrisinmtown

7
切勿直接编辑docker服务脚本(或任何服务脚本)。SystemD具有内置的差异编辑功能。Use systemctl edit docker.service和systemctl将使用您的编辑创建一个新文件。这样可以防止更新抹去您的更改。SystemD将在运行时合并两个文件。此处的好文档:digitalocean.com/community/tutorials/…–
Routhinator

谢谢!这非常有用。我在更新过程中不断收到警告。我来研究一下:_)
卢勋爵。

4
在Ubuntu Server 18.04上,它的工作方式如下:ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:4243
LUCIAN ALEXA

当我用-H tcp://本身的设置,没有-H fd://设置,我不能发出和客户端命令,例如..,码头工人的信息,搬运工版本等
克里斯˚F

2

/ etc / default目录是分发维护者放置其配置文件的位置。如果直接从Docker的存储库安装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

该覆盖简单地将所有命令行标志从systemd取消设置到dockerd守护程序。完成后,您可以覆盖docker使用的/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,并且打开了docker在网络上侦听,则说明您正在运行等效于打开的telnet服务器,并允许以root用户登录而不使用密码。如果您更喜欢ssh而不是telnet,或者您希望为根帐户输入密码,则必须配置TLS。在互联网上经常扫描docker API端口,如果您跳过此配置步骤,很快就会发现主机上安装了恶意软件。

可以在以下位置找到有关如何为客户端和服务器配置TLS密钥的完整详细信息:https : //docs.docker.com/engine/security/https/


1
一个很好的答案,它将在将来对docker服务的更新中继续存在。这是正确的方法。
Fopedush

2

如果您不想重新配置并重新启动docker守护进程,则可以使用ncat(来自nmap软件包)简单地将unix套接字桥接到TCP套接字:

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

或者,您可以使用socat或其他工具


惊人!我可以在后台运行此命令吗?当我关闭终端连接时丢失
Felix

啊,我发现nohup&
费利克斯·

0

有一个官方文档描述了如何配置Docker守护程序侦听连接的位置

systemd vs daemon.json

将Docker配置为同时使用systemd单元文件和daemon.json文件监听连接会导致冲突,从而阻止Docker启动。

使用systemd单位文件配置远程访问

  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中设置hosts数组,以连接到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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.