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 权限检查点。
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 权限不足导致镜像拉取失败的基础。