介绍
最近的项目中涉及到监控远程主机上的 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)
DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375"
但是通过这种方法修改完成重新启动 docker 守护进程之后,Docker Daemon 并没有在监听 2375 端口。然后发现其实在 /etc/default/docker
文件也有说到:
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
# Please see the documentation for "systemd drop-ins":
# https://docs.docker.com/engine/admin/systemd/
因为 Ubuntu 16.04 使用 systemd 来管理 docker 进程,/etc/default/docker
文件已经不再起作用了,该文件只对更老的系统起作用。正确的配置方式如下:
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 进程:
$ sudo service docker stop
注意:在上面的原文链接的方法中,还会修改 docker 的默认目录,也就是将 /var/lib/docker 修改成了 /data/docker ,修改之后我们原来的容器镜像都会找不到的,所以我们就不修改默认目录,还是使用原来的 /var/lib/docker。可以使用以下命令查看 docker 默认目录:
$ docker info | grep "Docker Root Dir"
Docker Root Dir: /var/lib/docker
2. Create/modify files
创建 /etc/docker/daemon.json
文件(如果已经存在则修改),加入以下内容:
{
"hosts" : ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}
- "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,其内容如下:
##Add this to the file for the docker daemon to use different ExecStart parameters (more things can be added here)
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
解释一下
默认情况下使用 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 服务:
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker.service
检查端口监听
# netstat -ntlp |grep dockerd
tcp6 0 0 :::2375 :::* LISTEN 6259/dockerd
如果检查端口监听时出现下面的提示,则说明需要使用 root 权限。
(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 服务:
$ docker -H 192.168.1.130:2375 images
$ docker -H 192.168.1.130:2375 ps