You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker多容器环境下如何共享SSH密钥?

实现Docker容器间无密码SSH登录的方案

我来帮你搞定从f-app容器无密码SSH登录其他容器的问题,结合你的现有配置,咱们分两种实用方案来实现,分别对应构建阶段预置密钥和运行阶段动态交换密钥,你可以根据场景选合适的:

方案一:构建阶段预置密钥(适合固定镜像、测试环境)

这种方式把SSH密钥提前打包进镜像,容器启动后直接就能用,优点是启动快,不需要额外的初始化步骤。

步骤1:本地生成SSH密钥对

先在你的宿主机上生成一对无密码的RSA密钥:

ssh-keygen -t rsa -f ./id_rsa -N ""

执行后会得到id_rsa(私钥)和id_rsa.pub(公钥)两个文件。

步骤2:修改Dockerfile,注入公钥

因为所有容器都需要接受f-app的登录请求,所以我们把公钥放到所有容器的authorized_keys里;而f-app需要持有私钥,后续单独处理。修改你的Dockerfile:

FROM openjdk:8
RUN apt-get update && \
    apt-get install -y openssh-server
EXPOSE 22
# 创建用户(和原配置一致)
RUN useradd -s /bin/bash -p $(openssl passwd -1 myuser) -d /home/myuser/ -m myuser
# 创建.ssh目录并设置权限
RUN mkdir -p /home/myuser/.ssh && \
    chown myuser:myuser /home/myuser/.ssh && \
    chmod 700 /home/myuser/.ssh
# 复制公钥到authorized_keys,允许持有对应私钥的客户端登录
COPY id_rsa.pub /home/myuser/.ssh/authorized_keys
# SSH对权限要求严格,必须设置为600
RUN chown myuser:myuser /home/myuser/.ssh/authorized_keys && \
    chmod 600 /home/myuser/.ssh/authorized_keys
ENTRYPOINT service ssh start && bash

步骤3:给f-app容器挂载私钥

在docker-compose.yml里给f-app添加volume,把宿主机的私钥挂载到容器内myuser的.ssh目录下:

f-app:
    image: f-app
    tty: true
    container_name: f-app
    hostname: f-app.info.my
    ports:
      - "22:22"
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.5
    extra_hosts:
      - "f-db.info.my:172.20.0.6"
      - "p-app.info.my:172.20.0.7"
      - "p-db.info.my:172.20.0.8"
    depends_on:
      - f-db
      - p-app
      - p-db
    # 新增:挂载私钥到容器内
    volumes:
      - ./id_rsa:/home/myuser/.ssh/id_rsa
    # 新增:启动时修正私钥权限(避免权限问题)
    command: >
      bash -c "chown myuser:myuser /home/myuser/.ssh/id_rsa && chmod 600 /home/myuser/.ssh/id_rsa && service ssh start && bash"

方案二:运行阶段动态交换密钥(适合生产环境、动态场景)

这种方式不在镜像里打包密钥,而是容器启动后自动生成/交换密钥,安全性更高,适合需要频繁更换密钥或者不想把密钥暴露在镜像中的场景。

步骤1:修改Dockerfile,安装sshpass

需要用sshpass自动输入初始密码来完成密钥交换,所以更新Dockerfile:

FROM openjdk:8
RUN apt-get update && \
    apt-get install -y openssh-server sshpass  # 新增sshpass
EXPOSE 22
RUN useradd -s /bin/bash -p $(openssl passwd -1 myuser) -d /home/myuser/ -m myuser
ENTRYPOINT service ssh start && bash

步骤2:编写密钥交换脚本

在宿主机创建setup_ssh.sh脚本,内容如下:

#!/bin/bash
# 启动SSH服务
service ssh start

# 切换到myuser用户执行操作
su - myuser << EOF
# 如果没有密钥对则生成无密码密钥
if [ ! -f ~/.ssh/id_rsa ]; then
    ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""
fi

# 遍历所有目标主机,自动添加主机指纹并复制公钥
for host in f-db.info.my p-app.info.my p-db.info.my; do
    # 自动接受主机指纹,避免交互
    ssh-keyscan \$host >> ~/.ssh/known_hosts
    # 用sshpass自动输入密码,完成公钥复制
    sshpass -p 'myuser' ssh-copy-id -o StrictHostKeyChecking=no myuser@\$host
done
EOF

# 保持容器运行
bash

给脚本添加执行权限:

chmod +x setup_ssh.sh

步骤3:在docker-compose中配置f-app使用脚本启动

修改docker-compose.yml里的f-app配置,挂载脚本并设置为入口:

f-app:
    image: f-app
    tty: true
    container_name: f-app
    hostname: f-app.info.my
    ports:
      - "22:22"
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.5
    extra_hosts:
      - "f-db.info.my:172.20.0.6"
      - "p-app.info.my:172.20.0.7"
      - "p-db.info.my:172.20.0.8"
    depends_on:
      - f-db
      - p-app
      - p-db
    # 挂载脚本到容器内
    volumes:
      - ./setup_ssh.sh:/home/myuser/setup_ssh.sh
    # 设置脚本为启动入口
    entrypoint: /bin/bash /home/myuser/setup_ssh.sh

关键注意事项

  • 权限要求:SSH对.ssh目录和文件权限极其严格,必须保证:
    • ~/.ssh目录权限为700
    • id_rsa和authorized_keys权限为600
      否则会直接拒绝登录请求。
  • 服务就绪问题:depends_on只保证容器启动顺序,不保证SSH服务已经就绪。如果用方案二,建议在脚本里加重试逻辑,比如循环检查目标主机的SSH端口是否开放,再执行密钥交换。
  • 安全性建议:如果用方案一,建议给f-app单独构建镜像,不要和其他容器共享同一个带私钥的镜像,降低密钥泄露风险。

内容的提问来源于stack exchange,提问作者flywell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:22:54