问题描述
我正在尝试找到一种用于将SSH密钥注入到容器中的“全局”解决方案。我知道有几种解决方案,包括docker build kit等...但是我不想构建映像并注入SSH密钥。我想通过docker compose使用现有映像来注入SSH密钥。
我使用以下docker compose文件:
version: '3.1'
services:
server1:
image: XXXXXXX
container_name: server1
command: bash -c "/root/init.sh && python3 /root/my_python.py"
environment:
- MANAGED_HOST=mserver
volumes:
- ./init.sh:/root/init.sh
secrets:
- id_rsa
secrets:
id_rsa:
file: /home/user/.ssh/id_rsa
init.sh如下:
#!/bin/bash
eval "$(ssh-agent -s)" > /dev/null
if [ ! -d "/root/.ssh/" ]; then
mkdir /root/.ssh
ssh-keyscan $MANAGED_HOST > /root/.ssh/kNown_hosts
fi
ssh-add -k /run/secrets/id_rsa
如果我使用参数命令运行docker compose
bash -c "/root/init.sh && python3 /root/my_python.py"
,然后到适当的远程主机($ MANAGED_HOST)的SSH身份验证不起作用。
代理程序正在运行:
root 8 1 0 12:50 ? 00:00:00 ssh-agent -s
kNown_hosts可以:
root@c67655d87ced:~# cat /root/.ssh/kNown_hosts
BLABLABLA ssh-rsa AAAAB3BLABLABLA....
并且代理正在运行,但是未添加私钥:
root@c67655d87ced:~# ssh-add -l
Could not open a connection to your authentication agent.
现在,如果我登录到容器(docker exec -it server1 / bin / bash)并从命令行逐个运行init.sh中的命令,则对适当的远程主机($ MANAGED_HOST)进行SSH身份验证)在工作?!?
任何想法,我如何通过使用docker compose使其工作?
解决方法
足以使文件$HOME/.ssh/id_rsa
以适当的权限存在;您不需要运行ssh代理。
#!/bin/sh
if ! [ -d "$HOME/.ssh" ]; then
mkdir "$HOME/.ssh"
fi
chmod 0700 "$HOME/.ssh"
if [ -n "$MANAGED_HOST" ]; then
ssh-keyscan "$MANAGED_HOST" >> "$HOME/.ssh/known_hosts"
fi
if [ -f /run/secrets/id_rsa ]; then
cp /run/secrets/id_rsa "$HOME/.ssh/id_rsa"
chmod 0400 "$HOME/.ssh/id_rsa"
fi
# exec "$@"
一个典型的模式是使用Dockerfile ENTRYPOINT
来执行这样的首次设置任务。这将得到passed the CMD
as arguments,并且文件末尾的带注释的exec "$@"
行将作为命令运行。您可以通过以下方式在映像的Dockerfile中进行设置:
FROM XXXXXX
...
# Script must be executable on the host,and must start with a
# #!/bin/sh "shebang" line
COPY init.sh /root
# MUST use JSON-array form
ENTRYPOINT ["/root/init.sh"]
# Can use any Dockerfile syntax
CMD ["python3","/root/my_python.py"]
在您的特定示例中,您正在启动init.sh
作为子流程。 ssh-agent
设置会设置一些环境变量,例如$SSH_AUTH_SOCK
,但是当它们作为子进程运行时,它们不会传播回宿主进程。您可以使用标准的POSIX shell .
内置(bash source
内置是等效的,但不是标准的)来使这些环境变量在父shell的上下文中设置:
command: sh -c ". /root/init.sh && exec python3 /root/my_python.py"
exec
用您通常需要的Python脚本替换了外壳包装。这也将成为ssh-agent
的父进程,如果该进程刚好退出,则可能使您感到惊讶。