从 ACP TopoLVM 本地存储中移除磁盘、设备类卷组或节点
本文档介绍如何移除故障磁盘、从设备类中移除设备类卷组,以及移除 ACP TopoLVM 本地存储中的存储节点。
根据故障范围,本文档涵盖以下场景:
- 从设备类卷组中移除一个
卷组设备
- 从设备类中移除一个
设备类卷组
- 移除一个 TopoLVM 存储节点
风险警告
- 本文档中的操作步骤会直接删除 PVC、PV 以及
logicalvolumes.topolvm.cybozu.com 等存储资源。删除后,受影响卷中的数据通常无法恢复,请提前备份数据。
- 操作前请确认已正确识别目标磁盘、设备类卷组或节点,并为受影响的工作负载安排维护时间窗口。
术语
选择正确的场景
请使用下表判断适用于您环境的场景。
场景 1:从设备类卷组中移除卷组设备
用户场景
- 当设备类卷组未完全损坏,但卷组中一个或多个卷组设备故障需要移除时,使用此操作步骤。
前提条件
- 目标节点仍在集群中且可访问。
- 目标设备类的
Provision Type 为 Thick。
- 目标设备类卷组未完全损坏,卷组中至少还有一个健康的卷组设备。
检查设备类卷组是否仍可恢复
在目标节点执行以下命令:
参数:
若命令返回正常输出,或仅提示部分 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>
参数:
如有需要,可添加 --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>
参数:
在编辑器中,从 status.json 中移除故障卷组设备的状态。例如,移除 /dev/vdb 的 deviceStates 条目。
之前:
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:从设备类中移除设备类卷组
用户场景
- 当节点上的设备类卷组完全损坏,无法仅通过移除单个卷组设备恢复时,使用此操作步骤。
前提条件
- 目标节点仍在集群中且可访问。
- 目标设备类卷组已完全损坏。
- 移除目标设备类卷组后,节点上至少还保留有另一个设备类卷组。
检查设备类卷组是否完全损坏
在目标节点执行以下命令:
若输出中不再出现目标 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 列为
PersistentVolume 和 logicalvolumes.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 及其关联的 volumeGroup 和 devices 配置。
之前:
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>
参数:
在编辑器中,从 lvmd.yaml 和 status.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
'
参数:
第 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>
参数:
在编辑器中,删除整个 lvmd.yaml 和 status.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 不再显示。