3. 常用资源API版本演进史:Deployment、StatefulSet、Ingress、CRD等核心资源的版本变化
Kubernetes API 版本遵循严格的废弃(Deprecation)与移除(Removal)策略。每个版本号(如 v1beta1 → v1)都代表不同的稳定性与功能承诺。理解核心资源的版本演进路径,是制定升级计划的前提。
3.1 版本命名规则与生命周期
Kubernetes API 版本分为三个层级:
| 版本层级 | 命名示例 | 稳定性 | 废弃后保留周期 |
|---|---|---|---|
| Alpha | v1alpha1 |
默认关闭,可能包含缺陷,随时可能变更 | 不保证向后兼容,通常在下个版本移除 |
| Beta | v1beta1, v2beta2 |
默认开启,经过充分测试,语义稳定 | 废弃后至少保留 3 个次要版本(约 9 个月) |
| Stable(GA) | v1, v2 |
生产就绪,长期支持 | 出现在 API 中后,极少移除;移除前会提前多个大版本通知 |
关键原则: 集群升级时,必须确保所有使用中的 API 版本在目标集群中仍然可用。如果某个资源版本已在目标集群中被移除,则升级后该资源将无法读取或写入。
3.2 Deployment 版本演进
Deployment 是 Kubernetes 中最常用的工作负载资源,其 API 版本演进路径清晰,是理解版本迁移的典型范例。
- Kubernetes 1.1 – 1.8:
extensions/v1beta1(初始引入) - Kubernetes 1.2 – 1.8:
apps/v1beta1(引入 apps 组) - Kubernetes 1.4 – 1.8:
apps/v1beta2(改进字段结构) - Kubernetes 1.9:
apps/v1(GA 稳定版本) - Kubernetes 1.16:
extensions/v1beta1、apps/v1beta1、apps/v1beta2被正式移除
迁移要点: 从 Kubernetes 1.16 开始,Deployment 只能使用
apps/v1。如果你的集群版本低于 1.16,必须提前将 Deployment 的 API 版本从 extensions/v1beta1 或 apps/v1beta1 迁移到 apps/v1。
# 检查集群中所有 Deployment 的 API 版本
kubectl get deployment --all-namespaces -o jsonpath='{range .items[*]}{.apiVersion}{"\n"}{end}' | sort -u
# 如果输出包含 extensions/v1beta1 或 apps/v1beta1,则需要迁移
# 迁移命令示例(使用 kubectl convert 插件):
kubectl convert -f old-deployment.yaml --output-version apps/v1 > new-deployment.yaml
kubectl apply -f new-deployment.yaml
3.3 StatefulSet 版本演进
StatefulSet 的演进路径与 Deployment 高度相似,但时间线略有不同。
| API 版本 | 引入版本 | 废弃版本 | 移除版本 |
|---|---|---|---|
apps/v1beta1 |
1.5 | 1.8 | 1.16 |
apps/v1beta2 |
1.8 | 1.9 | 1.16 |
apps/v1 |
1.9 | — | — |
注意: StatefulSet 从未在
extensions/v1beta1 中出现过。如果你在旧集群中看到 StatefulSet 使用 apps/v1beta1 或 apps/v1beta2,必须在升级到 1.16 之前迁移到 apps/v1。
3.4 Ingress 版本演进
Ingress 的版本演进较为复杂,因为它经历了从 extensions 组到 networking 组的迁移,并且引入了新的 IngressClass 资源。
- Kubernetes 1.1 – 1.13:
extensions/v1beta1(唯一版本) - Kubernetes 1.14: 引入
networking.k8s.io/v1beta1(功能与extensions/v1beta1相同) - Kubernetes 1.19: 引入
networking.k8s.io/v1(GA 版本,字段结构有重大变化) - Kubernetes 1.22:
extensions/v1beta1和networking.k8s.io/v1beta1被移除
关键差异:
networking.k8s.io/v1 中的 Ingress 规范与旧版本不兼容。主要变化包括:spec.backend 改为 spec.defaultBackend;pathType 字段变为必填;serviceName 和 servicePort 改为 service.name 和 service.port.number。
# 旧版本 Ingress(extensions/v1beta1)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: old-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /api
backend:
serviceName: api-service
servicePort: 8080
# 新版本 Ingress(networking.k8s.io/v1)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: new-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
3.5 CRD(CustomResourceDefinition)版本演进
CRD 本身作为 API 资源,其版本演进直接影响自定义资源的定义方式。
- Kubernetes 1.7:
apiextensions.k8s.io/v1beta1(初始引入,功能有限) - Kubernetes 1.16:
apiextensions.k8s.io/v1(GA 版本,引入结构模式、版本转换等关键特性) - Kubernetes 1.22:
apiextensions.k8s.io/v1beta1被移除
迁移建议: 所有 CRD 定义应尽快迁移到
apiextensions.k8s.io/v1。v1 版本强制要求 spec.preserveUnknownFields: false(默认),并且必须提供 spec.versions[*].schema.openAPIV3Schema 结构模式。这有助于防止数据损坏,并支持自动版本转换。
# 检查 CRD 的 API 版本
kubectl get crd -o jsonpath='{range .items[*]}{.apiVersion}{"\n"}{end}' | sort -u
# 如果输出包含 v1beta1,则需要迁移
# 迁移时,需要将 CRD 定义中的 apiVersion 改为 apiextensions.k8s.io/v1
# 并确保包含完整的 openAPIV3Schema 定义
3.6 核心资源版本演进总览图
下图展示了 Deployment、StatefulSet、Ingress 和 CRD 四个核心资源从引入到 GA 再到旧版本移除的完整时间线。
3.7 版本迁移优先级与检查清单
根据上述演进史,制定以下迁移优先级:
- 最高优先级: 检查所有使用
extensions/v1beta1的资源(Deployment、Ingress、DaemonSet、ReplicaSet、NetworkPolicy)。该版本在 1.16 已被移除。 - 高优先级: 检查所有使用
apps/v1beta1和apps/v1beta2的资源(Deployment、StatefulSet、DaemonSet、ReplicaSet)。该版本在 1.16 已被移除。 - 中优先级: 检查所有使用
networking.k8s.io/v1beta1的 Ingress 资源。该版本在 1.22 已被移除。 - 低优先级: 检查所有使用
apiextensions.k8s.io/v1beta1的 CRD 定义。该版本在 1.22 已被移除。
自动化检查命令:
# 一键扫描集群中所有废弃 API 版本的使用情况
kubectl get --raw /openapi/v2 | jq -r '.paths | keys[]' | grep -E '(extensions/v1beta1|apps/v1beta1|apps/v1beta2|networking.k8s.io/v1beta1|apiextensions.k8s.io/v1beta1)' | sort -u
3.8 版本迁移工具与最佳实践
| 工具/方法 | 适用场景 | 命令示例 |
|---|---|---|
| kubectl convert | 本地 YAML 文件版本转换 | kubectl convert -f old.yaml --output-version apps/v1 |
| kubectl get + patch | 集群中已有资源的原地升级 | kubectl get deploy my-deploy -o yaml | sed 's|extensions/v1beta1|apps/v1|' | kubectl apply -f - |
| kubectl-neat + jq | 清理冗余字段后转换 | kubectl neat old.yaml | kubectl convert -f - --output-version apps/v1 |
| API 版本检查器(第三方) | 大规模集群批量扫描 | kubectl-version-checker --kubeconfig ~/.kube/config |
最佳实践: 在升级集群之前,先在测试环境中运行
kubectl convert --validate=true 验证所有转换后的 YAML 文件。同时,建议使用 GitOps 工作流,将转换后的资源定义提交到版本控制系统,确保可追溯性。