我最近一直在尝试使用Docker构建一些服务,有一件事一直困扰着我,那就是把密码放在Dockerfile中。我是一名开发人员,所以在源代码中存储密码感觉就像在脸上打了一拳。这值得担心吗?Dockerfiles中有什么好的处理密码的约定吗?


当前回答

我们的团队避免将凭证放在存储库中,因此这意味着Dockerfile中不允许使用凭证。我们在应用程序中的最佳实践是使用来自环境变量的信用。

我们使用docker-compose来解决这个问题。

docker-compose之内。Yml,你可以为容器指定一个包含环境变量的文件:

 env_file:
- .env

确保将.env添加到.gitignore,然后在.env文件中设置凭据,如下所示:

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

将.env文件存储在本地或其他团队成员可以获取它的安全位置。

见:https://docs.docker.com/compose/environment-variables/ / the-env-file

其他回答

使用环境变量的另一种替代方法是使用卷使容器中可以访问主机上的目录,如果环境变量太多,环境变量会变得很混乱。

如果您将所有凭据作为文件放在该文件夹中,那么容器就可以读取这些文件并根据需要使用它们。

例如:

$ echo "secret" > /root/configs/password.txt
$ docker run -v /root/configs:/cfg ...

In the Docker container:

# echo Password is `cat /cfg/password.txt`
Password is secret

许多程序都可以从一个单独的文件中读取它们的凭据,因此通过这种方式,您可以将程序指向其中一个文件。

我们的团队避免将凭证放在存储库中,因此这意味着Dockerfile中不允许使用凭证。我们在应用程序中的最佳实践是使用来自环境变量的信用。

我们使用docker-compose来解决这个问题。

docker-compose之内。Yml,你可以为容器指定一个包含环境变量的文件:

 env_file:
- .env

确保将.env添加到.gitignore,然后在.env文件中设置凭据,如下所示:

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

将.env文件存储在本地或其他团队成员可以获取它的安全位置。

见:https://docs.docker.com/compose/environment-variables/ / the-env-file

我想,如果它是bash shell,像这样简单的东西就可以工作。

读取-sp "db_password:" password | docker run -itd——name <container_name>——build-arg mysql_db_password=$db_password alpine /bin/bash

只需默读它,并在Docker映像中作为参数传递。你需要在Dockerfile中接受变量作为ARG。

这肯定是一个问题。dockerfile通常被签入存储库并与其他人共享。另一种方法是在运行时提供任何凭据(用户名、密码、令牌,任何敏感的东西)作为环境变量。这可以通过-e参数(用于CLI中的单个变量)或——env-file参数(用于文件中的多个变量)来运行docker。阅读这篇文章,了解如何在docker-compose中使用环境。

使用——env-file绝对是一个更安全的选择,因为如果使用set -x,它可以防止秘密显示在ps或日志中。

然而,环境变量也不是特别安全。通过docker inspect可以看到它们,因此任何可以运行docker命令的用户都可以使用它们。(当然,在主机上可以访问docker的任何用户都有root权限。)

我更喜欢的模式是使用包装器脚本作为ENTRYPOINT或CMD。包装器脚本可以首先在运行时将秘密从外部位置导入到容器中,然后执行应用程序,提供秘密。具体的机制取决于您的运行时环境。在AWS中,您可以使用IAM角色、密钥管理服务和S3的组合来将加密的秘密存储在S3桶中。HashiCorp Vault或credstash是另一种选择。

在构建过程中使用敏感数据没有最佳模式。事实上,我有一个关于这个话题的SO问题。您可以使用docker-squash从映像中删除图层。但是Docker中并没有用于此目的的本机功能。

您可能会发现在容器中对配置的shykes注释很有用。

有一个新的docker命令用于“秘密”管理。但这只适用于蜂群。

docker service create
--name my-iis
--publish target=8000,port=8000
--secret src=homepage,target="\inetpub\wwwroot\index.html"
microsoft/iis:nanoserver