【问题标题】:How to pass local machine's SSH key to docker container?如何将本地机器的 SSH 密钥传递给 docker 容器?
【发布时间】:2019-01-14 20:49:40
【问题描述】:

我正在尝试从 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)" .

【问题讨论】:

    标签: git docker ssh dockerfile docker-container


    【解决方案1】:

    这对我有用:

    使用此解决方法:https://stackoverflow.com/a/47544999/3957754 将文件作为构建参数传递

    Dockerfile

    ARG SSH_KEY
    ENV SSH_KEY=$SSH_KEY
    
    # Make ssh dir
    RUN mkdir /root/.ssh/
     
    # Create id_rsa from string arg, and set permissions
    
    RUN echo "$SSH_KEY" > /root/.ssh/id_rsa
    RUN chmod 600 /root/.ssh/id_rsa
     
    # Create known_hosts
    RUN touch /root/.ssh/known_hosts
    
    # Add git providers to 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)" .
    

    有了这个,您可以在构建阶段或运行阶段使用ENTRYPOINT ["docker-entrypoint.sh"] 执行git clone git@github.com...(gitlab 或bitbucket)。

    如果您需要将任何文件作为参数传递给容器,这可能会起作用

    安全

    正如评论者所说,在构建时将文件传递给容器是不安全的。解决方法和最佳实践是:在 c.i(jenkins、bamboo、circleci 等)中克隆项目并执行docker build ...。在 docker 中克隆项目通常只用于旧的所需库,而不用于主要源代码。

    【讨论】:

    • 请注意,您的 SSH 私钥对使用 docker history 命令的映像的任何用户都是可见的。请参阅build images with BuildKit 部分以了解在构建映像时使用机密的安全方法。
    • 你是对的。使用 docker history 您将能够看到图像中的所有内容。但是问题需要在构建时将文件传递给容器。在这种情况下,该文件一定是不合理的
    • 很棒的@JRichardsz,感谢您的澄清!
    • 如果我需要共享图像,这不安全,对吧?有什么解决方法吗?
    • 嗨。我在答案中添加了一个安全部分;)
    【解决方案2】:

    在你运行docker build之前,我会在主机上克隆它,使用你已经运行的ssh-agent。

    如果您确实必须在图像中拥有私钥(您已经承认这是危险的),那么您应该能够将其放在默认位置 $HOME/.ssh/id_rsa 您的代码中;不要尝试启动 ssh-agent。如果您的问题是激进的主机密钥检查,您也可以注入一个$HOME/.ssh/config 文件,或者一个已经具有主机密钥的$HOME/.ssh/known_hosts 文件。由于所有这些都是文件,您可能会发现将它们放在 Docker 构建树中并 COPY 将它们放入 $HOME/.ssh 中会更容易。

    【讨论】:

    • 谢谢,试试看。但是请注意,我无法复制当前上下文之外的内容,而 ssh 密钥将始终如此。
    • 对,但是您可以将它们cp 作为构建序列的一部分进入当前上下文(在主机上,在您之前 docker build)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 2020-03-03
    相关资源
    最近更新 更多