SwiftServer
Docker

连接模式

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 命令行。

本页内容