直接连容器比连宿主机再 docker exec 更稳,但需解决权限、启动方式、ssh 配置三重约束:用 /usr/sbin/sshd -d -e 前台运行,确认 usepam no、/var/run/sshd 可写,映射端口如 -p 2222:22,防火墙放行,sshd 监听 0.0.0.0:22,vscode 中设 preferredauthentications password 并开启 passwordauthentication yes 和 permitrootlogin yes。

直接连容器比连宿主机再 docker exec 更稳,但必须让容器自己跑 SSH 服务——这不是“额外开个端口”那么简单,而是要解决权限、启动方式、SSH 配置三重约束。
容器里装 openssh-server 后 service ssh start 不生效?
Alpine 或 slim 镜像默认没 systemd,service ssh start 会静默失败;Ubuntu/Debian 系镜像虽支持,但容器主进程不是 init,sshd 容易被 kill。
- 用
/usr/sbin/sshd -D -e替代 service 命令:-D 表示前台运行,-e 输出日志到 stderr,确保容器不退出 - 检查
/etc/ssh/sshd_config是否含UsePAM no(尤其 Alpine),否则 SSH 启动卡住 - 确认
/var/run/sshd目录存在且可写,否则报错Could not load host key
Remote-SSH 连不上容器的 22 端口?先查这三处映射
端口不通不是网络问题,90% 出在映射链路断裂:宿主机 → 容器 → SSH 进程。
- 启动容器时必须显式映射,例如
docker run -p 2222:22,不能只写-p 22(那是映射到宿主机随机端口) - 检查宿主机防火墙是否放行该端口:
sudo ufw status或sudo iptables -L | grep 2222 - 进容器执行
netstat -tlnp | grep :22,确认sshd确实在监听0.0.0.0:22,而非127.0.0.1:22
VSCode 提示 “Permission denied (publickey)” 却已配好密码登录?
Remote-SSH 默认优先走密钥认证,哪怕你没配密钥,它也会尝试发送空密钥,触发服务端拒绝,根本不会 fallback 到密码流程。
- 在 VSCode 的 SSH 配置里强制指定认证方式:在
~/.ssh/config对应 Host 段加一行PreferredAuthentications password - 确保容器内
/etc/ssh/sshd_config同时开启PasswordAuthentication yes和PermitRootLogin yes(开发环境) - 如果用非 root 用户(如
developer),记得用passwd developer设密码,并确认该用户有 shell 权限(/etc/passwd中对应行末尾是/bin/bash)
真正麻烦的不是配置步骤,而是每次改完 Dockerfile 重新构建后,容易漏掉 /var/run/sshd 初始化或 sshd_config 的某行注释——建议把 SSH 启动命令和权限检查写成一个 entrypoint.sh,作为容器唯一入口。











