有时在构建Docker镜像时需要使用敏感数据。例如,用于下载远程文件或从私有存储库安装依赖项的API令牌或SSH密钥。可能需要分发结果图像并省略用于构建它的敏感凭证。怎么办呢?
我看过docker-squash可以将多个图层压缩为一个,从最终图像中删除任何已删除的文件。但是有更惯用的方法吗?
答案 0 :(得分:4)
关于习惯用法,我不确定,虽然码头工人还很年轻但有太多的习语。
然而,我们在公司遇到过同样的问题。我们得出以下结论,尽管这些是我们最好的努力,而不是已建立的docker最佳实践。
1)如果您需要构建时的值:在构建上下文中提供属性文件,其中包含可在构建时读取的值,然后可以在构建后删除属性文件。这不是便携式的,但可以完成这项工作。
2)如果在运行时需要值:将值作为环境变量传递。有权访问盒子上的ps的人可以看到它们,但这可以通过SELinux或其他方法进行限制(老实说,我不知道这个过程,我是开发人员,运营团队会处理那部分)。
答案 1 :(得分:2)
遗憾的是,在构建docker映像时仍然没有适当的解决方案来处理敏感数据。
此错误很好地总结了人们建议的每种hack的错误之处: https://github.com/moby/moby/issues/13490
大多数建议似乎将需要进入容器的秘密与用于构建容器的秘密相混淆,就像这里的几个答案一样。
当前看来实际上是安全的解决方案,所有解决方案似乎都围绕着将机密文件写到磁盘或内存中,然后启动一个愚蠢的小型HTTP服务器,然后让构建过程从http中获取机密。服务器,请使用它,而不要将其存储在图像中。
我发现最好的方法就是不(使用)此注释中指定的docker compose文件的内置预定义参数功能:
https://github.com/moby/moby/issues/13490#issuecomment-403612834
这似乎确实使秘密不属于图像构建历史。
答案 2 :(得分:1)
我们解决此问题的方法是,我们在docker build
之上编写了一个工具。使用该工具启动构建后,它将下载dockerfile并对其进行更改。它将所有需要“秘密”的指令更改为:
RUN printf "secret: asd123poi54mnb" > /somewhere && tool-which-uses-the-secret run && rm /somewhere
但是,除非使用像docker-squash这样的工具删除图层本身,否则这会将秘密数据留给有权访问图像的任何人。可以使用the history command
找到用于生成每个中间层的命令答案 3 :(得分:1)
Matthew Close在this blog article中谈到这一点。
总结:您应该使用docker-compose将敏感信息挂载到容器中。
答案 4 :(得分:1)
2019年,我不确定使用docker时是否有关于秘密的信息学方法或最佳做法:https://github.com/moby/moby/issues/13490到目前为止仍然开放。
到目前为止,我能找到的最佳方法是在容器中使用环境变量:
docker run
-e
选项...但是您的秘密在命令行历史记录中可用env_file
选项或docker-compose env_file
选项。至少秘密没有在命令行中传递docker inspect
命令)的人都可以使用机密我可以看到2个其他(部分?)解决方案:
使用多阶段docker构建:基本上,您的dockerfile将定义2张图片:
一个第一中间图像(“ 构建图像”),其中:
docker build
命令行中传递)第二张图片(“ 分发图片”),其中:
通过引用的github线程中的一些注释来解释这种方法:
警告
这种多阶段构建方法远非理想之举:在生成命令后,“ 构建映像”仍位于您的主机上(并包含您的敏感信息)。有precautions to take
--secret
构建选项:我今天发现了这个选项,因此还没有进行实验...到目前为止我所知道的:
-秘密
API 1.39 +
要公开显示的秘密文件(仅在启用BuildKit的情况下):id = mysecret,src = / local / secret