如何在 Docker 容器内使用 SSH 密钥?

容器内用 SSH 密钥的安全做法:挂载密钥目录为只读卷(-v ~/.ssh:/root/.ssh:ro)或构建期用 BuildKit 的 --mount=type=ssh;切忌 COPY 私钥进镜像。本文给出各方案与安全对比。

最佳实践
如何在 Docker 容器内使用 SSH 密钥?封面

核心原则:私钥绝不 COPY 进镜像(镜像层会永久留存,推到仓库就泄露)。运行时用法:把宿主机 .ssh 目录只读挂载进容器 -v ~/.ssh:/root/.ssh:ro;构建期用法(如构建时拉私有 git 仓库):用 BuildKit 的 SSH 挂载 RUN --mount=type=ssh,密钥不落镜像层。

方案一:运行时挂载(最常见)

docker run -it -v ~/.ssh:/root/.ssh:ro my-image
  • :ro 只读,容器改不了也泄露面小
  • 挂载的是目录,容器内 ssh 会找到 id_rsa/id_ed25519
  • 权限要求:ssh 要求私钥 600,挂载保持宿主权限一般没问题

容器内验证:

ssh -T git@github.com

方案二:构建期 SSH 挂载(拉私有依赖)

Dockerfile:

# syntax=docker/dockerfile:1
FROM python:3.12-slim
RUN apt-get update && apt-get install -y git openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh pip install git+ssh://git@github.com/org/private-repo.git

构建命令:

eval $(ssh-agent) && ssh-add
DOCKER_BUILDKIT=1 docker build --ssh default .

密钥通过 ssh-agent 转发进构建过程,不会留在任何镜像层——这是与 COPY 私钥的本质区别。

方案三:ssh-agent 套接字转发(docker run)

docker run -it \
  -v $SSH_AUTH_SOCK:/ssh-agent \
  -e SSH_AUTH_SOCK=/ssh-agent \
  my-image

容器内 ssh 直接使用宿主机的 agent,私钥文件根本不进容器。

反面清单

做法 问题
COPY id_rsa /root/.ssh/ 私钥永久留在镜像层,推仓库=泄露
ENV SSH_KEY=... docker inspect/history 可见
密钥放共享卷长期挂着 权限管理困难,用完即挂更好

观测云对照

密钥使用行为纳入审计视野。 容器对外 SSH 连接的日志(known_hosts 变化、连接记录)属安全敏感操作,统一采集后可追溯。

常见问题(FAQ)

Q:挂载后 ssh 报 "permissions are too open"?
A:Windows 挂载目录权限模拟问题;在容器内 chmod 600 /root/.ssh/id_* 或改用 agent 转发方案。

Q:容器内访问 Git 还要配什么?
A:git config --global user.email/name,以及把主机公钥加过 Git 平台的 deploy key。

Q:K8s 里怎么用?
A:私钥放 Secret,volume 挂载(defaultMode 0600);构建期用 Kaniko/BuildKit 的 ssh 机制。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台