Docker Compose注入SSH密钥至容器失败问题求助
解决Docker Compose中SSH密钥注入后无法通过ssh-agent认证的问题
这个问题的核心原因是shell环境变量没有在命令链中正确传递,导致后续的ssh-add和Python脚本无法访问ssh-agent的socket信息。
为什么手动执行有效,而Docker Compose的command不行?
当你用docker exec -it进入容器时,你处于一个交互式shell环境中:
- 执行
eval "$(ssh-agent -s)"后,SSH_AUTH_SOCK和SSH_AGENT_PID这两个关键环境变量会被设置在当前shell里 - 后续的
ssh-add和SSH命令自然能读取到这些变量,找到运行中的agent
但在Docker Compose的command: bash -c "/root/init.sh && python3 /root/my_python.py"中:
bash -c启动的是一个非交互式子shellinit.sh里启动ssh-agent后,环境变量只存在于init.sh运行的子shell中,当init.sh执行完毕,这个子shell退出,环境变量不会传递给后续的python3命令(甚至ssh-add在init.sh里可能都没正确生效,因为子shell的环境变量隔离问题)
解决方案1:跳过ssh-agent,直接配置密钥文件(最简洁)
容器环境下其实没必要用ssh-agent,直接将密钥文件放到SSH默认读取的路径,设置正确权限即可:
修改init.sh:
#!/bin/bash # 创建.ssh目录并设置正确权限 if [ ! -d "/root/.ssh/" ]; then mkdir -p /root/.ssh chmod 700 /root/.ssh # 添加目标主机到known_hosts ssh-keyscan $MANAGED_HOST > /root/.ssh/known_hosts chmod 644 /root/.ssh/known_hosts fi # 复制密钥到默认路径并设置严格权限 cp /run/secrets/id_rsa /root/.ssh/id_rsa chmod 600 /root/.ssh/id_rsa
调整Docker Compose的command:
保持原有command即可,因为SSH会自动读取/root/.ssh/id_rsa(只要权限正确):
command: bash -c "/root/init.sh && python3 /root/my_python.py"
这种方法避开了ssh-agent的环境变量问题,更适合容器这种短生命周期的环境。
解决方案2:确保ssh-agent环境变量传递给后续命令
如果你一定要用ssh-agent,可以修改init.sh,让后续命令继承agent的环境变量:
修改init.sh:
#!/bin/bash # 启动ssh-agent并捕获环境变量 agent_output=$(ssh-agent -s) eval "$agent_output" > /dev/null # 导出环境变量,让后续进程能访问 export SSH_AUTH_SOCK SSH_AGENT_PID # 初始化.ssh目录 if [ ! -d "/root/.ssh/" ]; then mkdir /root/.ssh ssh-keyscan $MANAGED_HOST > /root/.ssh/known_hosts fi # 添加密钥到agent ssh-add -k /run/secrets/id_rsa # 执行后续命令(用exec确保环境变量继承) exec "$@"
调整Docker Compose的command:
把Python命令作为参数传给init.sh,让init.sh最后执行它:
command: ["/bin/bash", "/root/init.sh", "python3", "/root/my_python.py"]
这样,Python脚本会在设置了agent环境变量的shell中执行,就能正常使用SSH认证了。
验证方法
部署后可以进入容器,执行以下命令检查状态:
# 查看ssh-agent环境变量 docker exec -it server1 echo $SSH_AUTH_SOCK # 检查密钥是否已添加 docker exec -it server1 ssh-add -l # 测试连接目标主机 docker exec -it server1 ssh $MANAGED_HOST
内容的提问来源于stack exchange,提问作者SteveM
相关产品推荐
相关产品推荐

