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

Deployment Docker和运行时使用的敏感信息,deployment,docker,Deployment,Docker,我们正在对接一个应用程序(用Node.js编写),它需要在运行时访问一些敏感数据(不同服务的API令牌),我找不到任何推荐的方法来处理这个问题 一些信息: 敏感信息不在我们的代码库中,但它以加密格式保存在另一个存储库中 在我们当前的部署中,在没有Docker的情况下,我们使用git更新代码库,然后通过SSH手动复制敏感信息 docker映像将存储在一个私有的、自托管的注册表中 我可以想出一些不同的方法,但它们都有一些缺点: 在构建时将敏感信息包含在Docker映像中。这当然是最简单的一个;然

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

一些信息:

  • 敏感信息不在我们的代码库中,但它以加密格式保存在另一个存储库中
  • 在我们当前的部署中,在没有Docker的情况下,我们使用git更新代码库,然后通过SSH手动复制敏感信息
  • docker映像将存储在一个私有的、自托管的注册表中
我可以想出一些不同的方法,但它们都有一些缺点:

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

  • PS:我做了一些研究,但没有发现任何类似于我的问题。其他问题(如)是关于构建时需要的敏感信息;在我们的例子中,我们需要运行时的信息

    过去我使用了选项3和4来解决这个问题。重新措辞/阐述:

    在映像中创建一个链接到主机系统中某个目录的卷,然后像现在这样通过SSH手动复制凭据

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

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

    将信息作为环境变量传递。但是,我们现在有5对不同的API凭据,这使得这有点不方便。然而,最重要的是,我们需要在配置脚本中保留敏感信息的另一个副本(将执行以运行Docker映像的命令),这很容易造成问题(例如,git中意外包含的凭据等)

    是的,使用
    -e key=value
    语法传递一组env变量很麻烦,但我更喜欢这样做。请记住,这些变量仍然向任何有权访问Docker守护进程的人公开。如果您的
    docker run
    命令是以编程方式编写的,则会更容易

    如果没有,请使用所讨论的
    --env file
    标志。创建一个具有key=value对的文件,然后使用该文件运行一个容器

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

    $cat>>myenv是一个很难正确解决的问题。我找到的最佳解决方案是Hashicorp的vault,但该项目非常新:但在这种情况下,chef仍然需要解密密钥。。。对的(仍然比解密数据更好,并且更安全地防止意外包含到GIT中…)另外,使用KMS也是个好主意,但即使我们在AWS上,我们也在尽可能做到与提供商无关,chef需要解密密钥。当然,有些东西最终会需要它。还有,不是你问的,而是我。你的博客文章很有道理,但事实是我们实际上要在年底前把所有东西都搬到Azure上,所以这对我们来说是一个真正的问题:)有道理,那样的话,使用KMS进行优化是不明智的。因此,只需小心保护chef服务器上的解密密钥。