排查卡在 Deleting 状态的集群

适用范围

本页描述的是这样一种情况:一个由 ACP 创建的业务集群正在删除,所有子资源(各 provider 对应的 Machine CR 以及它们所代表的 IaaS VM)都已经消失,但顶层 Cluster CR 仍然无限期停留在 Phase: Deleting

本页适用于任何由 ACP 创建的业务集群,不受底层 IaaS 类型限制:

  • 华为 DCS(DCS Provider)
  • 华为云 Stack(HCS Provider)
  • VMware vSphere(vSphere Provider)
  • Immutable Infrastructure 上的裸金属(baremetal Provider)
  • 通过 cluster-manager 管理的 SSH UPI 路径创建的集群

直接观测证据来自 DCS;其他 provider 共享相同的 global 集群控制平面路径。

不在适用范围内:

症状

Cluster CR 会显示如下模式。

查看位置现象
global 集群上的 Cluster.status.phaseDeleting,持续时间远超预期——通常从一小时到数小时不等。
Cluster.metadata.deletionTimestamp已设置。
Cluster.metadata.finalizers仍然包含 capi.cpaas.io/imported
Cluster.spec.infrastructureRefCluster.spec.controlPlaneRef二者都已设置(例如 infrastructureRef.kind: DCSClustercontrolPlaneRef.kind: KubeadmControlPlane)。这表明这是一个由 ACP 创建的集群——第三方集群没有这两个引用。
同一命名空间中的 provider 特定 Machine CR(DCSMachine / HCSMachine / VSphereMachine / 等),以及匹配的 infrastructure ClusterKubeadmControlPlaneMachineDeploymentMachine 资源都已不存在——级联删除已经完成。
IaaS 平台本身(DCS 门户、vCenter、HCS 门户、裸金属 inventory)该集群的 VM 都已不存在。
provider controller 日志(例如 cluster-api-provider-dcs-manager显示机器删除成功的日志项,例如 removed DCSMachine finalizer

capi.cpaas.io/imported finalizer(以及可能存在的 capi.cpaas.io/alauda-cluster: imported label)本身并意味着该集群是导入的——由 ACP 创建的集群也会携带这些内容。请使用上面的 infrastructureRef / controlPlaneRef 行来区分二者。

诊断

global 集群上运行下面两个检查,以确认该模式。

确认 capi.cpaas.io/imported finalizer 仍然存在:

kubectl get cluster <name> -n <ns> -o yaml | grep -A 2 finalizers

确认该集群是由 ACP 创建的。由 ACP 创建的集群会同时设置 spec.infrastructureRefspec.controlPlaneRef;第三方集群(通过导入接入)则两者都没有:

kubectl get cluster <name> -n <ns> \
  -o jsonpath='infrastructureRef={.spec.infrastructureRef.kind} controlPlaneRef={.spec.controlPlaneRef.kind}{"\n"}'

如果这两个值都非空(例如 infrastructureRef=DCSCluster controlPlaneRef=KubeadmControlPlane),则该集群是由 ACP 创建的,本页中的 workaround 适用。如果二者都为空,则该集群是作为第三方集群接入的;本页不适用,也不得使用下面的 workaround。

原因

Cluster CR 上的 capi.cpaas.io/imported finalizer 由 global 集群上的平台 controller 管理。对于作为第三方集群接入的集群,当集群被移除时,该 finalizer 会作为平台侧清理的一部分被释放。

由 ACP 创建的集群也带有相同的 finalizer。当一个由 ACP 创建的集群被删除时,其子资源和 IaaS VM 会被正确移除,但顶层 Cluster CR 上的 capi.cpaas.io/imported finalizer 不会被释放——因此该 CR 会一直停留在 Deleting

这是一种平台级行为,不是任何 IaaS provider 的故障,也不会影响导入的(第三方)集群。具体处理方式正在由平台团队调查中。

解决方法

在清除 finalizer 之前,请先确认没有任何对象依赖 Cluster CR 继续存在——所有子资源以及所有 IaaS VM 都必须已经消失。

步骤 1 — 确认命名空间中的所有 provider 特定 Machine CR 都已消失:

# Replace dcsmachines with the resource for your provider (hcsmachines, vspheremachines, ...).
kubectl get dcsmachines,hcsmachines,vspheremachines -n <ns>

# Also confirm the higher-level CAPI resources are gone:
kubectl get machines,machinedeployments,kubeadmcontrolplanes,dcsclusters,hcsclusters,vsphereclusters -n <ns>

每条命令都必须返回该集群没有任何资源。

步骤 2 — 确认该集群的 VM 已在 IaaS 平台上删除。 使用 provider 特定的验证方式:

  • DCS:通过 DCS 门户或 DCS API 列出 VM,确认该集群的 VM 已全部不存在。相关集群字段请参见 在 Huawei DCS 上创建集群
  • HCS:在 HCS 门户中列出 VM,并确认已全部不存在。
  • vSphere:在 vCenter 中、集群文件夹下列出 VM,并确认已全部不存在。
  • 裸金属:在 bare-metal inventory 中确认机器的 deprovisioning 已完成。

步骤 3 — 仅在步骤 1 和步骤 2 都确认没有剩余资源之后,再清除 Cluster CR 的 finalizers:

kubectl patch cluster <name> -n <ns> --type=merge \
  -p '{"metadata":{"finalizers":null}}'

Cluster CR 会立即消失。由于在执行此步骤之前,所有子资源和所有 IaaS VM 都已经消失,因此移除顶层 finalizer 不会留下孤儿对象——它只是清除了一个已经不再有任何 reconciler 会释放的标记。

为什么不直接等待?

finalizer 不会在计时器到期后自动释放,而且对于由 ACP 创建的集群,它也不会通过正常的平台清理路径释放。等待不会改变状态——已有持续九小时或更长时间仍无进展的观测记录。请在步骤 1 和步骤 2 确认后应用该 workaround。

永久修复

修复应在 global 集群控制平面中完成:当由 ACP 创建的集群的子资源都已消失后,必须释放其 capi.cpaas.io/imported finalizer。此问题的跟踪不在本文档范围内;这里不会承诺具体发布日期。在修复落地之前,上述 workaround 是受支持的恢复路径。

另请参见