连接模式
socket 转发与 CLI 隧道:怎样判断当前走的是哪一条,以及怎样用上更快的那条。
SwiftServer 通过机器已有的 SSH 连接使用 Docker Engine API, 一个请求到达守护进程有两条路径。每次连接时 App 都会自动探测这两条路径, 不需要配置。但其中一条明显更好,而且通常只要在服务器上改一处就能用上它。
两种模式
socket 转发:推荐的一种。SSH 服务器把每个 Docker Engine API 请求
直接送进 Docker socket(/var/run/docker.sock,或者检测到引擎的其他位置)。
为此服务器上不需要运行任何东西:没有额外进程,不占用 sshd 的会话名额
(在 MaxSessions 很低的服务器上这一点很重要),延迟也最低。
CLI 隧道:自动回退的一种。socket 转发不可用时,SwiftServer 在服务器上运行
docker system dial-stdio,让 docker 命令行去桥接守护进程。
功能上两者完全一致,容器、Compose、镜像、卷、网络、日志、事件都走同一套
Docker Engine API。但这条路径需要服务器上装有 docker 命令行,
并且会留下少量常驻开销:最多三条保活桥接通道,所有监控请求复用它们,
而不是每个请求起一个进程。实时流(事件、容器日志)使用各自的通道,
离开页面时立即回收。
每次连接和重试都会重新选择:先试 socket 转发,失败才交给 CLI 隧道。 一旦服务器允许 socket 转发,重新连接就会让这台机器升级过去, 没有任何开关需要切换。
我现在走的是哪一条
有两个地方能看出来:
- 概览标签页上的引擎卡片带有一个传输方式徽章。绿色的 Socket:/var/run/docker.sock 表示 socket 转发,橙色的 CLI 隧道表示回退。
- 机器的 Docker 连接界面上的连接日志。走 socket 转发时它写的是
Docker Engine reachable at /var/run/docker.sock;走回退时它会显示Effective socket failed: …,引用 SSH 服务器给出的真实拒绝原因,随后是Docker Engine reachable through the pinned docker CLI tunnel。
怎样用上 socket 转发
徽章是橙色,说明两道互相独立的门里有一道没开。两道都打开,重新连接, 徽章就会变绿。
1. 你的 SSH 用户能访问 Docker socket
sshd 是以你的登录用户身份打开这个 socket 的,
所以要求和在服务器上不加 sudo 直接运行 docker 完全一样:
# Socket permissions and group — typically root:docker, 660
ls -l /var/run/docker.sock
# Is your login user in the docker group?
id
# If not, add it, then log out and back in
sudo usermod -aG docker <your-user>Rootless Docker
rootless Docker 的 socket 位于
/run/user/<uid>/docker.sock。SwiftServer 会跟随
DOCKER_HOST 或当前 Docker 上下文指向的端点,不需要手动填路径。
2. sshd 允许 Unix socket 转发
这和 Docker 的权限是两个独立的开关。docker 命令走的是 SSH 的 exec 通道,
socket 转发走的是 SSH 的转发通道,所以 docker ps 用得好好的、
这道门却仍然关着,是完全可能的。NAS 和嵌入式系统尤其经常默认关闭转发。
检查 sshd 当前生效的配置:
sudo sshd -T | grep -iE 'allowstreamlocalforwarding|disableforwarding'期望的输出是:
allowstreamlocalforwarding yes
disableforwarding no如果不是,编辑 /etc/ssh/sshd_config:
AllowStreamLocalForwarding yes同时确认没有残留的 DisableForwarding yes 行,然后重启 sshd
(sudo systemctl restart sshd,或你所用发行版的等效命令)。
一些细节
Unix socket 转发需要 OpenSSH 6.7 或更高版本。2014 年之后的主流发行版都满足这个条件,
但部分 NAS 和路由器固件带的是精简过的 sshd,没有这项能力。在这些设备上,
CLI 隧道就是正确的模式,功能上不会缺少任何东西。另外请确认
authorized_keys 里这把密钥所在的那一行没有带
restrict 或 no-port-forwarding 选项,
它们同样会阻止转发。
验证
回到这台机器的 Docker 面板,点重试(或者断开再重新连接)。
看到绿色的 Socket:… 徽章就说明成功了。如果它仍然显示 CLI 隧道,
连接日志里的 Effective socket failed: 一行会引用服务器给出的拒绝原因,
那就是还没打开的那道门。
CLI 隧道有问题吗
没有。面板一样、数据一样、可执行的操作也一样,常驻开销被限制在三条复用的
保活通道上。如果你的服务器根本无法提供 socket 转发,一直用 CLI 隧道,
你损失的也只是一点延迟,外加需要服务器上有 docker 命令行。