2. Kubernetes Secrets 基础:Secrets 类型、创建方式、存储机制与安全考量

2.1 Secrets 的本质与设计目标

Kubernetes Secrets 是一种用于存储和管理敏感信息的原生资源对象,其设计目标是将敏感数据(如密码、、TLS 证书)与 Pod 定义、Deployment 等应用配置解耦。在资源配额约束环境下,Secrets 的缓存命中率直接影响 API Server 负载与 etcd 读写压力,因此理解其底层存储与访问机制是调优的前提。

核心原则:Secrets 默认以 Base64 编码存储,但编码 ≠ 加密。任何拥有 etcd 访问权限或 API Server 集群管理员权限的用户均可解码读取。

2.2 Secrets 类型与适用场景

Secrets 类型 用途 数据格式 典型场景
Opaque 通用型,存储任意键值对 Base64 编码的键值对 数据库密码、API
kubernetes.io/service-account- 服务账户令牌 自动注入 SA 令牌 Pod 与 API Server 认证
kubernetes.io/dockercfg Docker 仓库认证 .dockercfg JSON 从私有镜像仓库拉取镜像
kubernetes.io/dockerconfigjson Docker 仓库认证(新格式) config.json JSON 从私有镜像仓库拉取镜像
kubernetes.io/basic-auth HTTP 基本认证 username + password 外部服务 Basic Auth
kubernetes.io/ssh-auth SSH 密钥对 ssh-privatekey Git 仓库访问、远程主机连接
kubernetes.io/tls TLS 证书与私钥 tls.crt + tls.key Ingress 证书、mTLS 通信
调优提示:在资源配额约束下,应优先使用 Opaque 类型并控制单个 Secret 的键值对数量(建议 ≤ 20 个键),以减少 etcd 对象大小与 watch 事件负载。

2.3 Secrets 创建方式对比

创建方式 命令/示例 适用场景 缓存影响
kubectl 命令行 kubectl create secret generic db-pass --from-literal=password=myPass 快速测试、少量数据 直接写入 etcd,触发 watch 通知
kubectl 文件导入 kubectl create secret generic app-key --from-file=./key.json 文件型敏感数据 同上,文件大小影响 etcd 存储
YAML 声明式 kubectl apply -f secret.yaml GitOps、CI/CD 流水线 需提前 Base64 编码,适合版本管理
Kustomize 生成 secretGenerator 字段 环境差异化配置 支持 disableNameSuffixHash 减少变更
外部 Secret 管理工具 External Secrets Operator、Sealed Secrets 生产环境、合规要求 减少 etcd 直接存储,提升缓存命中率
# YAML 声明式创建 Opaque Secret 示例
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=        # Base64("admin")
  password: cGFzc3dvcmQxMjM=  # Base64("password123")

2.4 Secrets 存储机制与 etcd 交互

Secrets 在 Kubernetes 中的存储路径为 /registry/secrets/<namespace>/<name>。当 API Server 收到创建/更新请求时,数据经过以下流程写入 etcd:

  1. API 验证:校验 Secret 名称、命名空间、类型合法性。
  2. Base64 编码:对 data 字段中的值进行 Base64 编码(若用户已编码则直接存储)。
  3. etcd 写入:以 JSON 格式序列化后写入 etcd 的 key-value 存储。
  4. Watch 通知:API Server 向所有监听该 Secret 的 Informer 发送变更事件。
安全警告:etcd 默认未启用加密存储。若 etcd 磁盘被窃取或备份泄露,所有 Secrets 将直接暴露。生产环境必须启用 --encryption-provider-config 对 etcd 中的 Secrets 进行静态加密。
Secrets 写入 etcd 流程 kubectl / 客户端 API Server etcd POST /api/v1/secrets PUT /v3/kv/put API Server 内部处理 ① 请求验证 ② Base64 编码 ③ JSON 序列化 ④ 加密(若配置) API Server 缓存 写入缓存 存储路径 /registry/secrets/ <namespace>/<name>

2.5 Secrets 安全考量与风险矩阵

风险维度 风险描述 缓解措施 优先级
etcd 未加密 Secrets 以明文存储在 etcd 中 启用 --encryption-provider-config 静态加密 高
Base64 非加密 Base64 编码可被轻易解码 结合外部密钥管理服务(KMS)加密 高
RBAC 权限过宽 非必要 ServiceAccount 可读取 Secrets 最小权限原则,使用 Role + RoleBinding 高
Secrets 泄露到日志 环境变量方式注入时可能被日志记录 优先使用 Volume 挂载,避免 env 注入 中
Secrets 版本管理 明文 Secrets 提交到 Git 仓库 使用 Sealed Secrets 或 External Secrets Operator 中
Secrets 轮换延迟 更新 Secret 后 Pod 未自动获取新值 使用 Reloader 或手动滚动重启 Pod 低

2.6 Secrets 访问控制与缓存关系

在资源配额约束下,Secrets 的缓存命中率受以下安全策略影响:

  • RBAC 粒度:细粒度的 Role 绑定会导致更多独立的 Informer 实例,增加 API Server 的 watch 连接数,降低缓存复用率。
  • 命名空间隔离:跨命名空间访问 Secrets 需要额外的 RBAC 配置,且无法利用命名空间级别的缓存局部性。
  • ServiceAccount 关联:每个 Pod 自动挂载的 ServiceAccount Secret 会创建大量小对象,影响 etcd 缓存效率。
调优建议:在资源配额约束下,建议将频繁访问的 Secrets 集中到同一命名空间,并使用 ClusterRole + ClusterRoleBinding 统一授权,减少 API Server 的 watch 连接数,提升缓存命中率。
Secrets 访问控制与缓存路径 Pod A Pod B ServiceAccount API Server Informer 缓存 etcd RBAC 鉴权 读取/写入 缓存填充 缓存命中率关键因素 RBAC 粒度 → Informer 数量 → API Server 连接数 → 缓存复用率

2.7 本章小结

  • Kubernetes Secrets 提供 7 种内置类型,Opaque 是最通用的选择。
  • 创建方式包括命令行、文件导入、YAML 声明式、Kustomize 和外部工具,不同方式对 etcd 负载有直接影响。
  • Secrets 默认以 Base64 编码存储在 etcd 中,必须启用静态加密以保障生产安全。
  • RBAC 权限粒度、命名空间隔离策略直接影响 API Server 的 Informer 缓存效率,是资源配额约束下缓存命中率调优的关键切入点。