如何将本地机器的SSH密钥传递给Docker容器?
如何将本地机器的SSH密钥传递给Docker容器?
我正在尝试从Dockerfile构建一个Docker镜像,其中需要执行的步骤之一是安装一个只能通过私有Gitlab存储库获得的依赖项。这意味着容器需要访问SSH密钥来进行克隆。我知道这不是最安全的方法,但这只是一个临时的容器,一旦所有运行应用程序所需的组件都就位,它将被删除。
问题是,无论我尝试什么,都无法在Docker中使用ssh代理来建立连接。我得到的错误是:
npm ERR! Host key verification failed. npm ERR! fatal: Could not read from remote repository. npm ERR! npm ERR! Please make sure you have the correct access rights npm ERR! and the repository exists.
如果我尝试仅克隆存储库而不运行npm install
,同样的问题也会发生。这是我使用的Dockerfile:
FROM risingstack/alpine:3.4-v6.9.4-4.2.0 RUN apk update RUN apk add openssh ARG SSH_KEY # Authorize SSH Host RUN mkdir -p /root/.ssh && \ chmod 700 /root/.ssh && \ ssh-keyscan github.com > /root/.ssh/known_hosts # Add the keys and set permissions RUN echo "$SSH_KEY" > /root/.ssh/id_rsa && \ chmod 700 /root/.ssh/id_rsa && \ RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa && ssh -o StrictHostKeyChecking=no git@github.com || true && npm install
和以下命令(我将私钥作为构建参数传递):
docker build -t test --build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" .
问题原因:用户想要将本地机器的SSH密钥传递给Docker容器,以便在容器中进行SSH操作。
解决方法:用户可以在运行docker build
之前,在主机上使用已经运行的ssh-agent克隆密钥。如果用户确实需要将私钥放在镜像中(用户已承认这是危险的),则可以将它放在默认位置$HOME/.ssh/id_rsa
,与代码中的位置保持一致,不需要尝试启动ssh-agent。如果用户的问题是由于主机密钥检查过于严格,也可以注入一个$HOME/.ssh/config
文件,或者一个已经包含主机密钥的$HOME/.ssh/known_hosts
文件。由于所有这些都是文件,用户可能会发现将它们放在Docker构建树中并将其COPY
到$HOME/.ssh
中更容易。
感谢,我将尝试。但请注意,我无法将超出当前上下文的内容COPY
进来,而SSH密钥始终是超出上下文的。
是的,但是您可以在构建序列的一部分中将它们cp
到当前上下文中(在主机上,在您运行docker build
之前)。
问题的原因是需要将本地机器的SSH密钥传递给Docker容器,以便在构建阶段或运行阶段执行git克隆操作。但是,直接将文件传递给容器在构建时是不安全的。解决方法是使用以下的workaround来将文件作为构建参数传递:
Dockerfile:
ARG SSH_KEY ENV SSH_KEY=$SSH_KEY # 创建ssh目录 RUN mkdir /root/.ssh/ # 从字符串参数创建id_rsa,并设置权限 RUN echo "$SSH_KEY" > /root/.ssh/id_rsa RUN chmod 600 /root/.ssh/id_rsa # 创建known_hosts文件 RUN touch /root/.ssh/known_hosts # 将git提供者的公钥添加到known_hosts文件中 RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts RUN ssh-keyscan github.com >> /root/.ssh/known_hosts RUN ssh-keyscan gitlab.com >> /root/.ssh/known_hosts
构建命令:
docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .
通过以上方法,可以在构建阶段或运行阶段执行git克隆操作(gitlab或bitbucket)。这种方法也适用于传递任何文件作为容器的参数。
需要注意的是,在构建时将文件传递给容器不安全。最佳实践是在持续集成工具(如Jenkins、Bamboo、CircleCI等)中克隆项目,然后执行docker build命令。在Docker中克隆项目通常只用于获取旧的依赖库,而不是主要源代码。
另外,要注意SSH私钥将在镜像中的任何用户都可以使用docker history命令查看到。关于在构建镜像时安全使用机密信息的方法,请参考Docker文档中的"build images with BuildKit"部分。
需要注意的是,使用docker history命令可以查看镜像中的所有内容。但是问题需要在构建容器时传递文件,而这种情况下的文件不应该是敏感的。
需要注意的是,这种方法在Windows上不适用。另外要记住,99%的需求或云平台都使用Linux来构建镜像,Windows上构建只适用于演示或学习,不适用于生产环境。