将现有 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 已经存在,并且将每个节点映射到固定的 IP slot。

检查当前磁盘布局

首先,识别管理集群对象以及为每个节点提供支持的 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=Error 以及 lastError 置为相应状态。controller 会以较慢的循环重试,直到 spec 被更正为止:

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

文件系统(影响 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 下。需要关注的稳定阶段包括:

  • phase: Attached,表示旧 VM 仍然拥有该磁盘
  • phase: Available,表示磁盘已分离(并在需要时从标准卷转换为独立共享卷)
  • phase: Attached,表示替换后的 VM 已重新连接该磁盘

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

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

限制与恢复说明

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

相关主题