远程访问 Docker Daemon
介绍
最近的项目中涉及到监控远程主机上的 Docker 容器的运行状况,即通过本地 docker 客户端访问远程主机的 docker 服务端,以此来监控远程主机上的 Docker 容器。但是 Docker Daemon 默认情况下是只允许本地访问的,不允许远程访问。本文将首先介绍 Docker Daemon 的连接方式,然后说明如何配置远程访问。
Docker Daemon 的连接方式
UNIX 域套接字
默认就是这种方式, 会生成一个
/var/run/docker.sock
文件,UNIX
域套接字用于本地进程之间的通讯, 这种方式相比于网络套接字效率更高, 但局限性就是只能被本地的客户端访问。tcp 端口监听
服务端开启端口监听
dockerd -H IP:PORT
, 客户端通过指定IP和端口访问服务端docker -H IP:PORT
。通过这种方式, 任何人只要知道了你暴露的ip和端口就能随意访问你的docker服务了, 这是一件很危险的事, 因为docker的权限很高, 不法分子可以从这突破取得服务端宿主机的最高权限。
配置 Docker 远程访问
看到一些资料上面说可以通过修改 /etc/default/docker
文件来修改 Docker Daemon 的配置,也就是编辑docker的配置文件 /etc/default/docker
中的 DOCKER_OPTS
选项成同时监听本地 unix socket 和远程 http socket(2375)
1 | DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375" |
但是通过这种方法修改完成重新启动 docker 守护进程之后,Docker Daemon 并没有在监听 2375 端口。然后发现其实在 /etc/default/docker
文件也有说到:
1 | # THIS FILE DOES NOT APPLY TO SYSTEMD |
因为 Ubuntu 16.04 使用 systemd 来管理 docker 进程,/etc/default/docker
文件已经不再起作用了,该文件只对更老的系统起作用。正确的配置方式如下:
主要参考该链接:Adjustments to docker setting
1. Changes to default options
安装好 Docker 后可能有一些选项需要修改,就像我们这里想要配置 Docker Daemon 允许远程访问一样。有两种方法:
- 修改
/etc/default/docker
和/lib/systemd/system/docker.service
文件,但是这种方法对不同版本的 Docker 有不同的配置方法,不推荐。 - 创建
/etc/docker/daemon.json
来作为配置文件,Docker 推荐使用这种方法,这也是我们接下来介绍的。
注:这里使用的是 Ubuntu 16.04 LTS 系统,使用了 systemd 来管理 docker 进程。而更老版本的 Ubuntu 系统没有使用 systemd,所以只需要修改
/etc/default/docker
文件就够了。
开始之前,先关闭 docker 进程:
1 | $ sudo service docker stop |
注意:在上面的原文链接的方法中,还会修改 docker 的默认目录,也就是将
/var/lib/docker
修改成了/data/docker
,修改之后我们原来的容器镜像都会找不到的,所以我们就不修改默认目录,还是使用原来的/var/lib/docker
。可以使用以下命令查看 docker 默认目录:
1
2 $ docker info | grep "Docker Root Dir"
Docker Root Dir: /var/lib/docker
2. Create/modify files
创建 /etc/docker/daemon.json
文件(如果已经存在则修改),加入以下内容:
1 | { |
"unix:///var/run/docker.sock"
:unix socket,本地客户端将通过这个来连接 Docker Daemon。"tcp://0.0.0.0:2375"
:tcp socket,表示允许任何远程客户端通过 2375 端口连接 Docker Daemon。
注意:这里也和原文链接有点不同。
3. Servers using systemd:
可以使用 systemctl edit docker
来调用文本编辑器修改指定的单元或单元实例,ubuntu 默认调用的是 nano 编辑器,不是很好用,如果不熟悉 nano 编辑器的操作可以使用 vim 编辑器。
主要也就是新建或修改 /etc/systemd/system/docker.service.d/override.conf
,其内容如下:
1 | ##Add this to the file for the docker daemon to use different ExecStart parameters (more things can be added here) |
解释一下:
默认情况下使用 systemd 时,docker.service 的设置为:
ExecStart=/usr/bin/dockerd -H fd://
,这将覆盖写到 daemon.json 中的任何 hosts 。通过在 override.conf 文件中将 ExecStart 仅仅定义为:ExecStart=/usr/bin/dockerd
,这将会使用在 daemon.json 中设置的 hosts 。这个文件中的第一行ExecStart=
必须要有,因为它将用于清楚默认的 ExecStart 参数。如果是修改 docker.service 的文件而不是创建 override.conf,那么下次 systemd 重启时,docker.service 文件也会被重新创建。
重新加载 daemon 并重启 docker 服务:
1 | $ sudo systemctl daemon-reload |
检查端口监听:
1 | # netstat -ntlp |grep dockerd |
如果检查端口监听时出现下面的提示,则说明需要使用 root 权限。
1
2 (Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)在远程主机上面通过 tcp socket 来访问本机的 Docker Daemon 服务:
1 | $ docker -H 192.168.1.130:2375 images |
其中 192.168.1.130 是开放了远程访问的主机的 IP。
另外需要注意的是这种操作是不太安全的,仅用于测试使用。