Docker Secrets 密钥管理指南
Docker Secrets 为容器提供加密存储与安全分发的密钥管理:静态加密存于 Swarm Raft 数据库,按服务授权挂载到容器 tmpfs。本文覆盖创建、Compose 用法、最佳实践与第三方集成。
直接回答:Docker Secrets 是 Swarm 级的密钥管理——密钥静态加密存进 Raft 数据库,仅授权给需要的服务,在 Linux 容器中以 tmpfs 内存文件形式挂进容器(/run/secrets/<名>),分发时不写入容器持久层,应用仍可能把内容写入日志或文件。比硬编码与环境变量安全一个档次。
为什么不用环境变量
环境变量里的密钥:docker inspect 可见、/proc 可查、崩溃转储可能包含、子进程继承——四面漏风。Linux Swarm secret 对授权任务提供内存挂载,管理员及授权进程仍能读取。Windows 容器运行期间 secret 以明文存于容器根盘,应配合 BitLocker 等宿主机磁盘保护。
创建与使用
docker secret create db_password ./secrets/db_password.txt
docker service create --name api --secret db_password myimage
# 容器内读取:cat /run/secrets/db_password
以上需在 Swarm manager 上执行,并事先准备权限受限、未入库的密钥文件。应用必须显式读取 secret 文件,Docker 不自动将其变成应用配置。
Compose 用法
services:
api:
image: myimage
secrets: [db_password]
secrets:
db_password:
file: ./secrets/db_password.txt # 外部文件,不进镜像
注意:非 Swarm 模式的单机 Compose 用 file: 形式时只是普通文件挂载(无 Raft 加密)——静态加密是 Swarm 特性。
最佳实践
- 密钥文件不进 Git(或加密后入库)
- 最小授权:secret 只 attach 给需要的服务
- 轮换流程:新建 secret → 服务切换 → 验证各客户端认证成功 → 删旧(运行时换密钥需服务更新);验证日志只记录结果,不记录密钥值。
- 读取后程序立即加载并避免二次落盘
与第三方集成
规模更大时对接专业密钥系统(HashiCorp Vault、云厂商 SM):由受控自动化拉取密钥并创建 Swarm secret,再更新服务;容器内拉取文件不会自动创建 Swarm secret。
常见问题(FAQ)
Q:K8s 的 Secret 和 Docker Secrets 一样吗?
A:理念相同实现不同——K8s Secret 的 data 用 base64 编码,etcd 静态加密需另配(托管服务可能已开启);Swarm secret 默认加密存储和传输。各自的最佳实践都要单独学。
Q:密钥能热更新吗?
A:不能直接改——secret 不可变,更新=新建+重新授权+服务更新。设计轮换流程时按这个模型来。
Q:单机 Docker(非 Swarm)怎么管密钥?
A:Compose 的 file secret 勉强可用;更系统的方案是外部密钥管理 + 启动时拉取,或干脆上 Swarm/K8s。
官方参考
本文依据官方文档整理,示例未在本文中进行运行验证。生产部署需按所用版本、权限和实际负载验证。