如何安全地将秘密传递给Docker容器

70次阅读
没有评论

问题描述

有一个基础的Docker镜像,用于运行图像分析软件。对于从该镜像创建的每个容器,都有一组配置设置,其中一些是秘密(加密密钥、客户信息等),这些秘密被软件用于分析和分发处理后的图像。用户想知道如何安全地将这些秘密传递给容器。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1 – 环境变量

根据《12因素应用程序》指南,秘密只是配置的一部分,应该始终设置在环境变量中。你可以在运行Docker容器时将秘密设置为环境变量,然后应用程序从环境变量中获取这些秘密。
以下是使用环境变量的步骤:
1. 在运行Docker容器时,设置环境变量,将秘密传递给容器。
2. 在应用程序中,从环境变量中读取秘密。
这种方法的优点是简单易用,可以方便地管理秘密。但需要注意,环境变量可能会被泄露,比如通过Docker守护进程的inspect或exec命令,或者在某些调试模式下,环境变量可能会被输出到stdout或日志文件中。

方案2 – 挂载卷

你可以将所有秘密放在一个特定的配置/秘密文件中,然后将其作为挂载卷挂载到容器中。这样,应用程序可以从文件中读取秘密。
以下是使用挂载卷的步骤:
1. 创建一个包含秘密的配置/秘密文件。
2. 在运行Docker容器时,将该文件作为挂载卷挂载到容器中。
3. 在应用程序中,从挂载的文件中读取秘密。
这种方法的优点是可以将秘密存储在文件中,而不是直接暴露在环境变量中。但需要注意,挂载的文件可能会被泄露,因此需要确保文件的权限设置正确。

方案3 – 从秘密存储中获取

你可以使用一些秘密存储服务(如Hashicorp Vault或Amazon Secrets Manager)来存储和管理秘密。应用程序可以直接从秘密存储中获取所需的秘密,而无需在Docker容器中进行任何配置。
以下是使用秘密存储的步骤:
1. 配置和设置秘密存储服务(如Hashicorp Vault)。
2. 在应用程序中,使用相应的SDK或API从秘密存储中获取秘密。
这种方法的优点是可以使用动态创建的秘密,并且不必担心秘密在文件系统或Docker容器的环境变量中可见。
请注意,使用秘密存储服务需要额外的配置和设置,以及对秘密存储服务的访问权限。

方案4 – 使用管道传递秘密

还有一种方法是使用管道将秘密传递给Docker容器。以下是使用管道传递秘密的步骤:
1. 创建一个带有-i选项的Docker容器,使其等待从/proc/1/fd/0读取输入。
2. 运行第二个Docker命令,从标准输入读取秘密,并将其重定向到第一个容器等待的进程。
这种方法的优点是简单直接,不需要额外的配置和设置。但需要注意,使用管道传递的秘密可能会被泄露,因此需要确保适当的权限和安全措施。
请注意,以上解决方案中的每一种都有其优缺点和适用场景。根据你的具体需求和安全要求,选择适合你的解决方案。

个人观点

个人认为,使用环境变量是一种简单有效的方法。你可以将秘密存储在环境变量中,并在构建CI系统时从秘密存储中获取秘密,并在部署时设置环境变量。这样既可以方便地管理秘密,又可以保证开发人员不需要编写代码来获取秘密。应用程序的代码应该专注于自身的功能,而不是处理后端任务,如获取密码。

个人观点(更新)

根据@Dirk的评论,优先使用秘密存储而不是环境变量有一个非常强的理由,即不希望泄露秘密。秘密存储可以提供更高的安全性和灵活性,可以更好地保护秘密,并且可以轻松地撤销或更改权限。因此,在考虑安全性时,优先考虑使用秘密存储是一个明智的选择。

请注意,以上解决方案中的每一种都有其优缺点和适用场景。根据你的具体需求和安全要求,选择适合你的解决方案。

引用

正文完