我的Tomcat容器需要受到良好保护的数据,即数据库访问的密码以及单点登录到其他系统的证书和密钥。
我看到了一些使用-e
或-env-file
将秘密数据传递到容器的建议,但这可以通过docker inspect来发现(-env-file
还显示了docker inspect中文件的所有属性)。
另一种方法是将数据容器与秘密链接到服务容器,但我不喜欢在我的注册表中使用此数据容器的概念(可供更广泛的人使用)。我知道我可以建立一个私人注册表,但是我需要不同的注册表来进行测试和生产,但仍然可以访问生产注册表的每个人都可以访问秘密数据。
我正在考虑使用包含机密数据的目录来设置我的服务器,并将机密数据安装到我的容器中。这对于具有不同秘密的测试和生产服务器非常有效。但它创建了容器与我的特定服务器的依赖关系。
所以我的问题是:你如何处理秘密数据,这个问题的最佳解决方案是什么?
2017年1月更新
Docker 1.13现在有命令docker secret
和docker swarm。
另见“Why is ARG
in a DOCKERFILE
not recommended for passing secrets?”。
原始答案(2015年9月)
docker vault
提到的 Adrian Mouat的概念,在his previous answer上积极讨论(讨论继续在issue 1030)。
它现在被拒绝,因为它超出了docker的范围,但也包括:
我们已经提出了一个简单的解决方案来解决这个问题:bash脚本曾经通过单个issues 13490命令执行,从本地HTTP服务器下载私钥,执行给定的命令并在之后删除密钥。
由于我们在单个
RUN
中完成所有这些操作,因此图像中不会缓存任何内容。以下是它在Dockerfile中的外观:
RUN
围绕这一概念的第一个实现可以在
RUN ONVAULT npm install --unsafe-perm
上找到。要在本地开发图像,我们使用自定义开发框来运行Dockito Vault作为服务。
唯一的缺点是需要运行HTTP服务器,因此没有Docker集线器构建。
将加密密钥挂载到容器中,然后通过管道传递密码。问题来自于dockito/vault
模式,它会在读取容器内的管道时挂起。这是一个解决方法:
detach
首先,使用cid=$(docker run -d -i alpine sh -c 'read A; echo "[$A]"; exec some-server')
docker exec -i $cid sh -c 'cat > /proc/1/fd/0' <<< _a_secret_
选项创建docker守护进程,命令-i
将等待来自read A
的输入;然后运行第二个docker命令,从stdin读取秘密并重定向到最后一个挂起进程。