Ivan's Blog

使用本地命令调用远程 Docker

我平时使用 M 系列处理器的 Mac 笔记本处理工作,偶尔会使用到 Docker 构建、调试一些镜像,次数不多,但是整个 Docker 应用会占掉磁盘几十 GB 的空间,且随着使用缓存的增加,还会越来越大。另一方面 ARM 架构的镜像无法兼容生产环境的 x86 服务器,如老旧的 MySQL5.7 就根本没有 ARM 架构的镜像,因此在考虑如何利用内网或外网中服务器的 Docker 服务处理这些工作,从而避免在本机安装 Docker 环境。

通过 SSH 直接进入到远端装有 Docker 的服务器是一个选择,但是远程连接的开发总是有很强的割裂感,尤其是各类现代编辑器的远程支持,都不如直接在本地的体验好。

K8s 集群的管理者通常在使用 kubectl 命令行工具操作的时候,可以直接在本地随意一台主机上查看所有集群的状态。Docker 官方其实也提供了类似的解决方案,就是开放 Docker 服务的端口,利用 socket 连接进行远程通信。

具体的结构是这样的:

Pasted image 20241009095057

这样无论在本地使用 docker ps 命令,还是 build 一个镜像,都是直接调用远程的 Docker 服务来进行任务,任何基于 Docker 的工具,比如 lazydocker、VSCode 的 Docker 插件等,都能成功连接到该远程服务器。

接下来说一下配置方法,想要参考官方说明的,可以看 这里 (注意,该方法不被官方推荐,原因下文会讲)。

服务端配置

编辑配置文件 /etc/docker/daemon.json,在其加入以下内容:

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

重启 docker 服务,如果发现无法重启,看看是不是启动指令与配置文件有内容冲突。可以检查 /lib/systemd/system/docker.service 服务文件,找到启动的指令中是不是有 -H fd:// 这么个参数,其中的 -H 可能会与配置中的 hosts 冲突,去掉即可,去掉后要记得使用 systemctl daemon-reload 重载一下服务,然后重启 docker。

客户端配置

客户端的 docker 命令,默认使用本地的 docker 服务进行通信,而修改默认 host 的方法是修改环境变量 DOCKER_HOST,Linux/MacOS 系统可以直接修改 .zshrc 或是 .bashrc 这样的终端实现,在配置中添加以下内容:

export DOCKER_HOST=tcp://192.168.1.225:2375

其中 192.168.1.225 可以换成你自己的服务器 IP 地址。

经过以上配置,本地的 Docker cli 工具的命令就可以直接回显远程服务器的 docker 信息了,但是新的问题来了,这个过程并没有进行鉴权,如果服务器在公网,端口暴露后其他人岂不是可以直接操作服务器中的 Docker 服务了。

没错,所以以上方法仅限于在同一个内网中,且服务器的 2375 端口并未对外暴露的情况下使用,生产环境千万不可如此操作

Docker 官方更推荐的方式是使用更为安全的 ssh 或是 https 协议进行远程调用。https 的配置方式略微复杂,需要的可以去读 官方文档 。这里只介绍 ssh 通道的方式,相比其他所有方案都更为简单。

更为简单安全的 SSH 配置方式

与 TCP 的配置方式相同,其实只需要将 DOCKER_HOST 设置为 ssh://用户@ip 即可,比如在 shell 配置中增加以下内容:

export DOCKER_HOST=ssh://root@192.168.1.225

要注意的是,该处配置的 ssh 并不支持用户密码的登录方式,因此要提前配置好 SSH 的密钥方式登录,否则将会被提示权限拒绝。同时,使用该方式无需在服务器端做任何 Docker 相关的配置修改,也就是说,如果前边配置了 TCP 的连接,要记得清空 /etc/docker/daemon.json 文件中关于 host 的配置,否则端口依然会被恶意访问。

那 SSH 更安全,为什么我还要介绍基于 tcp 端口的连接方式呢?原因有下:

对于第二条,官方也提供了对于速度的优化方案,就是在本地的 ~/.ssh/config 配置文件中添加以下内容,增加 SSH 的复用而减少每次 docker 命令都要重新建立连接的延迟:

ControlMaster     auto
ControlPath       ~/.ssh/control-%C
ControlPersist    yes

如此则可以将 ssh 下使用 docker 的体验提升到接近 TCP 直连的方式。


NEXT Figma 20240531 更新 - 又是变量更新