2. 核心概念:Kubernetes Secret 类型详解
Kubernetes Secret 是集群中存储敏感信息的标准对象,其核心价值在于将敏感数据与 Pod 定义解耦。Secret 的类型(type 字段)决定了数据的编码方式、校验逻辑以及 Kubelet 在拉取镜像时的处理行为。本章重点剖析与镜像拉取认证直接相关的 docker-registry 类型,并对比其他常见类型。
2.1 Secret 类型总览与分类
Kubernetes 原生支持多种 Secret 类型,每种类型对应特定的使用场景。下表列出了最常用的几种类型及其核心差异:
| Secret 类型 | 用途 | 数据键(data 字段) | 编码方式 |
|---|---|---|---|
Opaque |
通用型,存储任意键值对(密码、 等) | 用户自定义 | Base64 |
kubernetes.io/dockerconfigjson |
镜像仓库认证(推荐方式) | .dockerconfigjson |
Base64 编码的 Docker config.json |
kubernetes.io/dockercfg |
镜像仓库认证(旧版格式) | .dockercfg |
Base64 编码的 Docker config |
kubernetes.io/basic-auth |
HTTP 基本认证(用户名+密码) | username, password |
Base64 |
kubernetes.io/tls |
TLS 证书与私钥 | tls.crt, tls.key |
Base64 |
kubernetes.io/ssh-auth |
SSH 认证私钥 | ssh-privatekey |
Base64 |
dockerconfigjson 是唯一被 Kubelet 原生支持的 Secret 类型。使用 Opaque 类型存储 Docker 认证信息虽然技术上可行,但 Kubelet 不会自动解析,必须通过 imagePullSecrets 字段显式引用,且格式必须符合 Docker 规范。
2.2 重点详解:docker-registry 类型(dockerconfigjson)
kubernetes.io/dockerconfigjson 是 Kubernetes 为镜像仓库认证专门设计的 Secret 类型。它的核心数据是一个符合 Docker 客户端规范的 config.json 文件,经过 Base64 编码后存储在 .dockerconfigjson 键中。
2.2.1 数据结构与格式
一个典型的 dockerconfigjson Secret 的 YAML 定义如下:
apiVersion: v1
kind: Secret
metadata:
name: my-registry-secret
namespace: default
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImJtVjRZVzF3YjI1bGJtOXlJR1ZzYVhOcGJtYz0ifX19
解码后的 .dockerconfigjson 内容(Base64 解码后)是一个 JSON 对象:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "base64_encoded_username:password"
}
}
}
其中 auth 字段的值是 username:password 的 Base64 编码字符串。Kubelet 在拉取镜像时,会读取该 Secret,解码 .dockerconfigjson,提取对应仓库地址的认证信息,并注入到容器运行时的拉取请求中。
2.2.2 创建方式对比
Kubernetes 提供了两种创建 dockerconfigjson Secret 的方式:
| 创建方式 | 命令/方法 | 适用场景 | 优点 |
|---|---|---|---|
| 命令行(推荐) | kubectl create secret docker-registry |
交互式创建,适合手动操作 | 自动生成 .dockerconfigjson 格式,无需手动 Base64 编码 |
| YAML 文件 | 手动编写 YAML 并 kubectl apply |
GitOps、CI/CD 流水线 | 可版本控制,适合自动化部署 |
命令行创建示例:
kubectl create secret docker-registry my-registry-secret \
--docker-server=https://index.docker.io/v1/ \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=myuser@example.com \
--namespace=default
--docker-email 字段在 Docker Hub 的旧版 API 中是必填项,但对于其他兼容 OCI 的镜像仓库(如 Harbor、GitLab Container Registry),该字段通常可选。Kubernetes 1.24+ 版本中,该字段已标记为可选。
2.2.3 与旧版 dockercfg 的对比
Kubernetes 早期版本支持 kubernetes.io/dockercfg 类型,其数据格式为 .dockercfg(Docker 1.x 时代的配置文件格式)。两者对比如下:
| 特性 | dockerconfigjson |
dockercfg |
|---|---|---|
| 数据键 | .dockerconfigjson |
.dockercfg |
| 内部格式 | Docker 1.13+ 的 config.json | Docker 1.12 及更早的 config |
| 推荐状态 | 当前推荐 | 已弃用(但兼容) |
| Kubelet 支持 | 完全支持 | 兼容支持 |
2.3 其他相关 Secret 类型
2.3.1 basic-auth 类型
kubernetes.io/basic-auth 用于存储 HTTP 基本认证凭据。虽然它不直接用于镜像拉取,但在某些场景下(如通过 Ingress 访问私有镜像仓库的 Web UI)会用到。
apiVersion: v1
kind: Secret
metadata:
name: my-basic-auth
type: kubernetes.io/basic-auth
data:
username: bXl1c2Vy
password: bXlwYXNzd29yZA==
2.3.2 tls 类型
kubernetes.io/tls 用于存储 TLS 证书和私钥,通常用于 Ingress 的 HTTPS 终止。在镜像拉取场景中,如果仓库启用了双向 TLS(mTLS),则需要将客户端证书和私钥以 tls 类型 Secret 挂载到 Pod 中,但这不是 Kubelet 原生支持的镜像拉取认证方式。
2.4 Secret 类型选择与镜像拉取的关系
下图展示了 Kubelet 在拉取镜像时如何根据 Pod 的 imagePullSecrets 字段选择并解析 Secret:
2.5 最佳实践与常见误区
- 始终使用
dockerconfigjson类型: 对于镜像拉取认证,优先使用kubernetes.io/dockerconfigjson,避免使用Opaque类型手动构造认证数据。 - 避免在 Secret 中存储明文密码: 即使 Base64 编码不是加密,也应结合 RBAC 限制 Secret 的访问权限,并启用 etcd 加密。
- 注意命名空间隔离:
imagePullSecrets必须与 Pod 位于同一命名空间,或通过ServiceAccount的secrets字段全局注入。 - 不要混淆
basic-auth与dockerconfigjson:basic-auth不包含仓库地址信息,Kubelet 无法将其用于镜像拉取。
imagePullSecrets 引用的 Secret 类型是否为 dockerconfigjson,然后验证 .dockerconfigjson 中的仓库地址是否与镜像地址的 registry 部分完全匹配(包括端口号)。