在 VMware vSphere 上升级集群

本文介绍如何在平台侧发行版升级完成后,在 VMware vSphere 上升级 Kubernetes 集群。本文档所述工作流重点是通过 Cluster API 资源更新控制平面和工作节点。本页面中的提供商行为和规则已针对 VMware vSphere Provider v1.0.17 进行验证。准入 Webhook 强制执行的规则列于提供商要求中。

INFO

本页面在完整 ACP 升级流程中的位置

本页面仅介绍升级中的 Kubernetes 步骤。完整的 ACP 升级流程包括升级工件同步、通过 CVO 升级 ACP Core、升级 Aligned 插件,以及从 Marketplace 升级 Agnostic 插件,详见 ACP 产品文档。在开始本页面中的 Kubernetes 步骤之前,请先完成以下步骤:

当同一集群运行在 Alauda OS 上时,请使用本页面,因为其中的 Kubernetes 步骤会从新的 VM 模板替换节点,而不是原地升级二进制文件。

升级顺序

请按以下顺序升级 VMware vSphere 集群:

  1. (前提条件) 首先升级管理集群上的 ACP 平台。此操作会将 cluster-api-provider-vsphere 控制器和相关 CAPI 组件升级到能够理解新架构的版本。提供商会更新其 CRD,并自行将现有资源迁移到新的字段布局,无需手动修改 YAML。请参阅升级提供商。只有在管理侧控制器完成推出并变为 Ready 后,才可触发业务集群升级。
  2. 完成升级集群中所述的发行版版本升级。
  3. 验证现有的 KubeadmControlPlane 和 MachineDeployment 清单是否满足推出规则。不满足规则的清单可能会阻止升级的第一次编辑。请参阅根据准入规则检查清单。
  4. 验证控制平面运行状况良好,并且当前集群稳定。
  5. 将 Kube-OVN 升级到目标 ACP 版本所需的 chart 版本,并等待 AppRelease 达到 Success。
  6. 升级控制平面的 Kubernetes 版本。
  7. 将工作节点升级到目标 Kubernetes 版本。

前置条件

开始之前,请确保满足以下条件:

  • 发行版版本升级已完成。
  • 控制平面运行正常且可访问。
  • 所有节点均处于 Ready 状态。
  • 已使用受支持的 ACP 备份操作步骤完成并验证最新的 etcd 备份。
  • 已在 vSphere 环境中准备好使用为目标 ACP 发行版发布的 Alauda OS 镜像构建的 VM 模板。如果应用新的 VSphereMachineTemplate 时该模板不存在,升级将失败。
  • 对于跨越多个 Kubernetes 次要版本的跨版本升级,已预先准备好中间版本的 Core 镜像和 VM 模板。请参阅跨版本升级准备。
  • 目标 Kubernetes 版本与您的工作负载和附加组件兼容。
  • machine config pool 具有足够的容量来执行滚动更新。
  • KubeadmControlPlane 将 spec.rolloutStrategy.rollingUpdate.maxSurge: 0 和 spec.replicas 设置为 3 或更高,并且每个 MachineDeployment 都将 spec.strategy.rollingUpdate.maxSurge: 0 设置为 1 或更高的 maxUnavailable。这些值使替换操作能够复用相同的插槽和磁盘标识,准入 webhook 会强制执行这些值。请在开始之前,通过根据准入规则检查清单进行验证。
  • 管理集群不是灾难恢复备用集群。针对备用集群时,provider 会跳过非 global 对象,并每 30 秒重新排队一次,因此滚动更新看起来像是尚未开始,而不是失败。请参阅备用管理集群。
  • 您知道此集群的 KubeadmControlPlane 名称。请从 Cluster.spec.controlPlaneRef.name 中读取;在 VMware vSphere 上创建集群中的清单将其命名为 <cluster_name>-kcp。
  • 如果集群使用 Self-built VIP(controlPlaneLoadBalancer.type: internal),则 VSphereCluster.status.conditions[SelfBuiltLoadBalancerReady] 为 True,并且新 VM 模板满足 Alive 内核前置条件(可以加载 ip_vs 模块系列,且允许使用 net.ipv4.vs.conntrack=1)。替换的控制平面节点将从该模板构建,provider 不会注入或验证这些设置。
  • 查看 Kubernetes 升级路径和版本偏差策略。
WARNING

滚动更新规则可能会拒绝现有集群的首次编辑

这些规则同样适用于 UPDATE 和 CREATE,因此现有集群可能包含不再被接受的值:

  • KubeadmControlPlane 的 rolloutStrategy.rollingUpdate.maxSurge 未设置 — Cluster API 默认值为 1;
  • 包含 replicas: 1 的 KubeadmControlPlane;
  • MachineDeployment 的 strategy.rollingUpdate.maxUnavailable 未设置 — Cluster API 默认值为 0。

拒绝发生在版本提升本身,因此升级会在替换任何内容之前停止。请在更早的单独编辑中修正这些值。对于由 pool 支持的模板,处于 replicas: 1 的 KubeadmControlPlane 在扩展到 3 之前完全无法升级;单副本控制平面不是受支持的固定 IP 拓扑。扩展它需要分两部分进行:向控制平面的 VSphereMachineConfigPool 添加另外两个插槽 — 主机名、静态地址和所需的持久磁盘 — 然后在同一 patch 中提升 replicas 并设置 maxSurge,因为两条规则会在同一次更新中检查。请参阅根据准入规则检查清单。

WARNING

磁盘保留模型

升级依赖 Cluster API 的滚动替换机制。每个集群有五类磁盘;只有由 pool 管理的持久类磁盘和外部 CSI 卷会在删除并重新创建后保留。

磁盘类别声明位置升级后是否保留用途
系统磁盘(根卷)用于 spec.template.spec.template 的 VM 模板❌ 从不保留OS + kubelet/kubeadm/containerd。每次替换都会从新模板重新构建。
模板本地磁盘VSphereMachineTemplate.spec.template.spec.*(模板中声明的附加磁盘)❌ 从不保留临时缓存。会随旧 VM 一起销毁。
pool 管理的临时磁盘VSphereMachineConfigPool.spec.configs[].ephemeralDisks[]❌ 从不保留 — VMDK 会随 VM 一起删除,并为替换节点创建新的空磁盘可重建的节点本地数据,不应存放在系统磁盘上,包括标准的 /var/lib/kubelet、/var/lib/containerd 和 /var/lib/etcd 磁盘。
pool 管理的持久磁盘VSphereMachineConfigPool.spec.configs[].persistentDisks[]✅ 从旧 VM 分离,并在相同插槽重新连接到新 VM平台状态,例如 /var/cpaas。
外部 CSI 卷(vSphere CSI 等)工作负载 PVC / CSI 驱动✅ 与节点生命周期无关原生应用数据。

与由 pool 管理的持久磁盘不同,临时磁盘不参与回收,也不会持有插槽释放,因此不会延迟滚动更新。请参阅选择持久磁盘或临时磁盘。

磁盘所属的类别在集群创建时即已确定。 ephemeralDisks[] 是 provider v1.0.17 中新增的内容。在更早版本的 provider 中创建的集群会将 /var/cpaas、/var/lib/containerd 和 /var/lib/etcd 声明为持久磁盘,并在 etcd 磁盘上设置 wipeFilesystem: true;升级不会改变这一点:provider 不会迁移任何磁盘,并且已分配的插槽会拒绝删除或重塑任一列表中的磁盘,因此无法将磁盘从一个列表移动到另一个列表。不要在升级过程中重构 pool 的磁盘列表 — 标准的持久磁盘加临时磁盘划分仅适用于新创建的集群。

“保留”表示重新连接相同的磁盘标识 — 并不表示磁盘内容会回到过去。升级窗口期间写入 pool 管理磁盘的任何内容都会在升级后以及回滚后继续保留。

WARNING

无法就地修改模板

VSphereMachineTemplate.spec.template.spec 是不可变的。vSphere 准入 webhook 会拒绝任何更新,并显示消息 "VSphereMachineTemplate spec.template.spec field is immutable. Please create a new resource instead."。因此,本页面中的每个升级步骤都会创建一个带有新 metadata.name 的新 VSphereMachineTemplate,应用该模板,然后将控制资源的 infrastructureRef.name patch 为新模板。请保留旧模板,直到新滚动更新运行正常,以便在需要时回滚。

INFO

Fleet Essentials 边界

Fleet Essentials 1.0.4 及更高版本可以通过 CVO 请求 ACP 4.3 及更高版本的发行版版本升级。但它不会执行本页面所述的 vSphere Kubernetes 和 Alauda OS 替换。请先使用 ACP 工作流完成阶段 1,然后使用以下 YAML 操作步骤完成阶段 2。

WARNING

已升级的集群无法使用 Self-built VIP

Self-built VIP 仅适用于使用 provider v1.0.17 或更高版本、且在 ACP v4.4 或更高版本上创建的集群。使用更早版本 provider 创建的集群在 provider 升级后仍会保留其外部 LoadBalancer,且无法迁移到 Self-built VIP:provider 会在第一个控制平面节点引导时注入 VIP,而运行中的控制平面不支持就地迁移。请参阅控制平面端点模式。

端点本身不会移动,升级也不是更改端点的时机。控制平面端点 — 模式以及 VIP 或 LoadBalancer 地址 — 会在部署集群时确定,此后固定不变;集群运行期间或升级期间都无法调整。现有集群无需执行任何操作,也不会获得任何操作:spec.controlPlaneLoadBalancer 保持未设置,这正是外部 LoadBalancer 的表现,而现在写入该字段会被拒绝。正因如此,该字段是可选的 — 在 Self-built VIP 出现之前创建的集群会在整个升级过程中保持其端点配置不变。请参阅升级 Provider。

OS Support Matrix 中的必需值

ACP 发行版、Kubernetes 版本以及匹配的 CoreDNS、etcd 和 Kube-OVN 版本之间的权威映射位于 OS Support Matrix 中。开始操作前,请找到与目标 ACP 版本对应的行;该行提供了以下操作步骤所需的组件值。

VM 模板名称不在矩阵中。它是根据目标 ACP 发行版所发布的 Alauda OS 镜像,在 vSphere 中创建模板时使用的名称 — 请参阅下载 Alauda OS — 并且必须将 VSphereMachineTemplate.spec.template.spec.template 设置为该名称,同时应用于控制平面模板和 worker 模板。

从该行读取的单元格按以下方式映射到升级清单:

OS Support Matrix 列用于设置写入位置
Kubernetes VersionKubeadmControlPlane.spec.version 和 MachineDeployment.spec.template.spec.version控制平面和 worker
corednsKubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration.dns.imageTag仅控制平面。仅设置标签 — provider 会自行设置 dns.imageRepository,该值从该标签中的 -v<acp> 后缀派生而来,并将 CoreDNS 和 kube-proxy 跳过注解添加到你的 KubeadmControlPlane 中。请参阅清单中的 Provider 管理字段
etcdKubeadmControlPlane.spec.kubeadmConfigSpec.clusterConfiguration.etcd.local.imageTag仅控制平面
kube-ovn (chart)Cluster.metadata.annotations["cpaas.io/kube-ovn-version"] 和由 provider 管理的 cni-kube-ovn AppRelease在更改 KubeadmControlPlane 前,完成完整的特定 provider 版本的 Kube-OVN 操作步骤。provider 版本和目标 chart 版本共同决定 chart 名称及受支持的协调流程。

CoreDNS 和 etcd 镜像标签仅适用于控制平面,因为 clusterConfiguration 是一个 KubeadmControlPlane 字段。worker 节点从新 VM 模板继承容器镜像版本;MachineDeployment 不包含自身的 dns/etcd 标签。Kube-OVN 注解位于 Cluster 资源上,而不是 KubeadmControlPlane 上,因为 vSphere provider 独立于 Kubernetes 控制平面滚动更新监视该资源。

操作步骤

根据准入规则检查清单

在更改任何内容前,读取当前值:

kubectl -n <namespace> get kubeadmcontrolplane <cluster_name>-kcp \
  -o jsonpath='replicas={.spec.replicas} maxSurge={.spec.rolloutStrategy.rollingUpdate.maxSurge}{"\n"}'

kubectl -n <namespace> get machinedeployment -o custom-columns='NAME:.metadata.name,TYPE:.spec.strategy.type,SURGE:.spec.strategy.rollingUpdate.maxSurge,UNAVAIL:.spec.strategy.rollingUpdate.maxUnavailable'

空的 maxSurge 或 UNAVAIL 值表示该字段未设置,而未设置意味着 Cluster API 默认值 — 分别为 1 和 0。这两个默认值都不适用于由池支持的控制器。在提升版本前修正这些值:

# replicas is already 3 or more: correct maxSurge on its own.
kubectl -n <namespace> patch kubeadmcontrolplane <cluster_name>-kcp --type='merge' \
  -p='{"spec":{"rolloutStrategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":0}}}}'

# replicas is 1: set replicas and maxSurge in the same patch. Declare the two extra
# control-plane slots first.
kubectl -n <namespace> patch kubeadmcontrolplane <cluster_name>-kcp --type='merge' \
  -p='{"spec":{"replicas":3,"rolloutStrategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":0}}}}'

kubectl -n <namespace> patch machinedeployment <cluster_name>-md-0 --type='merge' \
  -p='{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":0,"maxUnavailable":1}}}}'

Webhook 会在每次更新 KubeadmControlPlane 时评估 maxSurge 和 replicas 规则,并同时报告这两条规则。因此,在 replicas: 1 集群上,只修正其中一项的补丁会被另一项拒绝。对于已有三个或更多控制平面的控制平面,切勿修补 replicas;上面的值是下限,而不是目标值。

使用 strategy.type: OnDelete 的 MachineDeployment 不受这两条规则限制,因为 OnDelete 已经先删除旧机器,再替换为新机器。

开始前,确认池运行正常:

kubectl -n <namespace> get vspheremachineconfigpool
kubectl -n <namespace> get vspheremachineconfigpool <cluster_name>-cp-pool \
  -o jsonpath='{range .status.conditions[*]}{.type}={.status} ({.reason}){"\n"}{end}'

应看到 Ready=True、MembersValid=True、MembersUnique=True 和 PersistentDisksReady=True。在已完全分配的池中,SlotAvailable 合理地可能为 False;它不属于 Ready 摘要。

在控制平面之前升级 Kube-OVN

按照在控制平面之前升级 Kube-OVN操作步骤执行,并选择与已安装 provider 版本匹配的 VMware vSphere 选项卡:仍使用 v1.0.15 或更早版本的集群应遵循旧版选项卡,而目标为 Kube-OVN v4.4 或更高版本时,必须先将 provider 升级到 v1.0.16 或更高版本。共享操作步骤包含 vSphere 特定的网络注解检查、Kube-OVN v4.4 中的 chart 名称迁移,以及所需的 AppRelease 健康检查。不要手动修补 chart 源;provider 会根据注解对其进行协调。

创建目标机器模板

开始滚动升级前,为控制平面和 worker 创建新的 VSphereMachineTemplate 资源。

  1. 导出现有控制平面模板

    kubectl get vspheremachinetemplate <cluster_name>-control-plane -n <namespace> -o yaml > new-cp-template.yaml
  2. 修改控制平面模板

    编辑 new-cp-template.yaml:

    • 将 metadata.name 设置为新的唯一名称(例如 <cluster_name>-control-plane-v2)
    • 将 spec.template.spec.template 更新为目标 VM 模板名称
    • 根据需要更新 CPU、内存或磁盘设置
    • 删除服务器生成的字段:metadata.resourceVersion、metadata.uid、metadata.generation、metadata.creationTimestamp、metadata.managedFields、metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"] 和 status
    • 保持 spec.template.spec.providerID 未设置。vSphere provider 会在 VM 创建后将 providerID 设置为该 VM 的 BIOS UUID;在模板中预先填充该值会破坏控制器的身份绑定。
  3. 导出并修改 worker 模板

    kubectl get vspheremachinetemplate <cluster_name>-worker -n <namespace> -o yaml > new-worker-template.yaml

    编辑 new-worker-template.yaml:

    • 将 metadata.name 设置为新的唯一名称(例如 <cluster_name>-worker-v2)
    • 将 spec.template.spec.template 更新为目标 VM 模板名称
    • 根据需要更新 CPU、内存或磁盘设置
    • 删除上面列出的相同服务器生成字段
  4. 应用两个新模板

    kubectl apply -f new-cp-template.yaml
    kubectl apply -f new-worker-template.yaml

升级控制平面

开始前,完成共享的在控制平面之前升级 Kube-OVN操作步骤,并使用 phase=Success 验证 cni-kube-ovn AppRelease 已处于目标修订版本。然后,按照OS Support Matrix 中的必需值中的说明,从 OS Support Matrix 的目标 ACP 行收集所有必需的控制平面值。

  1. 使用目标 Kubernetes 值修补 KubeadmControlPlane

    在一次编辑中更新 KubeadmControlPlane 资源,使 spec.version、CoreDNS 镜像标签、etcd 镜像标签以及基础设施模板引用都与同一 VM 模板保持一致:

    • spec.version ← OS Support Matrix 行中的 Kubernetes Version

    • spec.kubeadmConfigSpec.clusterConfiguration.dns.imageTag ← 同一行中的 coredns 列

    • spec.kubeadmConfigSpec.clusterConfiguration.etcd.local.imageTag ← 同一行中的 etcd 列

    • spec.machineTemplate.infrastructureRef.name ← 上面创建的新 VSphereMachineTemplate 名称

    • 当目标为 Kubernetes 1.35 或更高版本时,在同一次编辑中更新 spec.kubeadmConfigSpec.files 中的 /etc/kubernetes/patches/kubeletconfiguration0+strategic.json,如针对 Kubernetes 1.35 的必需 kubelet 补丁中所述

      kubectl edit kubeadmcontrolplane <cluster_name>-kcp -n <namespace>

    仅更新 spec.version 是不够的。CoreDNS 和 etcd 镜像标签必须随 Kubernetes 版本一起更新,因为它们基于同一发行版本构建;如果保留之前的值,CoreDNS 和 etcd Pod 可能与新的 Kubernetes 次版本不匹配。

    INFO

    provider 完成协调后,预期在刚才编辑的对象上看到 CoreDNS 和 kube-proxy 跳过注解,以及由控制器设置的 dns.imageRepository。不要删除这些内容,也不要重新应用缺少这些内容的已存储清单。业务集群的 kube-proxy DaemonSet 和 CoreDNS Deployment 仓库会分别进行协调,并且仅在此次滚动更新完成后才会协调,因此那里出现延迟是正常的。请参阅清单中的 Provider 管理字段。

    在 Self-built VIP 集群上,Alive 会在整个滚动更新期间保留 VIP。引导 VIP 仅注入原始 kubeadm init 节点;替换后的控制平面节点通过 VIP 加入,并且永远不会获得该 VIP。随着控制平面成员发生变化,provider 会根据当前控制平面节点地址更新 Alive 后端列表。请保留 maxSurge: 0 — VIP 和 etcd 仲裁都依赖一次替换一个节点。

  2. 监控控制平面滚动更新

    kubectl -n <namespace> get kubeadmcontrolplane <cluster_name>-kcp -w
    kubectl -n <namespace> get machine -l cluster.x-k8s.io/control-plane

升级 worker 节点

控制平面升级完成后,更新 MachineDeployment,使其引用新的 worker 模板和目标 Kubernetes 版本。

典型变更包括:

  • spec.template.spec.version — 目标 Kubernetes 版本
  • spec.template.spec.infrastructureRef.name — 新的 VSphereMachineTemplate 名称
  • spec.template.spec.bootstrap.configRef.name — 新的 KubeadmConfigTemplate 名称。Kubernetes 1.35 或更高版本必须进行此项设置,以便 worker 接收必需的 kubelet 补丁;对于更早的版本,仅当其他引导设置也需要更改时才进行修改。请参阅更新引导模板。

下面的补丁仅更改 spec.template.spec。如果预检检查显示需要修正 MachineDeployment 策略,则必须已经应用该修正 — 携带不合规策略的更新会被整体拒绝,包括版本字段。

应用这些更改:

以下命令包含 Kubernetes 1.35 或更高版本所需的引导引用。对于不需要更改引导配置的更早目标版本,请省略 bootstrap 对象。

kubectl patch machinedeployment <cluster_name>-md-0 -n <namespace> \
  --type='merge' -p='{
    "spec": {
      "template": {
        "spec": {
          "version": "<target_kubernetes_version>",
          "infrastructureRef": {
            "name": "<new-worker-template-name>"
          },
          "bootstrap": {
            "configRef": {
              "name": "<new-bootstrap-template-name>"
            }
          }
        }
      }
    }
  }'

监控 worker 滚动更新:

kubectl -n <namespace> get machinedeployment <cluster_name>-md-0 -w
kubectl -n <namespace> get machine
kubectl --kubeconfig=/tmp/<cluster_name>.kubeconfig get nodes -o wide

不更改 Kubernetes 版本的 OS Image 更新

使用此操作步骤可在 Kubernetes 版本保持不变的情况下,将节点迁移到新的 Alauda OS 镜像上 — 例如,获取 OS 安全修复,或将Pod 日志目录迁移应用到现有节点。

  1. 按照创建目标机器模板中的导出、清理和重命名操作步骤,创建新的 VSphereMachineTemplate 资源。仅将 spec.template.spec.template 更改为新的 VM 模板名称。
  2. 应用这两个新模板。
  3. 修补 KubeadmControlPlane.spec.machineTemplate.infrastructureRef.name,等待控制平面滚动更新完成,然后修补 MachineDeployment.spec.template.spec.infrastructureRef.name。

不要修改 spec.version、clusterConfiguration.dns.imageTag、clusterConfiguration.etcd.local.imageTag 或 cpaas.io/kube-ovn-version 注解。OS 镜像滚动更新不是 Kubernetes 版本跃升,因此不需要先更新 Kube-OVN。

相同的滚动更新规则仍然适用:两个控制器均为 maxSurge: 0,每个 MachineDeployment 至少为 maxUnavailable 个 1。由池管理的持久磁盘会像版本升级时一样重新挂载,由池管理的临时磁盘则会被销毁并以空磁盘重新创建。

要恢复,请将控制资源指回之前的模板。这是从失败的第 2 阶段升级中恢复的第 2 阶段。

并非失败的滚动更新暂停

某些滚动更新暂停是 provider 为保护数据而采取的措施。不要手动清除这些暂停。

附件安全暂停。删除 VSphereVM 时,provider 会扫描数据中心,查找仍挂载该槽位持久磁盘后端的 VM。只要其中任一磁盘仍处于挂载状态,provider 就会保留 finalizer 并重新入队。相同的检查也会保护池回收。滚动更新在删除第一个旧机器时看似停滞,通常是因为此暂停,而不是缺陷。不要移除 finalizer。

读取当前状态:

kubectl -n <namespace> get vspheremachineconfigpool <pool_name> \
  -o jsonpath='{range .status.persistentDiskStatuses[*]}{.hostname}{" "}{.name}{" "}{.phase}{" owner="}{.ownerMachineName}{" err="}{.lastError}{"\n"}{end}'
kubectl -n <namespace> get vspherevm -o custom-columns='NAME:.metadata.name,DELETED:.metadata.deletionTimestamp,FINALIZERS:.metadata.finalizers'

正常的交接顺序是先执行 Attached,旧 VM 消失后执行 Available,然后在替换节点上再次执行 Attached。ownerMachineName 和 ownerMachineUID 会在删除和重新创建过程中保留,因此替换节点会重新挂载相同的磁盘。

Reclaimed 是墓碑。 不要删除 phase: Reclaimed 条目来解除滚动更新停滞。有关删除该条目会导致重新播种循环的原因,请参阅集群创建页面上的故障排除。

SlotAvailable=False 是预期行为。 使用 maxSurge: 0 且池已完全分配时,只有删除旧机器后才会有空闲槽位。SlotAvailable 会从池的 Ready 摘要中排除,正是为了避免将此情况显示为失败。

在 vCenter 中关闭电源的节点会保持关闭状态。 一旦 VSphereVM 锁定 InitialPowerOnCompleted=True,控制器就不会再强制启动已关闭电源的 VM。滚动更新期间创建的替换 VM 未设置该锁定状态,因此在升级前被主动关闭电源的节点会在替换后恢复为开机状态。

从失败的阶段 2 升级中恢复

不要将 Kubernetes 次要版本降级视为普通回滚。根据滚动更新阶段选择恢复路径:

  1. 尚未创建目标版本控制平面 Machine:恢复之前的 Kube-OVN 注解,以及之前的 KubeadmControlPlane 和 MachineDeployment manifest 值。这会在引入新的控制平面数据格式之前取消目标滚动更新。
  2. 仅机器模板或 OS 镜像发生了变化,Kubernetes 次要版本未发生变化:将控制资源指回之前的模板。Cluster API 会执行另一次替换滚动更新。保持 Kubernetes 次要版本不变。
  3. 目标 Kubernetes 次要版本上的控制平面 Machine 已加入集群:不要将 Kubernetes、CoreDNS 或 etcd 修补回之前的次要版本。停止进一步的滚动更新,在目标次要版本上向前修复,或使用受支持的 ACP 恢复操作步骤从已验证的升级前备份恢复集群。

如果已创建目标次要版本的控制平面 Machine,但它从未加入集群,请先恢复健康的 etcd 仲裁,并确定是否可以安全地移除失败的替换节点。不要假定仅更改版本字段就足够。

在任何恢复过程中,请牢记以下基础设施事实:

  • 旧 VM 已不存在。 它们在升级期间已被销毁。模板恢复会创建一组全新的替换机器;它不会恢复原始 VM。
  • 旧的 VSphereMachineTemplate 资源必须仍然存在。 在新的滚动更新恢复健康之前,不要删除之前的模板。如果已经删除,请在尝试相同次要版本的模板恢复之前,从版本控制或备份中重新创建它。
  • 池管理的磁盘标识会保留,但数据状态不会保留。 VSphereMachineConfigPool.spec.configs[].persistentDisks[] 中声明的磁盘会在相同槽位重新挂载到替换机器,但升级窗口期间写入的数据仍保留在这些磁盘上。
  • 临时磁盘已丢失。 VSphereMachineConfigPool.spec.configs[].ephemeralDisks[] 上的数据会随每个被替换的 VM 一起销毁,无法从池中恢复。只有池管理的持久磁盘会重新挂载。
  • 不要撤销滚动更新规则修正。 如果阶段 1 要求恢复之前的 manifest 值,请将 maxSurge 保持为 0,并将 maxUnavailable 保持为 1 或更高值。恢复旧的、不符合要求的值不会被接受。

对于阶段 1,请使用阶段 1 恢复期间恢复 Kube-OVN中的 vSphere 规则。provider 会根据注解恢复 chart。等待恢复的 AppRelease 通过共享验证后,再更改控制平面 manifest。

KubeadmControlPlane 控制器可能会在 etcd 不健康时阻止替换。在重试任何安全的替换操作之前,请先恢复仲裁。

验证

升级后读取池状态:

kubectl -n <namespace> get vspheremachineconfigpool
kubectl -n <namespace> get vspheremachineconfigpool <pool_name> \
  -o jsonpath='{range .status.persistentDiskStatuses[*]}{.hostname}{" "}{.name}{" "}{.phase}{"\n"}{end}'

确认以下结果:

  • KubeadmControlPlane 达到目标版本和所需的从节点数量。
  • MachineDeployment 达到目标版本和所需的从节点数量。
  • 控制平面和工作节点恢复为 Ready 状态。
  • vSphere CPI daemonset 在业务集群中仍可用。
  • 每个 VSphereMachineConfigPool 报告 Ready=True 和 PersistentDisksReady=True,其 ALLOCATED 数量等于从该池中取出的运行中 Machine 数量,并且其 TOTAL 数量保持不变。
  • 已分配槽位上的每个持久磁盘都报告 phase: Attached。

故障排除

问题检查内容
KubeadmControlPlane 或 MachineDeployment 上的 kubectl edit 或 kubectl patch 被拒绝运行预检。有关完整的消息到原因映射,请参阅准入拒绝。
删除第一个机器后滚动更新停滞通常是卷附件安全暂停,而不是缺陷。请参阅并非故障的滚动更新保持。
池报告 Ready=True,但 SlotAvailable=False在 maxSurge: 0 滚动更新期间,已完全分配的池出现此情况是正常的。SlotAvailable 不包含在 Ready 摘要中。
被替换节点的磁盘为空确认磁盘声明在哪个列表中。在 v1.0.17 或更高版本上创建的集群中,/var/lib/kubelet、/var/lib/containerd 和 /var/lib/etcd 按设计为临时磁盘,每次替换时都会以空磁盘启动。在较旧的集群中,它们是持久磁盘,因此还要检查 wipeFilesystem;根据设计,它在 etcd 磁盘上为 true。
没有任何资源进行协调,没有条件发生变化,也没有显示错误管理集群可能是灾难恢复备用集群。请参阅备用管理集群。
工作负载节点已关闭且未恢复一旦 InitialPowerOnCompleted 锁定,这就是预期行为。在 vCenter 中将其开机。请参阅并非故障的滚动更新保持。
新的控制平面机器始终无法引导读取 VSphereVM 和 VSphereMachine 上的 BootstrapReady 条件;原因是 BootstrapSecretGetFailed 和 BootstrapSecretContentInvalid。
Kube-OVN 注解已更改,但 chart 名称或修订版本未趋于一致按照共享的 Kube-OVN 操作步骤执行。不要手动修补 chart 源。
控制平面达到目标版本后,业务 kube-proxy 或 coredns 仍使用旧的镜像仓库预期的延迟 — 这些资源仅在控制平面滚动更新完成后才会进行协调。请参阅manifest 中由 provider 管理的字段。
VSphereMachineTemplate 更新因不可变而被拒绝在新名称下创建新模板。请参阅本页顶部附近的警告。

后续步骤

Kubernetes 升级完成后,请继续参阅在 VMware vSphere 上管理节点执行常规节点操作。