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

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

此迁移由 YAML 驱动,因为 DCSIpHostnamePool.spec.pool[].persistentDisk 未在 Web UI 中公开。

INFO

版本

当集群运行 ACP v4.2.1 或更高版本时,请使用此操作步骤。

此操作步骤目前假设满足以下所有条件:

  • DCS VM 模板为 4.2.1 或更高版本。
  • Guest tools(vmtools)在 guest OS 中正常工作,以便完成安全关机和磁盘分离。

概述

较早创建的 DCS 集群通过 DCSMachineTemplate 创建可重复使用的数据磁盘。该布局无法为控制器提供足够的信息,以便在删除并重新创建实例时安全地保留磁盘。

当前模型会将升级期间保留的磁盘移入 DCSIpHostnamePool.spec.pool[].persistentDisk。每个磁盘都绑定到一个 (ip, slot) 身份。在滚动替换期间,控制器会执行以下操作:

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

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

开始之前

开始前,请确认以下所有事项:

  • 集群运行正常且当前保持稳定。
  • 由于池管理的持久磁盘需要逐个替换,因此相关控制平面和工作节点的发布策略使用 maxSurge: 0。
  • 您可以从 DCS UI 中识别旧 VM 上当前的磁盘 sequenceNum 值,或通过 DCS API 查询 VM 详细信息。
  • 您知道哪些磁盘必须保留,以及哪些磁盘仍可随 VM 一起重新创建。
  • 目标 DCSIpHostnamePool 已存在,并将每个节点映射到固定的 IP 槽位。

检查当前磁盘布局

首先,确定管理集群对象以及为每个节点提供支持的 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、大小、数据存储和 PCI 类型。

您可以通过以下方式收集这些信息:

  • DCS 平台 UI。
  • 封装 QueryVmInfo 的现有运维工具。
  • 如果您的环境已提供相应工作流,也可以直接检查 API。

每个要保留的磁盘都需要以下值:

  • 旧 sequenceNum
  • quantityGB
  • datastoreName 或 datastoreClusterName
  • path
  • format
  • pciType

确定哪些磁盘可声明

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

使用以下公式:

slot = oldSequenceNum - systemDiskCount - newTemplateDataDiskCount - 1

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

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

计算得出的 slot 必须:

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

如果磁盘不在尾部连续区域中,则必须采取以下措施之一:

  • 将它与旧模板末尾之间的磁盘也移入池管理的持久磁盘列表,或
  • 接受该不可声明的磁盘仍会随旧 VM 一起丢失

示例

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

旧序号旧磁盘
1系统磁盘
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. 更新导出的清单:

    • 保留系统磁盘。
    • 仅保留仍应随 VM 一起重新创建的模板本地磁盘。
    • 移除要通过 IP 池保留的所有磁盘。
    • 如果只有同时移动末尾磁盘才能声明目标磁盘,也要从模板中移除这些末尾磁盘。
    • 保留原始 metadata.name,因为此迁移会就地更新当前引用的模板。
    • 移除 resourceVersion、uid、creationTimestamp 和 managedFields 等临时元数据字段。
  3. 应用更新后的模板:

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

更新 DCSIpHostnamePool

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

此规范会通过以下三种方式与实时磁盘属性交互:

严格声明匹配。其中任一字段不匹配都会导致声明失败,并设置带有 lastError 的 phase=Error。控制器会以较慢的循环持续重试,直到规范得到更正:

  • quantityGB — 必须与实时磁盘大小完全匹配
  • datastoreName 或 datastoreClusterName — 必须指向与实时磁盘相同的存储目标
  • pciType — 必须与实时磁盘的 PCI 类型匹配。如果省略,provider 将使用默认值 VIRTIO;省略此字段前,请先验证实时磁盘的 PCI 类型,因为非 VIRTIO 的实时磁盘可能无法通过严格声明匹配

isThin 仅用于创建。只有在 provider 创建新的 DCS 持久卷时才会发送此字段。现有卷声明期间不会比较此字段,也不会转换现有卷。

文件系统(影响来宾端初始化,不影响声明检查):

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

来宾端(仅应用于替换 VM,不属于声明检查的一部分):

  • path — 来宾内部的挂载路径
  • 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

应用池更新:

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

检查池状态,确认控制器已声明并跟踪这些磁盘:

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

在转换期间,每条记录都会显示在 status.persistentDiskStatus 下。需要关注的稳定阶段包括:

  • 旧 VM 仍拥有磁盘时为 phase: Attached
  • 磁盘分离后为 phase: Available(如果需要,还会从 stock 卷转换为独立持久卷)
  • 替换 VM 重新连接磁盘后再次为 phase: Attached

在相应操作期间,可能会短暂出现临时阶段(Attaching、Detaching);永久移除磁盘时会出现 Deleting,例如清理池或集群期间。完整的阶段集合为 Creating、Available、Attaching、Attached、Detaching、Deleting、Error。

如果磁盘进入 phase: Error,请先检查 lastError,然后再重试。

限制和恢复说明

  • 在现有集群迁移路径中,只有尾部连续的磁盘可被声明。
  • 控制器只保护在 persistentDisk 中声明的磁盘。任何未声明的磁盘仍遵循 VM 生命周期,并可能随旧 VM 一起被删除。
  • 此迁移会更改保留磁盘的所有权模型。不要在 DCSMachineTemplate 和 DCSIpHostnamePool 中同时定义同一个磁盘。
  • 如果需要保留 /var/cpaas,请在此次迁移中将其移入 IP 池,而不是将其留在模板中。
  • 本操作指南适用于 ACP v4.2.1 或更高版本上的集群。

相关主题