从 ACP TopoLVM 本地存储中移除磁盘、设备类卷组或节点

本文档介绍如何移除故障磁盘、从设备类中移除设备类卷组,以及移除 ACP TopoLVM 本地存储中的存储节点。

根据故障范围,本文档涵盖以下场景:

  • 从设备类卷组中移除一个 卷组设备
  • 从设备类中移除一个 设备类卷组
  • 移除一个 TopoLVM 存储节点
风险警告
  • 本文档中的操作步骤会直接删除 PVC、PV 以及 logicalvolumes.topolvm.cybozu.com 等存储资源。删除后,受影响卷中的数据通常无法恢复,请提前备份数据。
  • 操作前请确认已正确识别目标磁盘、设备类卷组或节点,并为受影响的工作负载安排维护时间窗口。

术语

术语说明
device class由不同节点上的一个或多个设备类卷组组成的逻辑存储类。
device-class volume group节点上的一个 LVM 卷组,表示该节点上设备类的存储资源。
volume group device节点上的一个磁盘。在 LVM 中对应物理卷。

选择正确的场景

请使用下表判断适用于您环境的场景。

条件场景 1:从设备类卷组中移除卷组设备场景 2:从设备类中移除设备类卷组场景 3:移除 TopoLVM 存储节点
节点可访问性节点仍可访问。节点仍可访问。节点不可恢复,或您决定永久从 TopolvmCluster 中移除该节点。
卷组状态目标 LVM 卷组 仍存在且可识别。目标 LVM 卷组 不再存在或不可识别,但节点仍保留。节点及其上所有设备类卷组将一并移除。
移除范围从卷组中移除一个或多个故障磁盘。从保留的节点中移除一个设备类卷组。从 TopolvmCluster 中移除整个节点。
保留计划保留节点和设备类卷组。保留节点,但不保留目标设备类卷组。不保留节点及其上任何设备类卷组。

场景 1:从设备类卷组中移除卷组设备

用户场景

  • 当设备类卷组未完全损坏,但卷组中一个或多个卷组设备故障需要移除时,使用此操作步骤。

前提条件

  • 目标节点仍在集群中且可访问。
  • 目标设备类的 Provision TypeThick
  • 目标设备类卷组未完全损坏,卷组中至少还有一个健康的卷组设备。

检查设备类卷组是否仍可恢复

在目标节点执行以下命令:

vgs <vg-name>

参数:

  • <vg-name>:目标 LVM 卷组名称。

若命令返回正常输出,或仅提示部分 PV 缺失但卷组仍存在,则设备类卷组未完全损坏,可继续执行本操作步骤。

示例输出:

WARNING: Couldn't find device with uuid VJes6j-2a8V-8Cxf-eW84-yEJK-K24A-yBc9OD.
WARNING: VG hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33 is missing PV VJes6j-2a8V-8Cxf-eW84-yEJK-K24A-yBc9OD (last written to /dev/vdb).
WARNING: Couldn't find all devices for LV hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33/b6b331f0-5242-420f-a531-df90628bef80 while checking used and assumed devices.

操作步骤

第 1 步:停止 topolvm-operator

在 control-plane 节点执行以下命令,防止操作过程中 operator 进行资源调和:

kubectl -n nativestor-system scale --replicas 0 deployment topolvm-operator

第 2 步:查找受影响的 LVM 逻辑卷

在目标节点执行以下命令,查找使用故障磁盘的逻辑卷:

lvs -a -o +devices <vg-name> | egrep "<path-to-disks>|unknown device" | awk '{print $1}'

参数:

  • <vg-name>:目标 LVM 卷组名称。
  • <path-to-disks>:故障磁盘的设备路径,如 /dev/vdb。若匹配多个磁盘,用 | 分隔。

例如:

lvs -a -o +devices hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33 2>/dev/null | egrep "/dev/vdb|unknown" | awk '{print $1}'

示例输出:

b6b331f0-5242-420f-a531-df90628bef80

第 3 步:查找受影响的 PVC 和 PV

在 control-plane 节点执行以下命令,根据逻辑卷名称查找关联的 PV 和 PVC:

kubectl get pv -o json | jq -r --arg HANDLE <lv-name> '
  .items[]
  | select(.spec.csi.volumeHandle == $HANDLE)
  | [.metadata.name, .spec.claimRef.namespace, .spec.claimRef.name]
  | @tsv
'

参数:

  • <lv-name>:受影响的 LVM 逻辑卷名称。

示例输出:

pvc-e11f6c18-0e15-4c70-9a24-e7136fabfb2f	demo-space	pvc-topolvm

输出说明:

  • 第 1 列为 PersistentVolume 名称。
  • 第 2 列为 PersistentVolumeClaim 的命名空间。
  • 第 3 列为 PersistentVolumeClaim 名称。

第 4 步:停止使用受影响 PVC 的工作负载

确认受影响的 PVC 后,停止使用它们的工作负载,确保所有相关 Pod 已停止,然后继续操作。

第 5 步:删除受影响的 Kubernetes 存储资源

在 control-plane 节点执行以下命令:

kubectl delete pvc -n <pvc-namespace> <pvc-name>
kubectl delete pv <pv-name>
kubectl delete logicalvolumes.topolvm.cybozu.com <logicalvolume-name>

参数:

  • <pvc-namespace>:受影响 PVC 的命名空间。
  • <pvc-name>:受影响 PVC 的名称。
  • <pv-name>:受影响 PV 的名称。
  • <logicalvolume-name>:TopoLVM logicalvolumes.topolvm.cybozu.com 资源名称,与 <pv-name> 相同。

若查询结果包含多个资源,按映射关系逐一删除。

若资源无法正常删除,可根据需要添加 --force

第 6 步:清理残留的 LVM 逻辑卷

在目标节点执行以下命令,检查是否仍有逻辑卷残留:

lvs -a -o +devices <vg-name> 2>/dev/null | egrep "<path-to-disks>|unknown device" | awk '{print $1}'

参数:

  • <vg-name>:目标 LVM 卷组名称。
  • <path-to-disks>:故障磁盘的设备路径,如 /dev/vdb。若匹配多个磁盘,用 | 分隔。

若命令仍有输出,逐一删除残留逻辑卷:

lvremove <vg-name>/<lv-name>

参数:

  • <vg-name>:目标 LVM 卷组名称。
  • <lv-name>:要删除的逻辑卷名称。

如有需要,可添加 --force

第 7 步:从 LVM 卷组中移除缺失的物理卷

在目标节点执行以下命令:

vgreduce --removemissing <vg-name>

参数:

  • <vg-name>:目标 LVM 卷组名称。

如有需要,可添加 --force

第 8 步:更新 TopolvmCluster 资源

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit topolvmclusters.topolvm.cybozu.com topolvm

在编辑器中,从目标节点的 devices 列表中移除故障卷组设备。例如,从 nodeName: 192.168.133.50 的配置中移除 /dev/vdb

之前:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: hdd
            default: true
            devices:
              - name: /dev/vdb
                type: disk
              - name: /dev/vdc
                type: disk
            volumeGroup: hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33
        nodeName: 192.168.133.50

之后:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: hdd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33
        nodeName: 192.168.133.50

第 9 步:更新 lvmdconfig ConfigMap

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit configmaps lvmdconfig-<node-name>

参数:

  • <node-name>:目标节点名称。

在编辑器中,从 status.json 中移除故障卷组设备的状态。例如,移除 /dev/vdbdeviceStates 条目。

之前:

status.json: '{"node":"192.168.133.50","phase":"","failClasses":[],"successClasses":[{"className":"hdd","vgName":"hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33","state":"Ready","message":"create successful","deviceStates":[{"name":"/dev/vdb","state":"Online"},{"name":"/dev/vdc","state":"Online"}]}],"loops":[],"raids":[]}'

之后:

status.json: '{"node":"192.168.133.50","phase":"","failClasses":[],"successClasses":[{"className":"hdd","vgName":"hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33","state":"Ready","message":"create successful","deviceStates":[{"name":"/dev/vdc","state":"Online"}]}],"loops":[],"raids":[]}'

第 10 步:启动 topolvm-operator

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator

第 11 步:验证卷组设备已移除

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq

确认目标节点的 deviceStates 中不再出现已移除的卷组设备。

场景 2:从设备类中移除设备类卷组

用户场景

  • 当节点上的设备类卷组完全损坏,无法仅通过移除单个卷组设备恢复时,使用此操作步骤。

前提条件

  • 目标节点仍在集群中且可访问。
  • 目标设备类卷组已完全损坏。
  • 移除目标设备类卷组后,节点上至少还保留有另一个设备类卷组。

检查设备类卷组是否完全损坏

在目标节点执行以下命令:

vgs

若输出中不再出现目标 LVM 卷组,则设备类卷组已完全损坏,可继续执行本操作步骤。

注意

本场景移除的是节点上的整个设备类卷组,而非仅移除该卷组中的单个卷组设备。

操作步骤

第 1 步:停止 topolvm-operator

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system scale --replicas 0 deployment topolvm-operator

第 2 步:查找受影响的 PVC 和 PV

在 control-plane 节点执行以下命令,查找目标节点上指定存储类关联的 PV、PVC 及 logicalvolumes.topolvm.cybozu.com 资源:

kubectl get pv -o json | jq -r --arg NODE <node-name> --arg SC <storageclass-name> '
  .items[]
  | select(.spec.nodeAffinity.required.nodeSelectorTerms[]?.matchExpressions[]? | select(.key=="topology.topolvm.cybozu.com/node") | .values[]? == $NODE)
  | select(.spec.storageClassName == $SC)
  | [.metadata.name, .spec.claimRef.namespace, .spec.claimRef.name]
  | @tsv
'

参数:

  • <node-name>:目标节点名称。
  • <storageclass-name>:目标设备类卷组关联的存储类名称。若涉及多个存储类,请分别执行查询。

示例输出:

pvc-e11f6c18-0e15-4c70-9a24-e7136fabfb2f	demo-space	pvc-topolvm

输出说明:

  • 第 1 列为 PersistentVolumelogicalvolumes.topolvm.cybozu.com 资源名称。
  • 第 2、3 列为 PersistentVolumeClaim 的命名空间和名称。

若目标设备类卷组关联多个存储类,请对每个存储类重复执行查询及后续清理步骤。

第 3 步:停止使用受影响 PVC 的工作负载

确认受影响的 PVC 后,停止使用它们的工作负载,确保所有相关 Pod 已停止,然后继续操作。

第 4 步:删除受影响的 Kubernetes 存储资源

在 control-plane 节点执行以下命令:

kubectl delete pvc -n <pvc-namespace> <pvc-name>
kubectl delete pv <pv-name>
kubectl delete logicalvolumes.topolvm.cybozu.com <logicalvolume-name>

参数:

  • <pvc-namespace>:受影响 PVC 的命名空间。
  • <pvc-name>:受影响 PVC 的名称。
  • <pv-name>:受影响 PV 的名称。
  • <logicalvolume-name>:TopoLVM logicalvolumes.topolvm.cybozu.com 资源名称,与 <pv-name> 相同。

若查询结果包含多个资源,按映射关系逐一删除。

若资源无法正常删除,可根据需要添加 --force

第 5 步:更新 TopolvmCluster 资源

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit topolvmclusters.topolvm.cybozu.com topolvm

在编辑器中,从目标节点配置中移除设备类卷组。例如,在 nodeName: 192.168.140.13 的配置中,移除 className: hdd 及其关联的 volumeGroupdevices 配置。

之前:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: ssd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1
          - className: hdd
            devices:
              - name: /dev/vdb
                type: disk
            volumeGroup: hdd-97dc00f3-1df6-4f64-8ddc-7b0b6c5d6de5
        nodeName: 192.168.140.13

之后:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: ssd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1
        nodeName: 192.168.140.13

若被移除的 className 条目含有 default: true,请指定另一个剩余的类为默认类。

第 6 步:更新 lvmdconfig ConfigMap

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit configmaps lvmdconfig-<node-name>

参数:

  • <node-name>:目标节点名称。

在编辑器中,从 lvmd.yamlstatus.json 中移除对应目标设备类卷组的配置。例如,移除 className: hdd 的配置。

之前:

lvmd.yaml: |
  socket-name: /run/topolvm/lvmd.sock
  device-classes:
  - name: ssd
    volume-group: ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1
    default: true
    type: thick
  - name: hdd
    volume-group: hdd-97dc00f3-1df6-4f64-8ddc-7b0b6c5d6de5
    default: false
    type: thick
status.json: '{"node":"192.168.140.13","phase":"","failClasses":[],"successClasses":[{"className":"hdd","vgName":"hdd-97dc00f3-1df6-4f64-8ddc-7b0b6c5d6de5","state":"Ready","message":"create successful","deviceStates":[{"name":"/dev/vdb","state":"Online"}]},{"className":"ssd","vgName":"ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1","state":"Ready","message":"create successful","deviceStates":[{"name":"/dev/vdc","state":"Online"}]}],"loops":[],"raids":[]}'

之后:

lvmd.yaml: |
  socket-name: /run/topolvm/lvmd.sock
  device-classes:
  - name: ssd
    volume-group: ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1
    default: true
    type: thick
status.json: '{"node":"192.168.140.13","phase":"","failClasses":[],"successClasses":[{"className":"ssd","vgName":"ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1","state":"Ready","message":"create successful","deviceStates":[{"name":"/dev/vdc","state":"Online"}]}],"loops":[],"raids":[]}'

若被移除的 className 条目含有 default: true,请指定另一个剩余的类为默认类。

第 7 步:启动 topolvm-operator

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator

第 8 步:验证设备类卷组已移除

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq

确认目标节点不再显示已移除的设备类卷组,且剩余设备类卷组状态正常。

场景 3:移除 TopoLVM 存储节点

用户场景

  • 目标节点不可恢复,或您决定永久从 TopolvmCluster 中移除该节点。

前提条件

  • 您决定不保留目标节点上的任何设备类卷组。
  • 使用目标节点本地卷的工作负载已停止或迁移至其他节点。
  • 移除目标节点后,剩余节点仍能承载所需工作负载。

操作步骤

第 1 步:停止 topolvm-operator

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system scale --replicas 0 deployment topolvm-operator

第 2 步:查找受影响的 PVC 和 PV

在 control-plane 节点执行以下命令,查找与目标节点关联的 PV、PVC 及 logicalvolumes.topolvm.cybozu.com 资源:

kubectl get pv -o json | jq -r --arg NODE <node-name> '
  .items[]
  | select(.spec.nodeAffinity.required.nodeSelectorTerms[]?.matchExpressions[]? | select(.key=="topology.topolvm.cybozu.com/node") | .values[]? == $NODE)
  | [.metadata.name, .spec.claimRef.namespace, .spec.claimRef.name]
  | @tsv
'

参数:

  • <node-name>:目标节点名称。

第 3 步:停止使用受影响 PVC 的工作负载

确认受影响的 PVC 后,停止使用它们的工作负载,确保所有相关 Pod 已停止,然后继续操作。

第 4 步:删除受影响的 Kubernetes 存储资源

在 control-plane 节点执行以下命令:

kubectl delete pvc -n <pvc-namespace> <pvc-name>
kubectl delete pv <pv-name>
kubectl delete logicalvolumes.topolvm.cybozu.com <logicalvolume-name>

参数:

  • <pvc-namespace>:受影响 PVC 的命名空间。
  • <pvc-name>:受影响 PVC 的名称。
  • <pv-name>:受影响 PV 的名称。
  • <logicalvolume-name>:TopoLVM logicalvolumes.topolvm.cybozu.com 资源名称,与 <pv-name> 相同。

若查询结果包含多个资源,按映射关系逐一删除。

若资源无法正常删除,可根据需要添加 --force

第 5 步:更新 TopolvmCluster 资源

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit topolvmclusters.topolvm.cybozu.com topolvm

在编辑器中,删除目标节点的整个配置块。例如,删除 nodeName: 192.168.140.13 的配置块。

之前:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: hdd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33
        nodeName: 192.168.133.50
      - classes:
          - className: ssd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: ssd-4a8737fc-48d3-4c61-882d-0a5bcc6f77a1
          - className: hdd
            devices:
              - name: /dev/vdb
                type: disk
            volumeGroup: hdd-97dc00f3-1df6-4f64-8ddc-7b0b6c5d6de5
        nodeName: 192.168.140.13

之后:

spec:
  storage:
    deviceClasses:
      - classes:
          - className: hdd
            default: true
            devices:
              - name: /dev/vdc
                type: disk
            volumeGroup: hdd-2ab8f0a2-7d1d-42d7-ba6b-da94c6185c33
        nodeName: 192.168.133.50

第 6 步:更新 lvmdconfig ConfigMap

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system edit configmaps lvmdconfig-<node-name>

参数:

  • <node-name>:目标节点名称。

在编辑器中,删除整个 lvmd.yamlstatus.json 部分,不保留任何已移除节点的配置或状态。

第 7 步:启动 topolvm-operator

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator

第 8 步:验证节点已移除

在 control-plane 节点执行以下命令:

kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq

确认 status.nodeStorageState 中不再出现目标节点,例如 192.168.140.13 不再显示。