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

如何在Docker中间件容器A中自动通过SSH执行容器B、C的命令

原有思路的问题

你的思路存在SSH密钥认证逻辑颠倒的问题:SSH密钥认证是客户端(即容器A)持有私钥,服务端(即容器B、C)存储客户端的公钥即可完成认证,不需要容器A获取B、C的SSH密钥。另外使用sshpass传递密码的方案安全性低,也不符合无交互自动化的最佳实践。

正确实现方案

1. 预生成SSH密钥对

在宿主机执行以下命令生成无密码的SSH密钥对,全程无人工交互:

ssh-keygen -t ed25519 -f ./ssh_id -N ""

执行后会在当前目录生成两个文本格式的密钥文件:

  • ssh_id:私钥,后续给容器A使用
  • ssh_id.pub:公钥,后续给容器B、C使用

2. 调整容器B、C的配置

2.1 修改Dockerfile

补充SSH服务相关配置,确保sshd服务正常运行、支持密钥登录:

FROM node
RUN apt-get update
RUN apt-get install -y openssh-server
# 配置SSH服务允许root登录、开启密钥认证
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && \
    echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config && \
    mkdir -p /root/.ssh && \
    chmod 700 /root/.ssh
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["sh", "/docker-entrypoint.sh"]
WORKDIR /home/debian
COPY ./ /home/debian
RUN git init
RUN git clone --branch master https://github.com/SamLProgrammer/LAB1SD.git
WORKDIR /home/debian/LAB1SD
RUN npm install
CMD ["node", "index.js"]

2.2 修改docker-entrypoint.sh

确保启动时先运行sshd服务,再启动业务进程:

#!/bin/sh
# 启动SSH服务
service ssh start
# 修复公钥文件权限(避免权限过大导致SSH拒绝认证)
chmod 600 /root/.ssh/authorized_keys
# 启动主业务进程
exec "$@"

2.3 启动B、C容器时挂载公钥

运行容器时直接把预生成的公钥挂载到B、C的authorized_keys路径,不需要手动进入容器操作:

# 启动容器B示例
docker run -d -v ./ssh_id.pub:/root/.ssh/authorized_keys:ro <B镜像名>
# 启动容器C示例
docker run -d -v ./ssh_id.pub:/root/.ssh/authorized_keys:ro <C镜像名>

3. 调整容器A的配置

3.1 修改Dockerfile

安装SSH客户端依赖:

FROM node
RUN apt-get update
# 安装SSH客户端
RUN apt-get install -y openssh-client
WORKDIR /home/debian
COPY ./ /home/debian
RUN git init
RUN git clone --branch another https://github.com/SamLProgrammer/DockerMiddlewareLab1.git
WORKDIR /home/debian/DockerMiddlewareLab1
RUN npm install
CMD ["node", "index.js"]

3.2 启动容器A时挂载私钥

运行容器时把预生成的私钥挂载到A的默认SSH私钥路径:

docker run -d -v ./ssh_id:/root/.ssh/id_ed25519:ro <A镜像名>

4. 调整A中的.sh脚本

添加SSH参数跳过主机密钥校验,避免首次连接弹出交互提示:

#!/bin/bash
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
# 执行B容器的远程命令
ssh $SSH_OPTS root@<B容器IP> "mkdir -p /path/to/dir && touch /path/to/dir/someFile.txt"
# 执行C容器的远程命令
ssh $SSH_OPTS root@<C容器IP> "mkdir -p /path/to/dir && touch /path/to/dir/someFile.txt"
额外优化建议

如果使用docker-compose管理三个容器,可以直接将密钥配置为compose的secrets资源,不需要手动执行挂载命令,同时容器之间可以直接用服务名通信,不需要手动获取容器IP,自动化程度更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:09:01