Docker 之 远程连接
摘要
-
本文介绍如何远程连接Docker
远程连接Docker有如下三种方式
方式一:开启 TCP(不带 TLS,仅用于内网调试)
-
在docker服务端编辑
/etc/docker/daemon.json
,加上:
1 | { |
-
此时通过
sudo systemctl restart docker
重启 Docker会启动失败,原因是systemd会在docker启动命令中添加-H fd://
,其含义是从 systemd 传递进来的 socket 文件描述符监听 API 请求,当 Docker 被 systemd 启动并启用 socket activation(套接字激活)时,systemd 会预先创建 socket(比如 /var/run/docker.sock),然后再启动 dockerd,并通过文件描述符(fd)把这个 socket 传递给 dockerd。此时你在 dockerd 中看到的-H fd://
意思是:“不用自己打开 socket,去 systemd 那里拿吧。”
1 | # 通过该命令可以获取 docker 的启动命令文件是 /usr/lib/systemd/system/docker.service |
-
禁用
-H fd://
(systemd 与 daemon.json 冲突的根源)
1 | # 方式一: 去掉 `-H fd://` 参数 |
-
重启 docker daemon
1 | sudo systemctl daemon-reload |
-
在客户端测试连接
1 | docker -H tcp://远程IP:2375 ps |
-
在客户端加入环境变量后就不需要每次都加上 -H 参数了
1 | # zsh 就换成 ~/.zshrc |
-
❗不要开启无认证的
tcp://0.0.0.0:2375
在公网,这是裸奔的安全风险,任何人都能控制你的 Docker。 -
✅ 推荐方式是:
- 使用
tcp://0.0.0.0:2376 + --tlsverify
- 或通过
ssh:// 隧道
访问 Docker
- 使用
小贴士
- 通过上面的介绍你应该搞明白一件事,就是我们可以不用在
/etc/docker/daemon.json
中配置远程连接,而是通过 systemd 来配置,即在/usr/lib/systemd/system/docker.service
或者/etc/systemd/system/docker.service.d/override.conf
中配置。
1 | ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock |
- 那么问题来了:既然 systemd 就能搞定一切,那还要
/etc/docker/daemon.json
有什么用?答案是:可读性、可维护性、工具兼容性更强。
项目 | daemon.json |
systemd ExecStart |
---|---|---|
语法 | JSON | Shell 命令行 |
适合设置 | Hosts、日志、registry、镜像驱动等 | 启动命令、资源限制等 |
可读性 | 👍 结构化 | 👎 较长、容易出错 |
自动化支持 | 👍 工具友好 | 👎 需要 patch systemd |
方式二:开启 TCP + TLS 安全访问(推荐用于公网)
-
创建 TLS 证书,通过一个脚本实现,脚本名称
generate-docker-certs.sh
1 |
|
-
执行脚本
1 | chmod +x generate-docker-certs.sh |
-
将以下证书文件部署到docker服务端
1 | # 服务端:server-cert.pem, server-key.pem, ca.pem |
-
将以下证书文件部署到docker客户端
1 | cert.pem, key.pem, ca.pem |
-
在docker服务端编辑
/etc/docker/daemon.json
1 | { |
-
禁用
-H fd://
(systemd 与 daemon.json 冲突的根源)
1 | sudo mkdir -p /etc/systemd/system/docker.service.d |
-
重启 docker daemon
1 | sudo systemctl daemon-reload |
-
在客户端测试连接
1 | docker \ |
-
在客户端加入环境变量后就不需要每次都加上 -H 参数 和证书参数了
1 | cat <<EOT >> ~/.bashrc |
方式三:ssh:// 隧道访问
-
最简单的方式就是使用 ssh 远程执行命令的方式,这种方式不需要任何配置,支持密码和证书认证,也支持指定端口,但这不是标准的远程连接docker方式,适用于偶尔访问的情况。
1 | ssh -i ~/.ssh/lexing-test.pem -p22 centos@166.189.9.114 "docker ps" |
-
基于免密认证,如何配置免密登录可以参考 Linux常用命令--ssh、scp与免密登录
1 | # docker -H 远程访问 不支持在命令行直接输入密码或密钥文件,必须配置免密登录才可以,而且此时端口必须是默认的22 |
-
基于
config
配置(推荐)- 这种方式的优点是可以配置证书和端口
- 在 ~/.ssh/config 中指定具体的密钥文件和端口,登录用户必须拥有docker的运行权限(加入 docker group)
1
2
3
4
5Host mydocker
HostName 166.189.9.114
User centos
Port 22
IdentityFile ~/.ssh/my_docker_key- 测试
1
docker -H ssh://mydocker ps
-
添加环境变量避免每次都加上
-H
参数
1 | ## 基于免密认证 |
docker context
: 同时连接多个远程docker
-
上面介绍的三种方式,为了简化连接,都加上了
DOCKER_HOST
环境变量,但是DOCKER_HOST
只能配置一个,如果我们要同时连接多个远程docker服务呢,每次切换DOCKER_HOST
环境变量太过繁琐,可以通过下面的方式为每个远程docker服务创建一个context
1 | # TCP |
-
docker context
是 Docker CLI 的一个强大功能,它让你可以轻松地在 多个 Docker 后端环境之间切换,比如:- 本地 Docker(默认)
- 远程主机的 Docker(通过 SSH 或 TCP/TLS)
- Docker Desktop
- Docker Swarm 或 Kubernetes(部分支持)
-
就像你用
kubectl config use-context
切换 Kubernetes 集群,docker context
也允许你在多个 Docker 后端之间切换,而无需反复设置DOCKER_HOST
环境变量或写繁琐的 SSH 隧道命令。 -
常用命令一览
命令 | 说明 |
---|---|
docker context ls |
列出所有上下文 |
docker context use <name> |
切换到指定 context |
docker context create <name> --docker "Docker endpoint config" |
创建一个新的 context |
docker context rm <name> |
删除 context |
docker context inspect <name> |
查看 context 详情 |
docker context update <name> --docker "Docker endpoint config" |
更新 context 参数(Docker 24+ 支持) |
docker context show |
显示当前 context |
docker context export <name> <file.tar> |
导出 context 到tar文件 |
docker context import <name> <file.tar> |
导入 context 从tar文件 |
-
Docker endpoint config
参数名 | 中文描述 |
---|---|
from |
复制指定 context 名称 的 Docker 端点配置 |
host |
要连接的 Docker 端点地址 |
ca |
CA 签名的证书的路径 |
cert |
TLS 证书文件的路径 |
key |
TLS 密钥文件的路径 |
skip-tls-verify |
跳过 TLS 证书验证(⚠️ 不建议用于生产环境) |
三种远程连接 Docker 的方式及其优缺点总结
连接方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
1. SSH 方式 (ssh:// ) |
- 配置简单,无需额外开启 Docker TCP 端口和 TLS - 安全性高,基于 SSH 加密和认证 - 不用开放额外端口,防火墙友好 - 易于用 SSH 代理和密钥管理 |
- 需要远程用户有 Docker 权限(如属于 docker 组)- 连接速度可能受 SSH 连接影响 - 需要在本地安装并配置 SSH |
开发环境、内网管理、小规模远程操作 |
2. TCP + TLS 方式 | - 标准的远程 Docker API 访问 - 支持证书认证,安全性高 - 可以配置多个客户端和权限控制 - 适合自动化脚本、CI/CD 访问 |
- 配置较复杂,需要生成和管理 CA、服务器和客户端证书 - 需要开放 TCP 端口(如 2376),增加安全风险 - 证书配置错误容易导致连接失败 |
生产环境、自动化集成、需要高安全认证 |
3. TCP 明文访问(无 TLS) | - 配置最简单,只需监听 TCP 端口 - 方便快速测试和调试 |
- 极度不安全,数据明文传输 - 任何人都可访问 Docker API,极易被攻击 - 生产环境严重不建议使用 |
仅限局域网内测试或极简环境 |