Moby: 将 ssh 密钥代理转发到容器中

创建于 2014-06-13  ·  190评论  ·  资料来源: moby/moby

能够在runbuild期间将 ssh 密钥代理转发到容器中会很好。
我们经常需要构建存在于私有存储库中的源代码,其中访问由 ssh 密钥控制。

将密钥文件添加到容器中是一个坏主意,因为:

  1. 您刚刚失去了对 ssh 密钥的控制
  2. 您的密钥可能需要通过密码解锁
  3. 您的密钥可能根本不在文件中,只能通过密钥代理访问。

你可以这样做:

# docker run -t -i -v "$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" fedora ssh-add -l
2048 82:58:b6:82:c8:89:da:45:ea:9a:1a:13:9c:c3:f9:52 phemmer<strong i="15">@whistler</strong> (RSA)

但:

  1. 这仅适用于docker run ,不适用于build
  2. 这仅在 docker 守护程序与客户端在同一主机上运行时才有效。

理想的解决方案是让客户端像ssh一样转发密钥代理套接字。
然而,这样做的困难在于它需要远程 API 构建和附加调用来支持代理任意数量的套接字流。 仅执行单个 2 路流是不够的,因为 ssh 密钥代理是一个 unix 域套接字,并且它可以同时具有多个连接。

aresecurity exintermediate kinfeature

最有用的评论

@kienpham2000 ,为什么这个解决方案不会将密钥保存在图像层中? 复制和删除密钥的操作是在单独的命令中完成的,因此应该有一个包含密钥的层。
直到昨天,我们的团队一直在使用您的解决方案,但我们找到了改进的解决方案:

  • 我们使用aws s3 cli生成一个预签名URL来访问密钥,并限制访问大约5分钟,我们将这个预签名URL保存到repo目录中的一个文件中,然后在dockerfile中我们将其添加到图像中。
  • 在 dockerfile 中,我们有一个 RUN 命令执行所有这些步骤:使用 pre-sing URL 获取 ssh 密钥,运行 npm install 并删除 ssh 密钥。
    通过在单个命令中执行此操作,ssh 密钥不会存储在任何层中,但会存储预签名 URL,这不是问题,因为 URL 在 5 分钟后将无效。

构建脚本如下所示:

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile 看起来像这样:

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no [email protected] || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]

所有190条评论

不知道#6075会不会给你你需要的

一个秘密容器可能会让它更安全一点,但所有提到的要点仍然有效。

+1 我会发现此功能也很有用。 例如,特别是在构建需要来自私有 git 存储库的软件的容器时。 我宁愿不必将 repo 密钥共享到容器中,而是希望能够让“docker build ...”使用其他一些方法来访问解锁的 SSH 密钥,也许是通过运行 ssh -代理人。

+1。 我刚刚开始接触 Docker,这是我遇到的第一个障碍。 我花了一段时间尝试使用 VOLUME 来安装 auth sock,然后才意识到 docker 不能/不会在构建过程中安装主机卷。

我不希望无密码 SSH 密钥的副本到处都是,并且将一个副本复制到容器中然后在构建期间将其删除的机制感觉是错误的。 我确实在 EC2 内工作,甚至不喜欢将我的私钥复制到那里(无密码与否)。

我的用例是用 rebar 构建一个 erlang 项目。 果然,我_可以_克隆第一个 repo 并使用 Dockerfile 将其添加到映像中,但这不适用于项目具有的私有依赖项。 我想我可以在主机上构建项目并将结果添加到新的 Docker 映像中,但我想在 Docker 沙箱中构建它。

以下是其他一些具有相同用例的人: https :

请拥抱 SSH_AUTH_SOCK,它非常有用。

谢谢

编辑:既然我对 Docker 的工作原理(FS 层)有了更多的了解,就不可能执行我在构建期间添加 SSH 密钥并稍后删除它所描述的内容。 密钥仍将存在于某些 FS 层中。

+1,能够使用 SSH_AUTH_SOCK 将非常有用!

我使用 SSH 密钥对 Github 进行身份验证,无论是私有存储库还是公共存储库。

这意味着我的git clone命令看起来像: git clone [email protected]:razic/my-repo.git

我可以在docker runssh期间将我的主机~/.ssh目录批量安装到我的容器中。 但是,我无法在docker build期间挂载我的~/.ssh docker build

:+1: 用于构建期间的 ssh 转发。

据我所知,这是错误的方式。 正确的方法是在开发机器上创建 docker 镜像,然后将其复制到 docker 服务器。

@SevaUA - 不,那不正确。 此请求是由于执行docker build...时的限制。 您不能像执行docker run ...那样将变量导出到此阶段。 run 命令允许在运行时将变量导出到 docker 容器中,而构建不允许这样做。 此限制部分是基于 dockerd 在构建容器时的工作方式而有意为之。 但是有很多方法可以解决这个问题,并且所描述的用例是一个有效的用例。 因此,此请求试图以某种方式在构建中实现此功能。

我喜欢#6697(秘密商店/保险库)的想法,一旦合并,这可能会起作用。但如果这不起作用,另一种方法是做中间人透明代理 ssh 的东西在 docker daemon 之外,拦截 docker daemon 流量(不在内部)。 或者,所有 git+ssh 请求都可以发送到某个本地定义的主机,该主机透明地代理到 github 或您最终需要到达的任何内容。

这个想法已经被提出(见评论 2)。 它不能解决问题。

+1 用于构建期间的 ssh 转发。

+1 在docker build上的 SSH 代理转发

+1 用于构建过程中的 ssh 转发,例如 npm install 或类似的。

有没有人在 OSX 上运行期间进行 ssh 转发? 我在这里提出了一个问题: http ://stackoverflow.com/questions/27036936/using-ssh-agent-with-docker/27044586?noredirect=1#comment42633776_27044586 看起来 OSX 不可能......

+1 =(

也只是遇到了这个障碍。 试图运行npm install指向一个私人回购。 设置看起来像:
host -> vagrant -> docker可以 ssh-agent 转发host -> vagrant -! docker

+1
只是在尝试弄清楚如何在“docker build”期间让 ssh 代理工作时点击这个。

+1 和以前的家伙一样。 在构建 Docker 映像时需要访问一个或多个私有 git 存储库(例如bundle installnpm install )时,似乎是解决此问题的最佳方法。

我可以在 docker run 期间将我的主机 ~/.ssh 目录批量安装到我的容器中,并且 ssh 一切都很好。

@razic你能分享一下你是如何工作的吗? 因为当我尝试之前它确实抱怨“错误的所有者或权限”

除非您确保所有容器都以允许您这样做的特定用户或权限运行?

+1 到 SSH_AUTH_SOCK

@tonivdv查看有关此问题的初始评论中的docker run命令。 它绑定将SSH_AUTH_SOCK引用的路径挂载到容器内的/tmp/ssh_auth_sock ,然后将容器中的SSH_AUTH_SOCK设置为该路径。

@md5我假设@razic@tonivdv正在谈论这样的挂载: -v ~/.ssh:/root/.ssh:ro ,但是当您这样做时,.ssh 文件不归 root 所有,因此无法通过安全检查。

@KyleJamesWalker是的,这就是我从@razic那里@razic能够让它工作时,我想知道如何:)

@tonivdv我也很想知道这是否可能,但我上次尝试时找不到任何东西。

+1 我对使用 Docker 构建一次性开发环境很感兴趣,但我无法让它正常工作。 这在这方面会有很大帮助。

对于任何寻找临时解决方案的人,我有一个修复程序,我使用它来暴力破解:

https://github.com/atrauzzi/docker-laravel/blob/master/images/php-cli/entrypoint.sh

这绝不是一个理想的解决方案,因为它需要一个完整的入口点脚本,但确实有效。

@atrauzzi有趣的方法。 对于我们的开发环境,我们构建了一个基础镜像并直接将 ssh 密钥复制到其中。 它的优点是不需要在每次运行时都提供它。 并且默认情况下从该法师继承的每个图像也包含密钥。 但是,通过我们的方式,您显然无法公开分享它;p

+1 这会很棒

@tonivdv脚本所用的容器经常被制作和销毁,因为它只是 CLI 工具的主机。 您当然可以自由地只进行一次操作。 但是,如果有人更改了他们的设置并通过容器重新运行命令,则每次都必须是新副本。

@atrauzzi我明白。 您的方法应该被 docker 镜像采用,这可能需要一个私有 ssh 密钥。 例如,在私有存储库的情况下,作曲家图像应包含您的入口点脚本。 至少在 docker 提供本机解决方案之前。

:+1: 用于通过构建的 ssh 转发

这里也是必备!

@atrauzzi我目前正在使用另一种我非常喜欢的方法。 它正在制作一个包含 ssh 内容的数据卷容器。 当您想将 ssh 密钥用于另一个容器时,我可以简单地使用以下命令来使用它:

docker run -ti --volumes-from ssh-data ...

这样你就不需要在每个图像上放置一个入口点,它可以处理所有图像。

要创建该容器,我执行以下操作

docker run \
  --name ssh-data \
  -v /root/.ssh \
  -v ${USER_PRIVATE_KEY}:/root/.ssh/id_rsa \
  busybox \
  sh -c 'chown -R root:root ~/.ssh && chmod -R 400 ~/.ssh'

希望这可以帮助其他人:)

干杯

@tonivdv - 我采用了我的方法,因为如果有人必须添加或更新 SSH 设置,则必须重新导入它们。 我正在使用的特定容器是为运行单个命令而构建的,因此每次运行时,它都会获取副本以确保它是最新的。

@atrauzzi 是的,我明白。 话虽如此,正确维护其 ssh 卷容器取决于用户。 如有必要,他甚至可以使用不同的。 并且可以选择使用脚本即时生成它。 但我认为没有唯一的好解决方案。 这一切都取决于需求。 只是想分享,以便其他人可以根据自己的需要选择什么解决方案。 希望尽快写博客,我也会转发你的解决方案! 干杯

我不会要求运行容器的人维护一个充满 ssh 密钥的纯数据容器。 似乎涉及。

@atrauzzi确实,卷容器必须在那里,但是按照您的方式,用户必须在运行时共享它的 ssh 密钥,对吗? 因此,除了需要 ssh 卷容器之外,从运行的角度来看,这两种解决方案的唯一区别是:

docker run ... --volumes-from ssh-data ... php-cli ...

docker run ... -v ~/.ssh:/path/.host-ssh ... php-cli ..

对? 还是我错过了其他东西:)

但我完全明白你为什么要这样做。 但是,如果您想使用例如来自其他人的作曲家图像,volume-from 方式将开箱即用。 至少它避免了使用“入口点黑客”创建自己的图像。

正如我所说,两者都是一种解决方法,都各有利弊。

干杯

从 Docker 团队获得有关此功能状态的更新真的很棒。 具体来说,来自docker build SSH 身份验证。

这已经接近1年了。 考虑到现实生活用例的实用性,这有点令人惊讶。 目前,我们通过提交运行的容器来动态生成图像。 我们的应用程序存储库中不能有Dockerfile 。 这打破了几乎所有事情的流程。 在解决此问题之前,我无法真正将我的应用程序与 Compose 或 Swarm 等任何 Docker 服务一起使用。

更新将不胜感激。 谢谢,麻烦您了。

/cc @phemmer

并不是我们不想要这个功能或任何东西,我真的看到了这样的用例或构建中的秘密,我们只需要一个愿意实施的人的提案,然后如果批准了提案的实施。
此外,我代表我自己而不是所有维护者发言。

@jfrazelle

我知道你们没有忽视我们:)

所以状态是:

如果有一个被接受的提案,我们会考虑实施
和工程带宽。

这听起来准确吗?

另外,目前是否有任何公开的提案可以解决这个问题?

周二,2015年4月7日,杰西Frazelle [email protected]写道:

并不是我们不想要这个功能或任何东西,我真的看到了用处
对于这样的事情或构建中的秘密,我们只需要一个
来自愿意实施的人的提议,然后如果批准
提案的实施。
此外,我代表我自己而不是所有维护者发言。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90737847。

如果有一个被接受的提案,我们会考虑实施
和工程带宽。

是的

我不认为对此有任何公开的提议。

2015 年 4 月 7 日星期二下午 2:36,Zachary Adam Kaplan <
[email protected]> 写道:

@jfrazelle

我知道你们没有忽视我们:)

所以状态是:

如果有一个被接受的提案,我们会考虑实施
和工程带宽。

这听起来准确吗?

另外,目前是否有任何公开的提案可以解决这个问题?

2015 年 4 月 7 日,星期二,Jessie Frazelle通知@github.com
写道:

并不是我们不想要这个功能或任何东西,我真的看到了用处
对于这样的事情或构建中的秘密,我们只需要一个
来自愿意实施的人的提议,然后如果批准
提案的实施。
此外,我代表我自己而不是所有维护者发言。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90737847。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90738913。

我不知道我是否过于简单化了,但这是我的建议:

SSHAGENT: forward # 默认忽略

如果设置,在构建期间,套接字和相关的环境变量将连接到容器,在那里可以使用它们。 它的机械部分已经存在并且正在工作,只需将它们连接到docker build

我没有在 docker 代码库中工作的任何经验,但这对我来说非常重要,我会考虑接受它。

伟大的。 我在哪里可以找到如何提交提案? 有没有
具体指南还是我应该打开一个问题?

周二,2015年4月7日,杰西Frazelle [email protected]写道:

如果有一个被接受的东西,我们会考虑实施
提议
和工程带宽。

是的

我不认为对此有任何公开的提议。

2015 年 4 月 7 日星期二下午 2:36,Zachary Adam Kaplan <
通知@github.com
<_e i="18">

@jfrazelle

我知道你们没有忽视我们:)

所以状态是:

如果有一个被接受的东西,我们会考虑实施
提议
和工程带宽。

这听起来准确吗?

另外,目前是否有任何公开的提案可以解决这个问题?

2015 年 4 月 7 日,星期二,Jessie Frazelle < [email protected]
<_e i="31"/> 写道:

并不是我们不想要这个功能或任何东西,我真的看到了
利用
对于这样的事情或构建中的秘密,我们只需要一个
来自愿意实施的人的提议,然后如果批准
提案的实施。
此外,我代表我自己而不是所有维护者发言。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90737847。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90738913。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90739596。

我的意思是像一个设计提案
https://docs.docker.com/project/advanced-contributing/#design -proposal

2015 年 4 月 7 日,星期二,下午 2:39,Daniel Staudigel通知@ github.com
写道:

我不知道我是否过于简单化了,但这是我的建议:

SSHAGENT: forward # 默认忽略

如果设置,在构建期间,套接字和相关的环境变量是
连接到容器,在那里可以使用它们。 机械零件
这已经存在并且正在工作,这只是连接的问题
它们在 docker build 中。

我没有在 docker 代码库中工作的任何经验,但是这个
对我来说足够重要,我会考虑接受它。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90739803。

这是一个非常高级的想法,但是如果 docker 不是通过 docker 远程 api 附加,而是在容器内运行一个带有捆绑的 ssh 守护程序的 init 守护程序呢?

这可以用来解决许多问题。

  • 该守护进程将是 PID 1,主容器进程将是 PID 2。这将解决 PID 1 忽略信号和容器未正确关闭的所有问题。 (#3793)
  • 这将允许干净地转发 SSH 密钥代理。 (#6396)
  • 这个守护进程可以打开命名空间 (#12035)
  • 守护进程将创建 TTY (#11462)
  • ...可能还有许多其他问题我都忘记了。

你可能想看看https://github.com/docker/docker/issues/11529关于
第一个要点

2015 年 4 月 7 日星期二下午 2:46,Patrick Hemmer通知@ github.com
写道:

这是一个非常高级的想法,但是如果不是通过附加
docker 远程 api,docker 运行了一个 init 守护进程,并带有一个捆绑的 ssh
守护进程,在容器内?

这可以用来解决许多问题。

  • 该守护进程将是 PID 1,主容器进程将是
    PID 2. 这将解决 PID 1 忽略信号和
    容器未正确关闭。 (#3793
    https://github.com/docker/docker/issues/3793)
  • 这将允许干净地转发 SSH 密钥代理。 (#6396
    https://github.com/docker/docker/issues/6396)
  • 这个守护进程可以打开命名空间 (#12035
    https://github.com/docker/docker/issues/12035)
  • 守护进程会创建一个 TTY (#11462
    https://github.com/docker/docker/issues/11462)
  • ...可能还有许多其他问题我都忘记了。


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90741192。

11529 与 PID 1 问题完全无关。

拍摄效果复制粘贴,现在我必须再次找到另一个

不,它是那个,它修复了 PID 1 僵尸的东西,这就是我以为你指的是什么,但不管我只是张贴,因为它的 intesting 是全部

@phemmer听起来您有专业知识可以指导我们制定明智的实施建议。

它看起来也像@dts ,我愿意花时间做这件事。

@phemmer@dts有什么可能的方法可以将这个讨论带入一个稍微更实时的聊天客户端,以便更轻松地交流? 我可以通过 Slack、Google Chat/Hangout、IRC 联系我,如果需要,我会下载其他任何东西。

@phemmer听起来您有专业知识可以指导我们制定明智的实施建议

不幸的是不是真的:-)
我可以抛出设计想法,但我只知道 docker 代码库的一小部分。 这种类型的变化很可能是大规模的。

这里已经有一些提议:

@phemmer建议

如果 docker 不是通过 docker 远程 api 附加,而是在容器内运行一个带有捆绑的 ssh 守护程序的 init 守护程序怎么办?

@dts建议

SSHAGENT: forward # 默认忽略
如果设置,在构建期间,套接字和相关的环境变量将连接到容器,在那里可以使用它们。 它的机械部分已经存在并且正在工作,这只是在 docker build 中连接它们的问题。

@razic建议

docker build启用卷绑定。

在这一点上,我们真正需要的是有人接受其中之一,这样我们就可以开始着手处理了。

@jfrazelle知道我们如何进行下一步吗? 真的,我只是想完成这件事。 很明显,人们对此很感兴趣。 我愿意支持该功能,直到完成为止。

我可以参加 slack/irc/Gchat/etc 会议,我认为这会让事情变得容易一些,至少可以收集需求并决定合理的行动方案。

@dts建议

SSHAGENT: forward # 默认忽略

这只是关于如何使用它的一个想法,而不是实施。 “init/ssh 守护进程”是一个如何实现的想法。 两者都可以存在。

@razic建议

为 docker run 启用卷绑定。

不幸的是,这行不通。 假设这意味着docker build ,而不是已经支持卷安装的docker run ,那么客户端可以是远程的(boot2docker 是一个突出的例子)。 卷绑定仅在客户端与 docker 守护程序位于同一主机上时才有效。

@razic请参阅有关设计提案的链接...这些不是提案https://docs.docker.com/project/advanced-contributing/#design -proposal

@phemmer

我无法完全理解为什么这行不通。 docker-compose适用于针对swarm集群的卷安装。 如果文件/文件夹不在主机系统上,它的行为与您使用不存在的路径运行-v时的行为相同。

@jfrazelle 明白了。

如果文件/文件夹不在主机系统上,它的行为与您使用本地 docker 上不存在的路径运行 -v 的行为相同。

我不确定我是否遵循你的观点。 这种行为如何帮助解决这个问题?
如果我有一个 ssh 密钥代理在我的本地机器上监听/tmp/ssh-UPg6h0 ,并且我在远程机器上运行 docker,并调用docker build ,则本地 ssh 密钥代理无法访问码头守护进程。 卷安装不会得到它,并且docker build容器将无法访问 ssh 密钥。

从高层次来看,我认为只有两种方法可以解决这个问题:

1. 代理 ssh 密钥代理套接字:

docker 守护进程在容器内创建一个 unix 域套接字,每当有东西连接到它时,它就会将该连接代理回实际运行docker build命令的客户端。

这可能很难实现,因为在容器内可以有任意数量的连接到该 unix 域套接字。 这意味着 docker 守护进程和客户端必须代理任意数量的连接,或者守护进程必须能够说出 ssh 代理协议,并多路复用请求。

但是,既然 docker 远程 API 支持 websockets(在创建此问题时还没有),这可能不会太难。

2. 启动一个真正的 SSH 守护进程

不是绕过 ssh 代理,而是使用从客户端到容器的实际 ssh 连接。 docker 客户端要么捆绑了一个 ssh 客户端,要么将ssh调用到远程容器中。
这将是一个更大规模的变化,因为它将取代实现附加到容器的方式。 但它也可以减轻 docker 处理这个问题的麻烦,并迁移到标准协议。
这也有解决的其他问题(如提到的潜在这里)。

所以最终会有更大规模的变化,但可能是一个更合适的解决方案。
虽然实际上,由于规模,我怀疑这会发生。

@phemmer

我不确定我是否遵循你的观点。 这种行为如何帮助解决这个问题?

因为最常见的用例是人们使用托管在需要 SSH 身份验证的私有存储库中的依赖项构建映像。

您在具有 SSH 密钥的机器上构建映像。 就那么简单。

如果我有一个 ssh 密钥代理在我的本地机器上监听 /tmp/ssh-UPg6h0,并且我在远程机器上运行 docker,并调用 docker build,那么 docker 守护程序无法访问该本地 ssh 密钥代理。

我知道。 谁在乎? 我将在可以访问 auth 套接字的机器上运行docker build

我想说的是.... docker-compose允许您对swarm集群使用 volume 命令,无论文件是否实际位于主机上! .

我们应该对 docker 构建上的卷挂载做同样的事情。

| 文件在系统上 | 行动 |
| :-- | :-- |
| 是 | 安装 |
| 没有 | 无(实际上,如果文件/文件夹不存在,它会尝试挂载但会创建一个空文件夹,您可以通过运行docker run -v /DOES_NOT_EXIST:/DOES_NOT_EXIST ubuntu ls -la /DOES_NOT_EXIST来验证这一点)|

swarm背后的概念之一是使多主机模型透明。

很好,我们正在考虑远程 docker,但这应该无关紧要。

我们应该以与docker run完全相同的方式复制docker build卷挂载行为。

https://github.com/docker/compose/blob/master/SWARM.md

阻止多容器应用程序在 Swarm 上无缝工作的主要事情是让它们相互通信:在不同主机上的容器之间实现私有通信还没有以一种非黑客的方式解决。

从长远来看,网络正在以一种更适合多主机模型的方式进行彻底改革。 目前,链接的容器会自动安排在同一主机上。

@phemmer我认为人们可能正在考虑针对您描述的问题的解决方案。 您所描述的问题听起来像https://github.com/docker/docker/issues/7249 ,它是独立的。

如果我们采用我的方法:只允许在 docker build 中挂载卷(无论您尝试挂载的文件是否确实在系统上,那么我们可以关闭此问题。并开始在https://github.com/ 上工作

@cpuguy83在我创建提案之前,我正在查看 #7133 并注意到它看起来直接相关。

你能在这里补充几句吗? #7133 实际上与我解决此问题的建议有关,即允许docker build支持卷。

@razic这与VOLUME /foo实际上创建一个卷并在构建期间将其安装到容器中的事实有关,这通常是不可取的。

我还要说基于使用绑定安装将文件放入构建容器的提议可能不会成功。
见#6697

使用 docker build 运行 -v 可能会有不同的代码执行路径。
我们可以保留卷,而不是在构建期间创建卷并安装它
当前未引用 dockerfiles 中的卷的行为。 和
而是仅在使用 CLI 参数运行时对 -v 执行操作。

上周三,2015年4月8日,布赖恩·高夫[email protected]写道:

@razic https://github.com/razic这与 VOLUME 的事实有关
/foo 实际上创建了一个卷并将其挂载到容器中
构建,这通常是不可取的。

我还要说一个基于使用绑定安装将文件放入的建议
构建容器可能不会飞。
见 #6697 https://github.com/docker/docker/pull/6697


直接回复此邮件或在 GitHub 上查看
https://github.com/docker/docker/issues/6396#issuecomment -90905722。

@cpuguy83感谢您的澄清。

6697 也不会飞,因为它已经关闭了,#10310 实际上是 #6697 的骗局。

+1,我今天刚刚在尝试为使用 Bower 安装客户端依赖项的 Rails 应用程序构建映像时遇到了这个问题。 碰巧其中一个依赖项指向[email protected]:angular/bower-angular-i18n.git并且由于 git 在那里失败,所以 bower 失败,并且映像构建也失败。

顺便说一句,我真的很喜欢 vagrant 所做的事情。 使用 Vagrantfile 中的单个 forward_agent 配置,这可以解决流浪来宾的问题。 Docker 能实现这样的功能吗?

另外,作为附加说明,这是在构建图像时发生的。 有谁知道任何现有的解决方法?

我的解决方法是生成一个新的 RSA 密钥对,在 github 上设置发布密钥(添加指纹),并将私钥添加到 Docker 镜像:

ADD keys/docker_rsa /srv/.ssh/id_rsa

我很想避免这种情况,但我想现在这是可以接受的。 任何其他建议表示赞赏!

我不确定谁杀死了更多的小狗。 您这样做,或者 Docker 尚未为您提供更好的方法。

无论如何,我可能会在本周末提交一份提案。 @cpuguy83是对的,人们至少在考虑这一点并讨论可能的解决方案。 所以在这一点上,这只是我们就某事达成一致并让某人进行处理的问题。 我完全投入了工作,因为它实际上是我目前对 Docker 最大的抱怨之一。

@razic这是一个相当常见的用例,所以也感谢您对此进行调查。 至于解决方法,它有效。 可能key在使用后可以从镜像中删除,毕竟它只是用来从github上获取应用程序的代码。

@fullofcaffeine我不是 100% 确定 Docker 是如何在内部工作的,但我认为除非它是在单个 RUN 命令中完成的(这在您的解决方法中是不可能的),否则映像的历史记录会保留 SSH 密钥。

@razic好点。

为了解决这个限制,我们一直在尝试下载私钥(从本地 HTTP 服务器),运行需要密钥的命令,然后他们删除密钥。

由于我们在单个RUN完成所有这些操作,因此图像中不会缓存任何内容。 这是它在 Dockerfile 中的样子:

RUN ONVAULT npm install --unsafe-perm

我们围绕这个概念的第一个实现可以在https://github.com/dockito/vault 获得

唯一的缺点是需要运行 HTTP 服务器,因此没有构建 Docker 集线器。

让我知道你的想法 :)

+1
希望看到这个实现,这将有助于为开发环境设置容器

+1,只需要使用 boot2dock 转发 ssh-agent

我们最终做了一个 3 步过程来解决这个限制:

  1. 构建没有 SSH 所需依赖项的 docker 容器,在最后一步添加源
  2. 通过共享卷挂载源,加上通过共享卷的 SSH_AUTH_SOCK 并运行构建步骤,将需要 ssh 的输出(例如,github 托管的 ruby​​ gems)写回共享卷
  3. 重新运行 docker build,这将重新触发源添加,因为 gems 现在位于源目录中

结果是一个通过 SSH-auth 拉取依赖的 docker 镜像,其中从来没有 SSH 密钥。

我创建了一个脚本,以便在 OSX 上的 boot2docker 环境中以最小的麻烦为docker run启用 ssh 代理转发。 我知道它不能解决构建问题,但可能对某些人有用:

https://gist.github.com/rcoup/53e8dee9f5ea27a51855

Forward ssh 密钥代理是否与 Amazon EC 2 Container 服务等服务配合使用? 在我看来,这将需要一个特定的软件,该软件可能不适用于您用于部署容器的所有平台或 PaaS。

需要一个更通用的、适用于所有人的解决方案。

目前,我正在使用环境变量。 bash 脚本获取私钥(和已知主机)变量并将其打印到 id_rsa 和 known_hosts 文件。 它有效,但我还没有评估这种解决方案的安全影响。

FWIW,我发现容器化的 ssh-agent 和卷共享可以很好地工作,并且尽量少做傻事:

https://github.com/whilp/ssh-agent

不过,如果有一流的支持,那就太好了。

区分什么在 _run_ 和 _build_ 中起作用很重要。 @whilp的解决方案在 _run_ 中效果很好,但在 _build_ 中不起作用,因为在 _build_ 期间您无法访问其他 docker 的卷。 因此,为什么这张票仍然是一个疼痛的开放性疼痛。

@rvowles是的,同意。 我将一些东西放在一起,通过一系列运行/提交调用(即,没有 Dockerfiles)来生成容器; 这对我的特定用例很有意义,但是对代理转发之类的通用支持(包括构建时间)将非常有帮助。

在构建期间,用于运行容器的 IP 是否包含在 /etc/hosts 中? 如果是这样,一种解决方案可能是启动一个提供密钥的容器,然后在构建期间卷曲到它。

你们可能都有兴趣知道我已经在博客中介绍了在docker build期间使用 SSH 代理的方法 - http://aidanhs.com/blog/post/2015-10-07-dockerfiles-reproducibility-诡计/#_streamlining_your_experience_using_an_ssh_agent

你只需要启动一个容器。 启动后,SSH 代理访问应该可以在 Dockerfile 中仅添加 3 行额外的行就可以正常工作——不再需要将您的密钥暴露给容器。

一些警告:您需要 Docker >= 1.8,并且它不适用于 Docker Hub 自动构建(显然)。 另请阅读安全注意事项! 如果您有任何问题,请随时在我在帖子中链接到的 sshagent github 存储库中提出问题。

我也以与@aidanhs类似的方式解决了这个问题 - 通过在本地 docker 子网上拉取所需的机密,然后在文件系统快照发生之前将其删除。 一个正在运行的容器提供秘密,它是由客户端使用广播 UDP 发现的。
https://github.com/mdsol/docker-ssh-exec

在使这成为可能方面有任何进展吗? 我无法绑定挂载主机的~/.ssh目录,因为权限和所有权被搞砸了。

这难道不能通过允许绑定安装强制特定的 uid/gid 和权限来解决吗?

@atrauzzi bind-mounts 不能强制 uid/gid/permissions。
可以通过 FUSE(例如 bindfs)做到这一点,但不能只使用普通的绑定安装。

@cpuguy83这真的开始让我走上我不想面对的道路。 特别是当我使用基于 Windows 的主机时。

这里没有用户友好的选项吗? 我感觉这里有一个问题只是被推迟了。

@atrauzzi确实,在短期内解决这不是一个容易的问题(无论如何都不是无缝的)。

+1 这对于其他简单的 Node.js 应用程序 Dockerfile 来说是一个很大的障碍。 我已经开发了许多 Node 应用程序,我很少看到一个没有私有 Github 存储库作为 NPM 依赖项的应用程序。

作为一种解决方法@apeace ,您可以尝试将它们作为 git 子模块添加到您的 git 存储库中。 这样它们就在上下文中,您可以在构建期间添加它们,如果您想真正干净地删除或忽略每个文件中的.git文件。 在 docker build 中,它们可以使用本地目录进行安装。 如果由于某种原因他们需要完整的 git 存储库,请确保.git文件不存在于 docker 构建中,并将.git/modules/<repo><path>/<repo>/.git 。 这将确保它们是正常的回购,就像它们被克隆一样。

感谢@jakirkham 的建议,但我们长期以来一直使用私有存储库作为 NPM 依赖项,我不想破坏正常的npm install工作流程。

目前,我们有一个有效但很麻烦的解决方案。 我们有:

  • 创建了一个 Github 用户和团队,该用户和团队对我们用作 NPM 依赖项的存储库具有只读访问权限
  • 将该用户的私钥提交到我们拥有 Dockerfile 的存储库
  • 在 Dockerfile 中,我们使用RUN GIT_SSH='/code/.docker/git_ssh.sh' npm install代替RUN npm install RUN GIT_SSH='/code/.docker/git_ssh.sh' npm install

git_ssh.sh是这样的脚本:

#!/bin/sh
ssh -o StrictHostKeyChecking=no -i /code/.docker/deploy_rsa "$@"

它有效,但转发 ssh 密钥代理会更好,而且设置工作也少很多!

:+1:
无法相信此功能请求仍未实现,因为这里有很多用例,人们需要在构建期间从私有存储库进行访问。

我正在尝试为各种需要访问私有存储库的嵌入式系统开发环境构建容器。 添加对主机 ssh 密钥的支持将是一个很棒的功能。 在 SO 和其他页面上运行的最流行的方法是不安全的,只要不支持此功能层,私钥就会四处传播。

:+1:

:+1: 一直需要这个。

@apeace ,我不知道你是否看过它,但我之前已经评论过我们解决这个问题的方法。

它是脚本和 Web 服务器的组合。 你怎么看https://github.com/dockito/vault

@pirelenito不会使密钥在构建层中仍然可用吗? 如果是这种情况,我们就不值得将 Dockito Valut 添加到我们的构建过程中——这对我来说就像我们现在所做的一样“笨拙”。 我很欣赏这个建议!

@apeace ONVAULT脚本下载密钥,运行您的命令,然后立即删除密钥。 由于这一切都发生在同一个命令中,因此最后一层将不包含密钥。

@apeace在 Medidata,我们正在使用我们构建的一个名为docker-ssh-exec的小工具。 它只在生成的构建映像中留下docker-ssh-exec二进制文件——没有秘密。 并且它只需要对Dockerfile进行一个单词的更改,因此它非常“低足迹”。

但是,如果您_真的_需要使用 docker-native-only 解决方案,那么现在有一种内置方法可以做到这一点,如公司博客文章中所述。 Docker 1.9 允许您使用--build-arg参数将临时值传递给构建过程。 您应该能够将私有 SSH 密钥作为ARG传入,将其写入文件系统,执行git checkout ,然后 _delete_ 密钥,所有这些都在RUN的范围内docker-ssh-exec客户端所做的)。 这将产生一个丑陋的Dockerfile ,但应该不需要外部工具。

希望这可以帮助。

@benton我们提出了一个类似的解决方案。 :)

谢谢@pirelenito@benton ,我会看看你所有的建议!

编辑:以下是 _NOT_ 安全的,事实上:

作为记录,以下是您如何从 Github 检出私有存储库而不将 SSH 密钥留在生成的图像中。

首先,将以下Dockerfile user/repo-name中的user/repo-name您的私有仓库的路径(确保保留[email protected]前缀,以便 ssh 用于结帐):

FROM ubuntu:latest

ARG SSH_KEY
ENV MY_REPO [email protected]:user/repo-name.git

RUN apt-get update && apt-get -y install openssh-client git-core &&\
    mkdir -p /root/.ssh && chmod 0700 /root/.ssh && \
    ssh-keyscan github.com >/root/.ssh/known_hosts

RUN echo "$SSH_KEY" >/root/.ssh/id_rsa &&\
    chmod 0600 /root/.ssh/id_rsa &&\
    git clone "${MY_REPO}" &&\
    rm -f /root/.ssh/id_rsa

然后使用命令构建

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

将正确的路径传递给您的私人 SSH 密钥。

^ 使用 Docker 1.9

@benton您可能想仔细查看docker inspect sshtestdocker history sshtest 。 我认为您会发现最终图像中的元数据具有您的秘密,即使它在容器上下文本身内不可用...

@ljrittle很好的发现。 如果您使用VAR ,则密钥确实存在。 我想这里仍然需要外部解决方法。

可能尚未开发出本机解决方案的一个原因是一些变通方法 _are_ 到位。 但我同意这里的大多数其他人的观点,即内置解决方案可以更好地为用户服务,并且符合 Docker 的“包含电池”的理念。

从文档...

注意:不建议使用构建时变量来传递 github 密钥、用户凭据等秘密。

( https://docs.docker.com/engine/reference/builder/#arg )

我不认为文件路径适用于此,注释是关于在控制台日志中设置简单可见的密码/令牌。

我不关注@jcrombez。 该示例是通过ARG将 ssh 密钥作为变量传递。 所以,它确实适用。

在安全风险方面,这是非常不同的:

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

比这个 :

docker build --tag=sshtest --build-arg SSH_KEY="mykeyisthis" .

如果有人找到你的终端日志,结果就不一样了。
但我不是安全专家,由于其他一些我不知道的原因,这可能仍然很危险。

在命令行上,我想。

但是,正如@ljrittle指出的和@benton承认的那样,您使用--build-arg / ARG任何方式都将在构建中提交。 因此,检查它将揭示有关密钥的信息。 两者都在最终的 docker 容器中离开状态,并且在这方面都遭受相同的漏洞。 因此,为什么 docker 建议不要这样做。

_用户投票_

_获得更新通知的最佳方式是使用此页面上的_订阅_按钮。_

请不要对问题使用“+1”或“我也有这个”评论。 我们自动
收集这些评论以保持主题简短。

下面列出的人通过留下 +1 评论对该问题进行了投票:

@弗莱彻91
@benlemasurier
@dmuso
@probepark
@萨达
@ianAndrewClark
@jakirkham
@galindro
@luisguilherme
@阿库金
@allardhoeve
@SevaUA
@sankethkatta
@kouk
@cliffxuan
@kotlas92
@taion

_用户投票_

_获得更新通知的最佳方式是使用此页面上的_订阅_按钮。_

请不要对问题使用“+1”或“我也有这个”评论。 我们自动
收集这些评论以保持主题简短。

下面列出的人通过留下 +1 评论对该问题进行了投票:

@帕尼克
@杜斯克
@adambiggs

在安全风险方面,这是非常不同的:

docker build --tag=sshtest --build-arg SSH_KEY="$(cat ~/.ssh/path-to-private.key)" .

除了你的 bash 历史,它们完全一样; 这些信息可以在很多地方结束。

例如,考虑可以在服务器上记录 API 请求;

这是docker build --tag=sshtest --build-arg SSH_KEY="fooobar" .的守护进程日志

DEBU[0090] Calling POST /v1.22/build
DEBU[0090] POST /v1.22/build?buildargs=%7B%22SSH_KEY%22%3A%22fooobar%22%7D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&memory=0&memswap=0&rm=1&shmsize=0&t=sshtest&ulimits=null
DEBU[0090] [BUILDER] Cache miss: &{[/bin/sh -c #(nop) ARG SSH_KEY]}
DEBU[0090] container mounted via layerStore: /var/lib/docker/aufs/mnt/de3530a82a1a141d77c445959e4780a7e1f36ee65de3bf9e2994611513790b8c
DEBU[0090] container mounted via layerStore: /var/lib/docker/aufs/mnt/de3530a82a1a141d77c445959e4780a7e1f36ee65de3bf9e2994611513790b8c
DEBU[0090] Skipping excluded path: .wh..wh.aufs
DEBU[0090] Skipping excluded path: .wh..wh.orph
DEBU[0090] Applied tar sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef to 91f79150f57d6945351b21c9d5519809e2d1584fd6e29a75349b5f1fe257777e, size: 0
INFO[0090] Layer sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef cleaned up

_用户投票_

_获得更新通知的最佳方式是使用此页面上的_订阅_按钮。_

请不要对问题使用“+1”或“我也有这个”评论。 我们自动
收集这些评论以保持主题简短。

下面列出的人通过留下 +1 评论对该问题进行了投票:

@cj2

我正在尝试容器化一个简单的 ruby​​/rack 应用程序。 Gemfile 引用了几个私有 gem。 bundle install启动并尝试访问私有存储库的那一刻,我开始收到此错误

Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

我能够解决它,但不能不暴露我的私钥。 那不行。 请启用 ssh 身份验证转发。

+1 用于构建期间的 ssh 转发。 因为它,不能将go get与私人回购一起使用;(

+1 以安全的方式启用此用例

_用户投票_

_获得更新通知的最佳方式是使用此页面上的_订阅_按钮。_

请不要对问题使用“+1”或“我也有这个”评论。 我们自动
收集这些评论以保持主题简短。

下面列出的人通过留下 +1 评论对该问题进行了投票:

@lukad

刚刚阅读了这个非常有趣的讨论,我想知道一个简单的解决方案是否可以解决这些问题。 我在想,Dockerfile 中的一个选项可以在拍摄快照时排除/忽略特定的内部目录/文件。 这有多难?

IE

排除 .ssh

我认为它将适用于随后的所有步骤,因此如果您将它放在 FROM 之后,那么您可以随心所欲地添加密钥并正常构建,而不必担心密钥意外地出现在您的图像中(授予您可能需要在需要它们的每一步都添加它们,但您不必担心它们最终会出现在图像中)

@benton的建议工作正常,如果 id_rsa 键处于调试模式,

在构建期间暴露密钥的更可爱的方法是:

# Dockerfile
ARG SSH_KEY
RUN eval `ssh-agent -s` > /dev/null \
    && echo "$SSH_KEY" | ssh-add - \
    && git clone [email protected]:private/repository.git

docker build -t my_tag --build-arg SSH_KEY="$(< ~/.ssh/id_rsa)" .

哈,虽然它确实只是坐在那里,如果你看docker inspect my_tag .. 所以不确定 boot-arg 的真正价值是什么,除了比 ENV 稍微整洁一些。

而且,如果您在 id_rsa 密钥上有密码,我猜您可能是个坏人,并执行以下操作:

# Dockerfile
ARG SSH_KEY
ARG SSH_PASS
RUN eval `ssh-agent -s` > /dev/null \
    && echo "echo $SSH_PASS" > /tmp/echo_ps && chmod 700 /tmp/echo_ps \
    && echo "$SSH_KEY" | SSH_ASKPASS=/tmp/echo_ps DISPLAY= ssh-add - \
    && git clone [email protected]:private/repository.git
    && rm /tmp/echo_ps

docker build -t my_tag --build-arg SSH_KEY="$(< ~/.ssh/id_rsa)" --build-arg SSH_PASS=<bad_idea> .

当然,很难将哪怕是一点点的好主意合理化……但我想我们都是人。

诚然,这样做的最大原因似乎是人们在构建期间对私有存储库进行“捆绑安装”或“获取”。

我会说只是提供您的依赖项并添加整个项目..但是,有时需要立即完成。

@SvenDowideit @thaJeztah这个问题有什么解决方案吗? 我试图跟随线程,但在关闭和打开另一个线程之间以及很多意见之间我不知道 Docker 团队会做什么或什么时候做。

最好的,但需要实施?

Docker 构建在构建中使用 ssh-agent 代理到您主机的 ssh,然后使用您的密钥而无需知道它们!

对于任何刚刚了解 ssh-agent 代理的人: github 救援

@phemmer的原始想法。

@yordis我认为线程中还没有免费提供的“出色”解决方案。

来自 docker/docker-py#980 的这条评论似乎表明,如果您将 ssh 密钥复制到主机系统上根用户的密钥目录中,守护程序将使用这些密钥。 然而,我在这方面很疯狂,所以其他人可能能够澄清。


好的,但不是最好的

使用 docker 1.8 的构建参数传递密钥。
注意事项

绝对是个坏主意

很多人也在这里建议将密钥临时添加到构建上下文中,然后快速删除它。 听起来很危险,因为如果密钥潜入其中一个提交中,任何使用容器的人都可以通过检查特定提交来访问该密钥。


为什么这还没有消失?

它需要一个设计方案,这个问题是_cah_- _luttered_,目前想法还很模糊。 实际的实现细节正在迷失在“如果我们做了 x 会怎样”和 +1 的迷雾中。 为了组织起来并继续推进这个急需的功能,那些有可能解决方案的人应该创建一个 . . .

设计方案

然后参考这个问题。

我有一些关于这个问题的消息。

在上周的 DockerCon 上,我们被鼓励将最难的问题带到 Docker 的“咨询专家”展区,所以我过去与一位聪明而友好的工程师进行了简短的交谈,并获得了令人鼓舞的标题解决方案架构师。 我给了他一个关于这个问题的简短总结,我希望我能准确传达,因为他向我保证这可以用 _only_ docker-compose ! 他提议的细节涉及多阶段构建——可能是在与最终应用程序构建不同的上下文中积累依赖项——并且似乎涉及在构建时使用数据量。

不幸的是,我对 docker-compose 没有经验,所以我无法了解所有细节,但他向我保证,如果我写信给他确切的问题,他会回复一个解决方案。 所以我写了一封我希望

我敢肯定他很忙,所以我不希望立即有任何事情发生,但是我发现这令人鼓舞,因为他已经理解了问题,并且准备仅使用 docker 本地工具集进行攻击。

@benton我使用

version: '2'
services:
  serviceName:
     volumes:
      - "${SSH_AUTH_SOCK}:/tmp/ssh-agent"
    environment:
      SSH_AUTH_SOCK: /tmp/ssh-agent

确保 ssh-agent 在主机上启动并知道密钥(您可以使用 ssh-add -L 命令检查它)。

请注意,您可能需要添加

Host *
  StrictHostKeyChecking no

到容器的 .ssh/config。

嗨@WoZ! 谢谢你的回答,看起来很简单,所以我会试一试:)

不过我有一个问题,你如何在 docker hub 中使用它进行自动构建? 就我而言,现在无法在那里使用撰写文件:(

@garcianavalon效果很好,但仅适用于run ,而不适用于build 。 还没有使用 Docker for Mac,尽管它显然在待办事项列表中。

编辑: https :

我们针对我们的特定需求提出了另外两种解决方法:

1) 在我们的 VPN 后面为 npm、pypi 等设置我们自己的包镜像,这样我们就不需要 SSH。

2)我们已经可以访问私有repos的所有主机,所以我们在本地克隆/下载私有包到主机,运行它的包安装来下载它,然后使用-v将卷映射到docker,然后构建docker。

我们目前正在使用选项 2)。

至于docker rundocker-ssh-agent-forward似乎提供了一个优雅的解决方案,并且可以跨 Docker for Mac/Linux 工作。

从主机复制known_hosts文件而不是在容器中创建它可能仍然是一个好主意(不太安全),因为 ssh-agent 似乎没有转发已知主机。

但是在 docker run 步骤期间拉取私有依赖项的根本问题是绕过 docker 构建缓存,这在构建时间方面可能非常重要。

解决此限制的一种方法是 md5/date 您的构建依赖项声明(例如package.json ),将结果推送到图像并在文件未更改时重用相同的图像。 在图像名称中使用哈希将允许缓存多个状态。 它也必须与预安装映像摘要结合使用。

这应该比@aidanhs的构建服务器解决方案更强大,尽管我仍然需要大规模测试它。

这应该比@aidanhs的构建服务器解决方案更强大,尽管我仍然需要大规模测试它。

我的特定解决方案自 1.9.0 起就不起作用了 - 结果证明我所依赖的 1.8.0 中引入的功能不是故意的,所以它被删除了。

虽然我的解决方案的原则仍然很好(它只需要你的机器上有一个 DNS 服务器,a)你的机器使用 b)你可以将条目添加到适当的位置),我不能说我很热情再推荐一下。

感谢您提供额外信息@aidanhs!

关于我提出的解决方案的一些更新:散列实际上不需要组合,因为可以简单地使用添加依赖项声明文件后的基本映像的散列。 此外,最好将 known_host 文件简单地挂载为一个卷,因为 ssh-agent 无论如何只能在运行时使用——而且更安全,因为它包含您连接到的所有主机的列表。

我为 node/npm 实现了完整的解决方案,可以在这里找到详细的文档和示例: https :

当然,这些原则可以扩展到其他框架。

同样的问题,一个人如何构建某些东西,其中某些东西需要 SSH 凭据,以便在构建时在 docker 容器内检查和构建多个项目,而无需将凭据写入映像或基础映像。

我们通过两步构建过程来解决这个问题。 创建包含源/密钥/构建依赖项的“构建”映像。 一旦构建完成,它就会运行以将构建结果提取到一个 tarfile 中,然后将其添加到“部署”映像中。 然后删除构建映像,发布的所有内容都是“部署”映像。 这有一个很好的副作用,可以降低容器/层的大小。

@binarytemple-bet365 请参阅https://github.com/iheartradio/docker-node的端到端示例。 当我使用 ssh 服务容器时,我使用了两个以上的步骤,预安装(安装私有依赖项之前的基础映像)、安装(私有依赖项运行时安装后的容器状态)和安装后(添加安装后的命令)私有依赖项)以优化速度和关注点分离。

查看Rocker ,这是一个干净的解决方案。

@Sodki我接受了你的建议。 是的, rocker是一个干净且经过深思熟虑的解决方案。 更令人遗憾的是 docker 团队不会将这个项目置于他们的翼下并弃用docker build 。 谢谢你。

还是没有更好的办法? :(

有人试过这种新的壁球吗? https://github.com/docker/docker/pull/22641可能是我们正在寻找的 docker 原生解决方案。 现在就去试试,然后回来报告看看进展如何。

超过 2 年,这还没有修复 😞 请 Docker 团队做点什么

看起来 1.13 中的新--squash选项对我有用:
http://g.recordit.co/oSuMulfelK.gif

我用: docker build -t report-server --squash --build-arg SSH_KEY="$(cat ~/.ssh/github_private_key)" .构建它

因此,当我执行docker historydocker inspect ,密钥不会显示。

我的 Dockerfile 看起来像这样:

FROM node:6.9.2-alpine

ARG SSH_KEY

RUN apk add --update git openssh-client && rm -rf /tmp/* /var/cache/apk/* &&\
  mkdir -p /root/.ssh && chmod 0700 /root/.ssh && \
  ssh-keyscan github.com > /root/.ssh/known_hosts

RUN echo "$SSH_KEY" > /root/.ssh/id_rsa &&\
  chmod 0600 /root/.ssh/id_rsa

COPY package.json .

RUN npm install
RUN rm -f /root/.ssh/id_rsa

# Bundle app source
COPY . .

EXPOSE 3000

CMD ["npm","start"]

@kienpham2000 ,您的屏幕截图看起来仍然包含密钥-您能否检查带有--no-trunc标志的docker history的输出,并在此处报告私钥是否显示在 docker 中历史?

@ryanschwartz你是对的, --no-trunc显示了整个该死的东西,这不会飞。

@kienpham2000
他们在 1.13 版本中引入的另一件事是:

建立秘密
• 使用 —build-secret 标志启用构建时机密
• 在构建期间创建 tmpfs,并将秘密暴露给
构建容器,在构建过程中使用。
https://github.com/docker/docker/pull/28079

也许这可以工作?

Build secrets 没有进入 1.13,但希望会在 1.14 中完成。

2016 年 12 月 15 日上午 9:45,“亚历克斯”通知@github.com写道:

@kienpham2000 https://github.com/kienpham2000
他们在 1.13 版本中引入的另一件事是:

建立秘密
• 使用 —build-secret 标志启用构建时机密
• 在构建期间创建 tmpfs,并将秘密暴露给
构建容器,在构建过程中使用。
• #28079 https://github.com/docker/docker/pull/28079

也许这可以工作?


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/docker/docker/issues/6396#issuecomment-267393020或静音
线程
https://github.com/notifications/unsubscribe-auth/AAdcPDxrctBP2TlCtXen-Y_uY8Y8B09Sks5rIXy2gaJpZM4CD4SM
.

所以一年后:不,这是一个坏主意。 你不应该那样做。 还有各种其他解决方案。 例如,Github 可以提供访问令牌。 您可以在风险较小的配置文件/环境变量中使用它们,因为您可以指定每个令牌允许哪些操作。

解决办法是实现SSH转发。 比如 Vagrant 就是这样做的。

有人能解释一下为什么实现它如此复杂吗?

@omarabid - 您是否在回复您最初提出的使用环境变量传递要在 Dockerfile 中使用的私钥的建议? 毫无疑问,这是一种糟糕的安全做法。

至于您使用访问令牌的建议,它们最终会存储在一个层中,并且与 SSH 密钥一样放置在周围也是危险的。 即使它只有只读访问权限,大多数人也不希望其他人对他们的存储库具有只读访问权限。 此外,需要频繁撤销/轮换/分发; 这对于每个开发人员等来说更容易处理,而不是使用“主”访问令牌。

build secrets 解决方案提到了一些评论,看起来这是朝着正确方向迈出的一步,但使用 SSH 代理的能力是最好的。 也许可以将 SSH 代理与构建机密结合使用,我不确定。

开发人员/CI 系统在 git/build 操作期间使用 SSH 代理是很自然的。 这比拥有必须在各种系统中集体撤销/替换的纯文本、无密码私钥安全得多。 此外,使用 SSH 代理,私钥数据不可能提交到图像。 在最坏的情况下,环境变量/SSH_AUTH_SOCK 残余将留在图像中。

我在没有显示密钥内容或使用额外的 3rd 方 docker 工具的情况下获得了这个最新的解决方法(希望构建 PR 期间的秘密库将很快合并)。

我正在使用 aws cli 将共享私钥从 S3 下载到主机当前存储库中。 此密钥使用 KMS 进行静态加密。 下载密钥后,Dockerfile 将在构建过程中复制该密钥,然后将其删除,内容不会显示在docker inspectdocker history --no-trunc

先从S3下载github私钥到宿主机:

# build.sh
s3_key="s3://my-company/shared-github-private-key"
aws configure set s3.signature_version s3v4
aws s3 cp $s3_key id_rsa --region us-west-2 && chmod 0600 id_rsa

docker build -t app_name .

Dockerfile 看起来像这样:

FROM node:6.9.2-alpine

ENV id_rsa /root/.ssh/id_rsa
ENV app_dir /usr/src/app

RUN mkdir -p $app_dir
RUN apk add --update git openssh-client && rm -rf /tmp/* /var/cache/apk/* && mkdir -p /root/.ssh && ssh-keyscan github.com > /root/.ssh/known_hosts

WORKDIR $app_dir

COPY package.json .
COPY id_rsa $id_rsa
RUN npm install && npm install -g gulp && rm -rf $id_rsa

COPY . $app_dir
RUN rm -rf $app_dir/id_rsa

CMD ["start"]

ENTRYPOINT ["npm"]

@kienpham2000 ,为什么这个解决方案不会将密钥保存在图像层中? 复制和删除密钥的操作是在单独的命令中完成的,因此应该有一个包含密钥的层。
直到昨天,我们的团队一直在使用您的解决方案,但我们找到了改进的解决方案:

  • 我们使用aws s3 cli生成一个预签名URL来访问密钥,并限制访问大约5分钟,我们将这个预签名URL保存到repo目录中的一个文件中,然后在dockerfile中我们将其添加到图像中。
  • 在 dockerfile 中,我们有一个 RUN 命令执行所有这些步骤:使用 pre-sing URL 获取 ssh 密钥,运行 npm install 并删除 ssh 密钥。
    通过在单个命令中执行此操作,ssh 密钥不会存储在任何层中,但会存储预签名 URL,这不是问题,因为 URL 在 5 分钟后将无效。

构建脚本如下所示:

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile 看起来像这样:

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no [email protected] || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]

@diegocsandrim感谢您指出这一点,我真的很喜欢您的解决方案,将在这里更新我们的内容。 感谢分享!

我对这个线程有点陌生,但从根本上说,人们似乎正试图解决一个由 PKI 更好地解决的问题。 并非每个人都必须尝试解决相同的问题,而 PKI 将是更好的解决方案,但足够的参考似乎表明它可能是应该考虑的问题。

看起来很烦人,但基本上可以

  • 创建本地证书颁发机构
  • 有一个生成证书的过程
  • 有一个颁发证书的过程
  • 有一个撤销上述证书的过程
  • 让 ssh 守护进程使用 PKI

如果人们觉得这是可行的,那么请务必创建它并开源它,毕竟工作需要做好一次。 我不知道 roumen petrov 构建是否安全并且没有记录任何源代码(没有检查 tar),所以我不知道它有多安全。

https://security.stackexchange.com/questions/30396/how-to-set-up-openssh-to-use-x509-pki-for-authentication

https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

@mehmetcodes :拥有 PKI 并不能真正解决问题。 要使基于 PKI 的 SSH 身份验证起作用,您仍需要将私钥加载到映像中。

除非您的本地证书颁发机构颁发有效期很短的证书(例如,不到一个小时),并且您在成功构建后立即撤销证书,否则这是不安全的。

如果您设法创建短期证书流程,这与仅使用在构建完成后立即撤销的新 SSH 密钥没有太大区别。

哦,这比那更烦人,但我必须在做某事,否则为什么它会存在于野外?

https://blog.cloudflare.com/red-october-cloudflares-open-source-implementation-of-the-two-man-rule/
https://blog.cloudflare.com/how-to-build-your-own-public-key-infrastructure/

我不知道,对于大多数用例来说,SSH 临时密钥可能要好得多,但是每个资源都有一些令人不安的地方,包括我建议的资源,特别是在这种情况下。

您通常只需使用密钥安装卷,但这无助于需要 docker for Mac / moby 解决方案。

谁……是moby?

@whitecolor
Image of Moby

我在 MacOS 上做到了这一点:

bash-3.2$ docker run -t -i -v "$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" python:3.6 ssh-add -l
docker: Error response from daemon: Mounts denied:
The path /var/folders/yb/880w03m501z89p0bx7nsxt580000gn/T//ssh-DcwJrLqQ0Vu1/agent.10466
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.
.

/var/ 是一个别名,Docker 似乎在努力解决这个问题。 但是,如果我在 $SSH_AUTH_SOCK 路径前加上/private (即解析的别名路径),那么 Docker 可以读取该文件,但我得到:

bash-3.2$ docker run -t -i -v "/private$SSH_AUTH_SOCK:/tmp/ssh_auth_sock" -e "SSH_AUTH_SOCK=/tmp/ssh_auth_sock" python:3.6 ssh-add -l
Could not open a connection to your authentication agent.

在这一点上,我想知道这有多糟糕……

docker run -v ~/.ssh:/root/.ssh python:3.6 bash

?

docker build  --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa_no_pass)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" --squash .

然后在 Docker 文件中:

ARG ssh_prv_key
ARG ssh_pub_key

# Authorize SSH Host
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts

# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub

并且不要忘记包括

RUN rm -f /root/.ssh/id_rsa /root/.ssh/id_rsa.pub

作为最后一步。

这里的问题是您的私钥不应该受密码保护。

上一条评论的问题是键最终出现在层中...... rm 不会从前一层中删除,因为 docker 文件中的每一行都是一层..

docker secret不能解决这个问题吗?
WDYT @thaJeztah

docker secret 在构建过程中(还)不可用,并且只在服务中可用(所以还没有用于docker run

当使用多阶段构建时,这样的东西可以工作(在我的手机上打字,所以让我链接我不久前创建的要点); https://gist.github.com/thaJeztah/836c4220ec024cf6dd48ffa850f07770

我不再涉及 Docker,但是,这个问题怎么可能存在这么长时间。 我并不是要大声疾呼,而是不了解解决这个问题需要付出什么努力,因为在我处理这个问题的时候,对于任何从ruby gems私人回购。

Moby关心这个问题吗? 我想为什么对于看起来没什么大不了的事情来说,它必须如此困难。

已经快3年了😢

@yordis docker builder 被冻结了一两年。 Docker 团队表示 builder 已经足够好了,他们将精力集中在其他地方。 但这已经消失了,从那以后对 builder 进行了两次更改。 壁球和 mustli 阶段构建。 因此,构建时的秘密可能正在酝酿之中。

对于 ssh-agent 的运行时转发,我会推荐https://github.com/uber-common/docker-ssh-agent-forward

我想为什么对于看起来没什么大不了的事情来说,它必须如此困难。

@yordis阅读了这个问题的顶级描述,实现这一点buildkit项目,以便将来对构建器进行增强; https://github.com/moby/buildkit

@thaJeztah我希望我能拥有所需的技能,但我没有。

@villem你知道 Docker 团队的路线图吗?

可以在此处找到建筑商的每周报告; https://github.com/moby/moby/tree/master/reports/builder build time secrets 仍在最新报告中列出,但可以使用帮助

我们正在使用@diegocsandrim的解决方案,但有一个中间加密步骤,以避免在 S3 中留下未加密的 SSH 密钥。

这个额外的步骤意味着无法从 Docker 映像中恢复密钥(下载它的 URL 会在五分钟后过期)并且无法从 AWS 中恢复(因为它是用只有 docker 映像知道的轮换密码加密的) .

在 build.sh 中:

BUCKET_NAME=my_bucket
KEY_FILE=my_unencrypted_key
openssl rand -base64 -out passfile 64
openssl enc -aes-256-cbc -salt -in $KEY_FILE -kfile passfile | aws s3 cp - s3://$BUCKET_NAME/$(hostname).enc_key
aws s3 presign s3://$BUCKET_NAME/$(hostname).enc_key --expires-in 300 > ./pre_sign_url
docker build -t my_service

在 Dockerfile 中:

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - | openssl enc -aes-256-cbc -d -kfile passfile > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    mkdir /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts && \
    [commands that require SSH access to Github] && \
    rm ./my_key && \
    rm ./passfile && \
    rm -rf /root/.ssh/

如果您使用的是docker run您应该使用--mount type=bind,source="${HOME}/.ssh/",target="/root/.ssh/",readonly挂载您的 .ssh。 readonly 很神奇,它屏蔽了正常的权限,ssh 基本上可以看到它满意的 0600 权限。 您还可以使用-u root:$(id -u $USER)来让容器中的 root 用户写入它创建的与您的用户在同一组中的任何文件,因此希望您至少可以读取它们,如果没有完全写入它们而不必 chmod/chown .

最后。

我相信这个问题现在可以通过使用多阶段构建仅使用docker build来解决。
只需COPYADD SSH 密钥或其他任何您需要的秘密,然后在RUN语句中随意使用它。

然后,使用第二个FROM语句启动一个新的文件系统,并使用COPY --from=builder导入一些不包含 secret的目录子集。

(我还没有真正尝试过这个,但如果该功能按描述工作......)

@benton多阶段构建按照描述工作,我们使用它。 到目前为止,它是许多不同问题的最佳选择,包括这个问题。

我已经验证了以下技术:

  1. 将私钥的 _location_ 作为构建参数(例如GITHUB_SSH_KEY )传递到多阶段构建的第一阶段
  2. 使用ADDCOPY将密钥写入需要进行身份验证的任何位置。 请注意,如果密钥位置是本地文件系统路径(而不是 URL),则它必须_not_位于.dockerignore文件中,否则COPY指令将不起作用。 这对最终图像有影响,您将在第 4 步中看到...
  3. 根据需要使用密钥。 在下面的示例中,密钥用于向 GitHub 进行身份验证。 这也适用于 Ruby 的bundler和私有 Gem 存储库。 根据此时您需要包含多少代码库,您最终可能会再次添加密钥作为使用COPY .ADD .的副作用。
  4. 必要时取下钥匙。 如果关键位置是本地文件系统路径(而不是 URL),那么它很可能是在您执行ADD .COPY .时与代码库一起添加的。这可能是_确切地说是目录_将被复制到最终的运行时映像中,因此您可能还希望在使用完密钥后包含RUN rm -vf ${GITHUB_SSH_KEY}语句。
  5. 一旦您的应用程序完全构建到它的WORKDIR ,使用新的FROM语句开始第二个构建阶段,指示您所需的运行时映像。 安装任何必要的运行时依赖项,然后从第一阶段对WORKDIR安装COPY --from=builder

这是演示上述技术的示例Dockerfile 。 提供GITHUB_SSH_KEY构建参数将在构建时测试 GitHub 身份验证,但关键数据将_不_包含在最终运行时映像中。 GITHUB_SSH_KEY可以是文件系统路径(在 Docker 构建目录中)或提供密钥数据的 URL,但在此示例中密钥本身不得加密。

########################################################################
# BUILD STAGE 1 - Start with the same image that will be used at runtime
FROM ubuntu:latest as builder

# ssh is used to test GitHub access
RUN apt-get update && apt-get -y install ssh

# The GITHUB_SSH_KEY Build Argument must be a path or URL
# If it's a path, it MUST be in the docker build dir, and NOT in .dockerignore!
ARG GITHUB_SSH_KEY=/path/to/.ssh/key

  # Set up root user SSH access for GitHub
ADD ${GITHUB_SSH_KEY} /root/.ssh/id_rsa

# Add the full application codebase dir, minus the .dockerignore contents...
# WARNING! - if the GITHUB_SSH_KEY is a file and not a URL, it will be added!
COPY . /app
WORKDIR /app

# Build app dependencies that require SSH access here (bundle install, etc.)
# Test SSH access (this returns false even when successful, but prints results)
RUN ssh -o StrictHostKeyChecking=no -vT [email protected] 2>&1 | grep -i auth

# Finally, remove the $GITHUB_SSH_KEY if it was a file, so it's not in /app!
# It can also be removed from /root/.ssh/id_rsa, but you're probably not going
# to COPY that directory into the runtime image.
RUN rm -vf ${GITHUB_SSH_KEY} /root/.ssh/id*

########################################################################
# BUILD STAGE 2 - copy the compiled app dir into a fresh runtime image
FROM ubuntu:latest as runtime
COPY --from=builder /app /app

GITHUB_SSH_KEY构建参数中传递密钥数据本身_可能_更安全,而不是传递密钥数据的 _location_。 如果密钥数据存储在本地文件中,然后添加COPY .这将防止意外包含密钥数据。 但是,这需要使用echo和 shell 重定向将数据写入文件系统,这可能不适用于所有基本映像。 对您的一组基本图像使用最安全和最可行的技术。

@jbiel又一年,我找到的解决方案是使用 Vault 之类的东西。

这是包含 2 个方法的链接(@benton 之前描述的壁球和中间容器)

我只是添加了一条注释,说明如果您在使用的 ssh 密钥上有密码,当前的任何方法都不起作用,因为每当您执行需要访问的操作时,代理都会提示您输入密码。 我不认为有办法解决这个问题而不传递关键短语(出于多种原因,这是不可取的)

解决。
创建 bash 脚本(~/bin/docker-compose 或类似):

#!/bin/bash

trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &

/usr/bin/docker-compose $@

在 Dockerfile 中使用 socat:

...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
  && apk add --no-cache socat openssh \
  && /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
  && bundle install \
...
or any other ssh commands will works

然后运行docker-compose build

@benton你为什么使用RUN rm -vf ${GITHUB_SSH_KEY} /root/.ssh/id* ? 不应该只是RUN rm -vf /root/.ssh/id*吗? 或者也许我误解了这里的意图。

@benton而且这样做也不安全:

RUN ssh -o StrictHostKeyChecking=no -vT [email protected] 2>&1

你必须检查指纹

我通过这种方式解决了这个问题

ARGS USERNAME
ARGS PASSWORD
RUN git config --global url."https://${USERNAME}:${PASSWORD}@github.com".insteadOf "ssh://[email protected]"

然后用

docker build --build-arg USERNAME=use --build-arg PASSWORD=pwd. -t service

但首先,您的私有 git 服务器必须支持username:password克隆存储库。

@zeayes RUN 命令存储在容器历史记录中。 因此您的密码对其他人可见。

正确的; 使用--build-arg / ARG ,这些值将显示在构建历史中。 如果您使用多阶段构建_并且_信任构建图像的主机(即,没有不受信任的用户可以访问本地构建历史),_并且_中间构建阶段不会被推送到注册表,则可以使用此技术。

例如,在以下示例中, USERNAMEPASSWORD只会出现在第一阶段(“builder”)的历史记录中,而不会出现在最后阶段的历史记录中;

FROM something AS builder
ARG USERNAME
ARG PASSWORD
RUN something that uses $USERNAME and $PASSWORD

FROM something AS finalstage
COPY --from= builder /the/build-artefacts /usr/bin/something

如果仅将最终映像(由“finalstage”生成)推送到注册表,则USERNAMEPASSWORD将不会出现在该映像中。

_然而_,在本地构建缓存历史中,这些变量仍然存在(并以纯文本形式存储在磁盘上)。

下一代构建器(使用BuildKit )将具有更多功能,也与传递构建时机密有关; 它在 Docker 18.06 中作为实验性功能可用,但将在未来版本中脱离实验性,并且将添加更多功能(我必须检查当前版本中是否已经可以使用机密/凭据)

@kinnalru @thaJeztah谢谢,我使用多阶段构建,但是可以在缓存容器的历史记录中看到密码,谢谢!

@zeayes哦! 我看到我做了一个复制/粘贴错误; 最后阶段不得使用FROM builder .. 。 这是一个完整的例子; https://gist.github.com/thaJeztah/a​​f1c1e3da76d7ad6ce2abab891506e50

@kinnalru 的这条评论是正确的做法https://github.com/moby/moby/issues/6396#issuecomment -348103398

使用这种方法,docker 永远不会处理您的私钥。 它今天也可以使用,无需添加任何新功能。

我花了一段时间才弄明白,所以这里有一个更清晰、更完善的解释。 我将@kinnalru代码更改为使用--network=hostlocalhost ,因此您无需知道您的 IP 地址。 (要点在这里

这是docker_with_host_ssh.sh ,它包装了 docker 并将SSH_AUTH_SOCK转发到本地主机上的端口:

#!/usr/bin/env bash

# ensure the processes get killed when we're done
trap 'kill $(jobs -p)' EXIT

# create a connection from port 56789 to the unix socket SSH_AUTH_SOCK (which is used by ssh-agent)
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &
# Run docker
# Pass it all the command line args ($@)
# set the network to "host" so docker can talk to localhost
docker $@ --network='host'

在 Dockerfile 中,我们通过 localhost 连接到主机 ssh-agent:

FROM python:3-stretch

COPY . /app
WORKDIR /app

RUN mkdir -p /tmp

# install socat and ssh to talk to the host ssh-agent
RUN  apt-get update && apt-get install git socat openssh-client \
  # create variable called SSH_AUTH_SOCK, ssh will use this automatically
  && export SSH_AUTH_SOCK=/tmp/auth.sock \
  # make SSH_AUTH_SOCK useful by connecting it to hosts ssh-agent over localhost:56789
  && /bin/sh -c "socat UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:localhost:56789 &" \
  # stuff I needed my ssh keys for
  && mkdir -p ~/.ssh \
  && ssh-keyscan gitlab.com > ~/.ssh/known_hosts \
  && pip install -r requirements.txt

然后你可以通过调用脚本来构建你的图像:

$ docker_with_host_ssh.sh build -f ../docker/Dockerfile .

@cowlicks你可能对这个 pull request 感兴趣,它增加了对docker build --ssh支持,以便在构建期间转发 SSH 代理; https://github.com/docker/cli/pull/1419。 Dockerfile 语法仍然不在官方规范中,但您可以在 Dockerfile 中使用syntax=..指令来使用支持它的前端(请参阅拉取请求中的示例/说明)。

该拉取请求将成为即将发布的 18.09 版本的一部分。

看起来这现在在 18.09 版本中可用。 由于此线程在发行说明和媒体发布之前出现,因此我将在此处交叉发布。

发行说明:
https://docs.docker.com/develop/develop-images/build_enhancements/#using -ssh-to-access-private-data-in-builds

中等帖子:
https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

非常令人兴奋。

我想我们可以关闭它,因为我们现在有docker build --ssh

相关的撰写问题在这里:docker/compose#6865。 使用 Compose 并将 SSH 代理套接字暴露给容器的功能,这些容器注意到将在下一个候选版本1.25.0-rc3(登陆

此页面是否有帮助?
0 / 5 - 0 等级