将现有 Huawei DCS 集群迁移到池托管持久磁盘

当你将现有 Huawei DCS 集群从较旧的模板磁盘布局升级到当前的池托管持久磁盘模型时,请使用本指南。

在 DCS provider v1.0.16 或更高版本中,此迁移通过 YAML 驱动,因为 DCSIpHostnamePool.spec.pool[].persistentDisk 在 Web UI 中不可见。

INFO

版本

当集群运行 ACP v4.2.1 或更高版本,并且目标 DCS provider 版本为 v1.0.16 或更高版本时,请使用此操作步骤。

此操作步骤当前假定以下所有条件都成立:

  • 目标环境使用支持池托管持久磁盘的 DCS controller 实现。
  • DCS VM 模板为 4.2.1 或更高版本。
  • Guest tools(vmtools)在 guest OS 内正常工作,以便能够完成安全关机和磁盘分离。

概述

较旧的 DCS 集群通过 DCSMachineTemplate 创建可复用的数据磁盘。该布局无法向 controller 提供足够的信息,以便在删除后重新创建替换时安全保留磁盘。

当前模型将升级时需要保留的磁盘移动到 DCSIpHostnamePool.spec.pool[].persistentDisk 中。每个磁盘都绑定到一个 (ip, slot) 标识。在滚动替换期间,controller 会执行以下步骤:

  1. 从旧 VM 中接管现有磁盘。
  2. 安全停止旧 VM。
  3. 分离磁盘。
  4. 在需要时,将标准卷转换为独立持久卷。
  5. 删除旧 VM。
  6. 将磁盘重新连接到替换 VM。
  7. 启动替换 VM,后者会挂载现有文件系统,而不会重新格式化它。

这也是平台所要求的 /var/cpaas 磁盘的文档化模型。

开始之前

在开始之前,请确认以下所有内容:

  • 集群处于健康且当前稳定的状态。
  • 由于池托管持久磁盘需要逐个替换,因此相关 control plane 和 worker 的滚动策略都使用 maxSurge: 0
  • 你可以通过 DCS UI 或通过 DCS API 查询 VM 详情,识别旧 VM 上当前磁盘的 sequenceNum 值。
  • 你知道哪些磁盘必须保留,以及哪些磁盘仍然可以随 VM 一起重新创建。
  • 目标 DCSIpHostnamePool 已经存在,并且将每个 node 映射到固定的 IP slot。

检查当前磁盘布局

首先,识别管理集群对象以及承载每个 node 的 DCS VM:

kubectl get kubeadmcontrolplane -n cpaas-system
kubectl get machinedeployment -n cpaas-system
kubectl get machine -n cpaas-system
kubectl get dcsmachine -n cpaas-system
kubectl get dcsiphostnamepool -n cpaas-system

对于你计划迁移的任何 DCSMachine,请检查当前 VM 详情,并记录你想保留的每个磁盘的 sequenceNum、大小、datastore 和 PCI 类型。

你可以从以下位置收集这些信息:

  • DCS 平台 UI。
  • 你现有的运维工具,这些工具封装了 QueryVmInfo
  • 如果你的环境已经暴露了该工作流,也可以直接通过 API 检查。

对于每个要保留的磁盘,你需要以下值:

  • sequenceNum
  • quantityGB
  • datastoreNamedatastoreClusterName
  • path
  • format
  • pciType

确定哪些磁盘可以接管

现有集群只能接管位于旧 VM 磁盘布局尾部连续区域中的磁盘。

使用以下公式:

slot = oldSequenceNum - systemDiskCount - newTemplateDataDiskCount - 1

应用公式时,请使用以下常量:

  • systemDiskCount = 1
  • newTemplateDataDiskCount = 在 DCSMachineTemplate 中保留的非系统磁盘数量

计算得到的 slot 必须:

  • 大于或等于 0
  • 在同一个 IP 条目内唯一

如果某个磁盘不在尾部连续区域内,则你必须:

  • 将它与旧模板尾部之间的磁盘也一并移动到池托管持久磁盘列表中,或者
  • 接受该不可接管磁盘仍然会随旧 VM 一起丢失

示例

假设旧模板的磁盘顺序如下:

旧序号旧磁盘
1system disk
2/var/lib/kubelet
3/var/lib/etcd
4/var/lib/containerd
5/var/cpaas

如果新模板只保留 system + /var/lib/kubelet + /var/lib/containerd,那么 newTemplateDataDiskCount = 2

你要保留的磁盘sequenceNum新模板数据磁盘数计算得到的 slot可接管
/var/cpaas525 - 1 - 2 - 1 = 1
/var/lib/containerd/var/cpaas4, 514 - 1 - 1 - 1 = 1, 5 - 1 - 1 - 1 = 2
/var/lib/etcd323 - 1 - 2 - 1 = -1

更新 DCSMachineTemplate

就地编辑当前引用的 DCSMachineTemplate,使其不再声明你希望保留的磁盘。

  1. 导出当前模板:

    kubectl get dcsmachinetemplate <template-name> -n cpaas-system -o yaml > current-template.yaml
  2. 更新导出的 manifest:

    • 保留系统磁盘。
    • 仅保留那些仍应随 VM 一起重新创建的模板本地磁盘。
    • 删除所有你希望通过 IP pool 保留的磁盘。
    • 如果只有在同时移动尾随磁盘时目标磁盘才可接管,也要从模板中删除这些尾随磁盘。
    • 保留原始的 metadata.name,因为此迁移是在原位更新当前引用的模板。
    • 删除诸如 resourceVersionuidcreationTimestampmanagedFields 等临时元数据字段。
  3. 应用更新后的模板:

    kubectl apply -f current-template.yaml -n cpaas-system

更新 DCSIpHostnamePool

为每个保留的磁盘,在匹配的 IP slot 中添加 persistentDisk 条目。

该 spec 会通过三种方式与实时磁盘属性交互:

严格接管匹配。 其中任一字段不匹配都会导致接管失败,并设置 phase=ErrorlastError。controller 会在较慢的循环中重试,直到 spec 被更正:

  • quantityGB — 必须与实时磁盘大小完全一致
  • datastoreNamedatastoreClusterName — 必须指向与实时磁盘相同的存储目标
  • pciType — 必须与实时磁盘的 PCI 类型一致。如果省略,provider 将使用默认值 VIRTIO;在省略此字段之前,请先验证实时磁盘的 PCI 类型,因为非 VIRTIO 的实时磁盘可能会导致严格接管匹配失败

isThin 仅用于创建。它只会在 provider 创建新的 DCS 持久卷时发送。在现有卷接管期间不会参与比较,也不会转换现有卷。

文件系统(影响 guest 侧初始化,不影响接管检查):

  • format — 仅在初始化新磁盘时使用。如果实时磁盘已经存在文件系统,则会保留现有格式并跳过 mkfs

guest 侧(仅应用于替换 VM,不属于接管检查的一部分):

  • path — guest 内的挂载路径
  • mountOptions — 挂载选项
  • options — 仅在首次格式化时应用的 mkfs 选项

对于平台要求的 /var/cpaas 磁盘,请在此迁移中将其移动到池托管布局中。

slot 设置为上一节中计算得到的值。不要在不同的磁盘布局之间重复使用固定示例值。

示例:

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DCSIpHostnamePool
metadata:
  name: <iphostname-pool-name>
  namespace: cpaas-system
spec:
  pool:
  - ip: "<node-ip>"
    mask: "<mask>"
    gateway: "<gateway>"
    dns: "<dns>"
    hostname: "<hostname>"
    machineName: "<machine-name>"
    persistentDisk:
    - slot: <calculated-slot>
      quantityGB: 40
      datastoreClusterName: <datastore-cluster-name>
      path: /var/cpaas
      format: xfs
      pciType: VIRTIO

应用 pool 更新:

kubectl apply -f <updated-pool-file>.yaml -n cpaas-system

触发滚动升级

在触发替换之前:

  • 确认 KubeadmControlPlane.spec.rolloutStrategy.rollingUpdate.maxSurge = 0
  • 确认每个 MachineDeployment.spec.strategy.rollingUpdate.maxSurge = 0

这些设置是此迁移以及后续升级期间复用池托管持久磁盘的前提条件。

然后触发滚动:

kubectl patch kubeadmcontrolplane <kcp-name> -n cpaas-system \
  --type='merge' \
  -p='{"spec": {"rolloutAfter": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}}'
kubectl patch machinedeployment <md-name> -n cpaas-system \
  --type='merge' \
  -p='{"spec": {"rolloutAfter": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}}'

验证接管、分离、转换和重新连接

在滚动期间监视管理集群资源:

kubectl get kubeadmcontrolplane <kcp-name> -n cpaas-system -w
kubectl get machinedeployment <md-name> -n cpaas-system -w
kubectl get machine -n cpaas-system -w

检查 pool 状态,确认 controller 已接管并跟踪这些磁盘:

kubectl get dcsiphostnamepool <iphostname-pool-name> -n cpaas-system -o yaml

在迁移过程中,每条记录都会显示在 status.persistentDiskStatus 下。需要关注的稳定阶段如下:

  • 当旧 VM 仍然拥有磁盘时,phase: Attached
  • 磁盘分离后为 phase: Available(必要时,还会从标准卷转换为独立持久卷)
  • 替换 VM 重新连接磁盘后再次变为 phase: Attached

在相应操作期间,可能会短暂出现过渡阶段(AttachingDetaching);当磁盘被永久删除时会出现 Deleting,例如在 pool 或集群清理期间。完整的阶段集合为 CreatingAvailableAttachingAttachedDetachingDeletingError

如果某个磁盘进入 phase: Error,请在重试前检查 lastError

限制和恢复说明

  • 在现有集群迁移路径中,只有尾部连续磁盘可以被接管。
  • controller 仅保护在 persistentDisk 中声明的磁盘。任何未声明的磁盘仍然遵循 VM 生命周期,并可能随旧 VM 一起被删除。
  • 此迁移会更改保留磁盘的所有权模型。不要在 DCSMachineTemplateDCSIpHostnamePool 中同时定义同一个磁盘。
  • 如果你需要保留 /var/cpaas,请在此次迁移中将其移动到 IP pool 中,而不是将其保留在模板里。
  • 本操作指南适用于运行在 ACP v4.2.1 或更高版本、并迁移到 DCS provider v1.0.16 或更高版本的集群。

相关主题