2. Kubernetes Secrets 基础:Secrets 的作用、类型与创建方式

在 Kubernetes 中,Secrets 是一种专门用于存储敏感信息的资源对象,例如密码、OAuth 令牌、SSH 密钥、镜像仓库凭证等。与 ConfigMap 不同,Secrets 在设计上更注重安全性,默认会以 Base64 编码存储,并支持更细粒度的访问控制(RBAC)。

2.1 Secrets 的核心作用

  • 解耦敏感数据与 Pod 定义:避免在 YAML 或容器镜像中硬编码密码、。
  • 细粒度权限控制:通过 RBAC 限制哪些 ServiceAccount 或用户能读取特定 Secret。
  • 动态挂载与更新:支持以环境变量或 Volume 方式注入到 Pod,部分更新可被运行中的 Pod 感知。
  • 加密存储(可选):配合 KMS 或 etcd 加密,实现静态数据加密。
关键认知: Secrets 的 Base64 编码并非加密。任何拥有 Secret get 权限的人都可以解码查看明文。真正的安全依赖于 RBAC 和 etcd 加密。

2.2 Secrets 的三种常用类型

类型 用途 典型场景 数据格式
Opaque 存储任意键值对(通用型) 数据库密码、API 、应用配置密钥 Base64 编码的键值对
kubernetes.io/dockerconfigjson 存储 Docker 镜像仓库认证信息 从私有仓库拉取镜像 Base64 编码的 Docker config.json
kubernetes.io/tls 存储 TLS 证书与私钥 Ingress 证书、mTLS 通信 tls.crt 和 tls.key 字段

2.3 三种创建方式详解

方式一:使用 kubectl create secret 命令(推荐)

这是最常用且最直观的方式,kubectl 会自动处理 Base64 编码。

# 创建 Opaque 类型 Secret
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password='S3cur3P@ss'

# 创建 dockerconfigjson 类型 Secret
kubectl create secret docker-registry regcred \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=myuser \
  --docker-password=mypassword \
  --docker-email=myuser@example.com

# 创建 TLS 类型 Secret
kubectl create secret tls tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

方式二:使用 YAML 清单文件(声明式)

适用于 GitOps 或需要版本控制的场景。注意:YAML 中的值必须预先进行 Base64 编码。

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=          # echo -n 'admin' | base64
  password: UzNjdXIzUEBzcw==  # echo -n 'S3cur3P@ss' | base64
---
apiVersion: v1
kind: Secret
metadata:
  name: regcred
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJteXVzZXIiLCJwYXNzd29yZCI6Im15cGFzc3dvcmQiLCJlbWFpbCI6Im15dXNlckBleGFtcGxlLmNvbSIsImF1dGgiOiJiRzluYVc0NmJHOW5hVzQ2YzI5aWFHVnVZM2c9In19fQ==
⚠️ 安全警告: 将明文密码写入 YAML 并提交到 Git 仓库是高风险行为。生产环境应使用 Sealed Secrets、External Secrets Operator 或 Vault 集成。

方式三:使用 kustomize 或 Helm(模板化)

在 GitOps 工作流中,通常使用 kustomize 的 secretGenerator 或 Helm 的 tpl 函数动态生成 Secret,避免明文硬编码。

# kustomization.yaml 示例
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: db-secret
  literals:
  - username=admin
  - password=S3cur3P@ss
  type: Opaque

2.4 Secrets 类型与创建方式对比总览

创建方式 适用类型 优点 缺点
kubectl create secret Opaque, dockerconfigjson, TLS 命令简单,自动编码,适合快速测试 不便于版本控制,难以审计
YAML 清单 所有类型 声明式,可 Git 管理,可复用 需手动 Base64 编码,易泄露
kustomize / Helm 所有类型 模板化,支持变量注入,适合 CI/CD 学习曲线略高,需额外工具

2.5 Secrets 在 Pod 中的使用流程(内联 SVG)

下图展示了 Secret 从创建到被 Pod 消费的完整链路,以及 RBAC 权限检查点。

Secrets 创建与消费流程 Secrets 创建 → 消费流程与 RBAC 权限检查点 1. 创建 Secret 2. etcd 存储 3. RBAC 权限检查 4. Pod 请求 Secret 5. API Server 鉴权 6. 注入 Pod 🔑 关键说明: • 步骤 3(RBAC 检查)是镜像拉取失败的核心排查点。 • 如果 Pod 的 ServiceAccount 没有对 Secret 的 get 权限, kubelet 将无法读取 dockerconfigjson,导致 ImagePullBackOff。

2.6 镜像拉取场景中的关键 Secret 类型:dockerconfigjson

在后续章节的故障排查中,kubernetes.io/dockerconfigjson 是最常出问题的 Secret 类型。它的内部结构如下:

{
  "auths": {
    "https://index.docker.io/v1/": {
      "username": "myuser",
      "password": "mypassword",
      "email": "myuser@example.com",
      "auth": "bXl1c2VyOm15cGFzc3dvcmQ="
    }
  }
}

其中 auth 字段是 username:password 的 Base64 编码。kubelet 在拉取镜像时,会使用该 Secret 中的凭证向镜像仓库进行身份认证。

💡 排查要点: 当出现 ImagePullBackOff 或 ErrImagePull 时,首先检查 Pod 所在 Namespace 是否存在名为 regcred 或类似名称的 dockerconfigjson Secret,并确认该 Secret 的 .dockerconfigjson 数据是否包含正确的仓库地址和认证信息。

2.7 本章小结

  • Secrets 是 Kubernetes 管理敏感数据的标准方式,支持 Opaque、dockerconfigjson、TLS 三种常用类型。
  • 创建方式包括 kubectl 命令、YAML 清单、kustomize/Helm,各有适用场景。
  • 镜像拉取依赖 dockerconfigjson 类型的 Secret,其读取权限受 RBAC 控制。
  • 理解 Secrets 的创建与消费流程,是后续排查 RBAC 权限不足导致镜像拉取失败的基础。