Docker 和 运行 时使用的敏感信息

Docker and sensitive information used at run-time

我们正在 docker 化一个应用程序(用 Node.js 编写)需要在 运行 时间访问一些敏感数据(API 不同服务的令牌) 而且我找不到任何推荐的方法来处理这个问题。

一些信息:

我可以想到一些不同的方法,但它们都有一些缺点:

  1. 在构建时将敏感信息包含在 Docker 图像中。这当然是最简单的;但是,它使任何有权访问图像的人都可以使用它们(我不知道我们是否应该那么信任注册表)。
  2. 与 1 类似,但凭据位于纯数据映像中。
  3. 在映像中创建一个链接到主机系统中目录的卷,然后像我们现在所做的那样通过 SSH 手动复制凭据。这也很方便,但是我们不能轻易启动新服务器(也许我们可以使用类似 etcd 的东西来同步它们?)
  4. 将信息作为环境变量传递。但是,我们现在有 5 对不同的 API 凭据,这让这有点不方便。然而,最重要的是,我们需要在配置脚本中保留敏感信息的另一个副本(将对 运行 Docker 图像执行的命令),这很容易产生问题(例如凭据意外包含在 git 等中)。

PS: 我做了一些研究,但找不到与我的问题类似的任何东西。其他问题(如 this one)是关于构建时所需的敏感信息;在我们的例子中,我们需要 运行-time

的信息

我过去曾使用您的选项 3 和 4 来解决这个问题。到 rephrase/elaborate:

Create a volume in the image that links to a directory in the host system, and manually copy the credentials over SSH like we're doing right now.

我使用配置管理(Chef 或 Ansible)在主机上设置凭据。如果应用程序采用需要 API 令牌或数据库凭据的配置文件,我会使用配置管理从模板创建该文件。 Chef 可以从加密数据包或属性中读取凭据,在主机上设置文件,然后使用您描述的卷启动容器。

请注意,在容器中,您可能需要 运行 应用程序的包装器。包装器将配置文件从安装的任何卷复制到应用程序期望的任何位置,然后启动应用程序。

Pass the information as environment variables. However, we have 5 different pairs of API credentials right now, which makes this a bit inconvenient. Most importantly, however, we would need to keep another copy of the sensitive information in the configuration scripts (the commands that will be executed to run Docker images), and this can easily create problems (e.g. credentials accidentally included in git, etc).

是的,使用 -e key=value 语法传递一堆环境变量很麻烦,但这是我更喜欢这样做的方式。请记住,这些变量仍然会暴露给有权访问 Docker 守护程序的任何人。如果您的 docker run 命令是以编程方式编写的,那就更容易了。

如果不是,请使用 --env-file 标志,如讨论的那样 here in the Docker docs。您使用键=值对创建一个文件,然后 运行 使用该文件的容器。

$ cat >> myenv << END
FOO=BAR
BAR=BAZ
END
$ docker run --env-file myenv

可以使用上述 chef/config 管理创建 myenv 文件。

如果您在 AWS 上托管,则可以在此处利用 KMS。通过 KMS 加密 env 文件或配置文件(传递给卷中的容器)。在容器中,使用包装器脚本调用 KMS,解密文件,将其移入放置并启动应用程序。这样配置数据就不会暴露在磁盘上。