在构建Docker映像时,如何习惯性地访问敏感数据?

在构建Docker映像时,如何习惯性地访问敏感数据?,docker,Docker,有时在构建Docker映像时需要使用敏感数据。例如,用于下载远程文件或从专用存储库安装依赖项的API令牌或SSH密钥。可能需要分发生成的映像,并省略用于构建映像的敏感凭据。如何做到这一点 我已经看到了可以将多个图层压缩为一个图层,从最终图像中删除任何已删除的文件。但是还有更惯用的方法吗?关于惯用方法,我不确定,尽管docker还很年轻,有太多的惯用方法 然而,我们公司也有同样的问题。我们得出以下结论,尽管这些是我们的最佳努力,而不是既定的docker最佳实践 1) 如果在生成时需要这些值:在生成

有时在构建Docker映像时需要使用敏感数据。例如,用于下载远程文件或从专用存储库安装依赖项的API令牌或SSH密钥。可能需要分发生成的映像,并省略用于构建映像的敏感凭据。如何做到这一点


我已经看到了可以将多个图层压缩为一个图层,从最终图像中删除任何已删除的文件。但是还有更惯用的方法吗?

关于惯用方法,我不确定,尽管docker还很年轻,有太多的惯用方法

然而,我们公司也有同样的问题。我们得出以下结论,尽管这些是我们的最佳努力,而不是既定的docker最佳实践

1) 如果在生成时需要这些值:在生成上下文中提供一个属性文件,其中包含可以在生成时读取的值,则可以在生成后删除该属性文件。这不是便携式的,但会做的工作


2) 如果在运行时需要这些值:将值作为环境变量传递。有权访问机箱上的ps的人可以看到它们,但这可以通过SELinux或其他方法进行限制(老实说,我不知道这个过程,我是开发人员,操作团队将处理这部分)。

我们解决这个问题的方法是在
docker build
之上编写一个工具。使用该工具启动构建后,它将下载dockerfile并对其进行更改。它将所有需要“秘密”的指令更改为:

RUN printf "secret: asd123poi54mnb" > /somewhere && tool-which-uses-the-secret run && rm /somewhere

但是,这使得任何有权访问图像的人都可以使用机密数据,除非使用docker squash之类的工具删除图层本身。用于生成每个中间层的命令可以使用

找到,Matthew Close在中谈到了这一点


概述:您应该使用docker compose将敏感信息装载到容器中。

遗憾的是,在构建docker映像时,仍然没有合适的解决方案来处理敏感数据

这个bug很好地总结了人们建议的每一个黑客的错误:

大多数建议似乎混淆了需要进入容器的秘密和用于构建容器的秘密,如这里的几个答案

当前的解决方案似乎实际上是安全的,所有这些解决方案似乎都围绕着将机密文件写入磁盘或内存,然后启动一个愚蠢的小型HTTP服务器,然后让构建过程从HTTP服务器中提取机密,使用它,而不是将其存储在映像中

我所发现的最好的方法是(错误地)使用docker compose文件的内置预定义args功能,而不是达到那种复杂程度,如以下注释所述:


这似乎将机密排除在图像构建历史之外。

2019,而且我不确定在使用docker:时是否有关于机密的idomatic方法或最佳实践保持开放状态


运行时的秘密: 到目前为止,我能找到的最佳方法是在容器中使用环境变量:

  • 使用
    docker run
    -e
    选项。。。但是,您的秘密可以在命令行历史记录中找到
  • 使用docker选项或docker compose选项。至少在命令行中没有传递机密
  • 问题:在任何情况下,现在任何能够在docker主机上运行docker命令的人都可以使用机密(使用命令)

构建时的秘密(您的问题): 我可以看到这个问题的另外两个(部分?)解决方案:

多阶段构建: 使用多阶段docker构建:基本上,docker文件将定义两个图像:

  • 一个第一中间映像(“构建映像”),其中:

    • 您将机密添加到此图像中:使用或机密文件(小心构建参数:它们必须在
      docker build
      命令行中传递)
    • 您构建了您的人工制品(现在您可以访问您的私有存储库)
  • 第二个图像(“分布图像”),其中:

    • 从“构建图像”复制构建的人工制品
    • 在docker注册表上分发您的图像
  • 引用的github线程中的几个注释解释了这种方法:

    小心

    这种多阶段构建方法远非理想:“构建映像”在build命令之后仍然位于主机上(并且包含您的敏感信息)。有

    新的
    --secret
    构建选项: 我今天发现了这个选项,因此还没有进行实验。。。到目前为止我所知道的:

    • 它是在github上发布的
    • 这一评论引发了一场争论
    • (docker v19.03目前)没有详细说明此选项:它与下面的描述一起列出,但没有关于它的详细部分: --秘密

      API 1.39+

      要向生成公开的机密文件(仅在启用BuildKit时):id=mysecret,src=/local/Secret


    关于1,问题在于将图像推送到索引(Docker hub、quay.io等)时,会推送到图像的所有层,包括具有属性文件的层。任何拉取该图像的人都可以启动一个带有层的容器,该层仍然具有属性文件,并可以查看敏感变量。啊,好的,抱歉。我以为你指的是共享一个构建文件(其他人可以在其中构建,然后在构建时提供自己的属性文件)。如果在一个
    RUN
    命令中下载某个文件,对其内容执行任何需要的操作,最后删除该文件,则下载的文件不会提交到层中。它必须在一个
    RUN
    命令中运行