首页/安全/加密与证书速查/容器中的密钥注入

容器中的密钥注入

容器内密钥应通过 Secret 挂载或外部密钥系统注入,而不是打进镜像层;挂载建议只读,并确认密钥未进入镜像历史、构建缓存与运行日志。

加密与证书速查安全更新于 2026-10-13

容器里怎么放密钥

容器与镜像是一对容易出错的组合:镜像层是不可变的,任何在构建阶段写进去的密钥都会永久留在层里,哪怕后续步骤删除文件也依然能从历史层中提取出来。正确做法是运行时注入——Secret 挂载成文件、CSI 驱动按需从 KMS 拉取、启动时从密钥系统获取。注入方式也有优先级:文件挂载优于环境变量,因为环境变量更容易被子进程继承、被诊断接口打印、被 crash 报告收集。

基本信息

注入方式Secret 卷挂载、CSI 驱动对接 KMS、启动时按需拉取
优先级文件挂载优于环境变量
挂载要求只读挂载,避免容器内进程改写密钥文件
禁止做法在 Dockerfile 里 COPY 或 RUN 写入密钥
检查点镜像历史与 CI 日志中不得出现密钥材料
权限按最小权限给应用账号可读即可

典型使用场景

  • TLS 证书部署:把证书与私钥通过 Secret 挂到容器指定目录。
  • 构建流水线:从 KMS 动态获取密钥,而不是写入 CI 变量并打入镜像。
  • 多环境部署:不同环境挂载不同密钥,避免密钥随镜像流动。
  • 安全审计:检查镜像层与历史记录中是否存在密钥材料。
  • 密钥轮换:轮换后由挂载更新驱动,减少重建镜像的操作。

只读挂载与 Secret 读取

只读挂载与 Secret 读取
# 只读挂载密钥目录,容器内进程无法改写
docker run --read-only \
  --mount type=bind,src=/run/secrets/tls,dst=/etc/tls,readonly nginx:stable
# 从 Kubernetes Secret 读取证书内容(注意该命令会把明文打到终端)
kubectl get secret tls-secret -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/tls.crt
# 检查镜像历史,确认构建阶段没有写入密钥
docker history --no-trunc <image>

注入方式对比

方式适用场景风险点
Secret 卷挂载常规应用读取文件形式凭据挂载权限过宽、可被容器内进程改写
CSI 驱动对接 KMS云上按需获取,避免静态存储依赖驱动与权限配置正确
环境变量兼容老旧应用的临时手段易被日志、诊断接口与子进程泄露
镜像内打包任何场景都不推荐镜像层不可删除,密钥长期留存在仓库
启动时拉取需要在内存中使用而不落盘拉取失败会导致启动阻塞,需要重试策略
删除镜像里的密钥文件并不能把它从镜像层中移除:只要有人持有该镜像,仍可逐层提取。发现密钥曾被打进镜像层时,正确处置是轮换密钥并从源头改掉构建流程。

易错点

  • 把私钥 COPY 进镜像层:后续删除仍可从历史层提取,且镜像可能已被分发到多处。
  • 用环境变量承载私钥:诊断信息、崩溃上报与子进程都可能带出去。
  • 挂载密钥目录为可写:容器内进程一旦被攻破即可替换服务端私钥。
  • 轮换密钥后不更新挂载来源:容器仍加载旧文件,排查时容易误判为服务未重启。

数据来源与参考

  • Docker 官方文档(挂载与 Secrets)
  • Kubernetes 官方文档(Secret 卷挂载)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌