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


当前回答

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

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

例如:

$ 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

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

其他回答

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

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

我们的团队避免将凭证放在存储库中,因此这意味着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

这肯定是一个问题。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注释很有用。

12因素应用程序方法告诉我们,任何配置都应该存储在环境变量中。

Docker compose可以在配置中进行变量替换,因此可以用来将密码从主机传递到Docker。

从版本20.10开始,除了使用secret-file,您还可以直接使用env提供秘密。

Buildkit: secrets:允许提供秘密与env moby/moby#41234 docker/cli#2656 moby/ Buildkit #1534 支持——secret id=foo,env=MY_ENV作为将秘密值存储到文件的替代方案。 ——secret id=GIT_AUTH_TOKEN将加载env,如果它存在,而文件不存在。

秘密文件:

THIS IS SECRET

Dockerfile:

# syntax = docker/dockerfile:1.3
FROM python:3.8-slim-buster
COPY build-script.sh .
RUN --mount=type=secret,id=mysecret ./build-script.sh

build-script.sh:

cat /run/secrets/mysecret

执行:

$ export MYSECRET=theverysecretpassword
$ export DOCKER_BUILDKIT=1
$ docker build --progress=plain --secret id=mysecret,env=MYSECRET -t abc:1 . --no-cache
......
#9 [stage-0 3/3] RUN --mount=type=secret,id=mysecret ./build-script.sh
#9 sha256:e32137e3eeb0fe2e4b515862f4cd6df4b73019567ae0f49eb5896a10e3f7c94e
#9 0.931 theverysecretpassword#9 DONE 1.5s
......