从 LVM 存储中移除磁盘、设备类卷组或节点
本文介绍如何移除故障磁盘、从设备类中移除设备类卷组,以及移除 LVM Storage 中的存储节点。
根据故障范围,本文涵盖以下场景:
- 从
device-class volume group 中移除 volume group device
- 从
device class 中移除 device-class volume group
- 移除 TopoLVM 存储节点
风险警告
- 本文中的操作步骤会直接删除 PVC、PV 和
logicalvolumes.topolvm.cybozu.com 等存储资源。删除这些资源后,受影响卷中的数据通常无法恢复。请提前备份数据。
- 继续操作之前,请确认已识别出正确的磁盘、设备类卷组或节点,并为受影响的工作负载安排维护窗口。
术语
选择正确的场景
使用下表确定适用于您环境的场景。
场景 1:从设备类卷组中移除卷组设备
用户场景
- 当
device-class volume group 未完全损坏,但卷组中的一个或多个 volume group devices 发生故障且必须移除时,请使用此操作步骤。
前提条件
- 目标节点仍在集群中且可访问。
- 目标设备类的
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
在控制平面节点上运行以下命令,以防止 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
在控制平面节点上运行以下命令,通过逻辑卷名称查找关联的 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 后,停止使用这些 PVC 的工作负载,并确认所有相关 Pod 均已停止,然后再继续。
步骤 5:删除受影响的 Kubernetes 存储资源
在控制平面节点上运行以下命令:
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 资源
在控制平面节点上运行以下命令:
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
在控制平面节点上运行以下命令:
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
在控制平面节点上运行以下命令:
kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator
步骤 11:验证卷组设备已移除
在控制平面节点上运行以下命令:
kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq
确认已移除的卷组设备不再显示在目标节点的 deviceStates 中。
场景 2:从设备类中移除设备类卷组
用户场景
- 当节点上的设备类卷组完全损坏,无法仅通过移除单个卷组设备进行恢复时,使用此操作步骤。
前提条件
- 目标节点仍在集群中且可访问。
- 目标设备类卷组已完全损坏。
- 移除目标设备类卷组后,节点上至少保留一个其他设备类卷组。
检查设备类卷组是否已完全损坏
在目标节点上运行以下命令:
如果输出中不再显示目标 LVM volume group,则表示设备类卷组已完全损坏,您可以按照此操作步骤执行。
注意
此场景会从节点中移除整个设备类卷组,而不仅仅是移除该卷组中的单个卷组设备。
操作步骤
步骤 1:停止 topolvm-operator
在控制平面节点上运行以下命令:
kubectl -n nativestor-system scale --replicas 0 deployment topolvm-operator
步骤 2:查找受影响的 PVC 和 PV
在控制平面节点上运行以下命令,以查找目标节点上与指定存储类关联的 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 后,停止使用这些 PVC 的工作负载,并确认所有相关 Pod 均已停止,然后再继续。
步骤 4:删除受影响的 Kubernetes 存储资源
在控制平面节点上运行以下命令:
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 资源
在控制平面节点上运行以下命令:
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
在控制平面节点上运行以下命令:
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
在控制平面节点上运行以下命令:
kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator
步骤 8:验证设备类卷组已移除
在控制平面节点上运行以下命令:
kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq
确认目标节点上不再显示已移除的设备类卷组,并确认剩余的设备类卷组运行状况正常。
场景 3:移除 TopoLVM 存储节点
用户场景
- 目标节点已无法恢复,或者您已决定将其从 TopolvmCluster 中永久移除。
前提条件
- 您已决定不保留目标节点上的任何设备类卷组。
- 使用目标节点上本地卷的工作负载已停止,或已迁移到其他节点。
- 移除目标节点后,剩余节点仍可继续承载所需的工作负载。
操作步骤
步骤 1:停止 topolvm-operator
在控制平面节点上运行以下命令:
kubectl -n nativestor-system scale --replicas 0 deployment topolvm-operator
步骤 2:查找受影响的 PVC 和 PV
在控制平面节点上运行以下命令,查找与目标节点关联的 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 后,停止使用这些 PVC 的工作负载,并确认所有相关 Pod 均已停止,然后再继续。
步骤 4:删除受影响的 Kubernetes 存储资源
在控制平面节点上运行以下命令:
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 资源
在控制平面节点上运行以下命令:
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
在控制平面节点上运行以下命令:
kubectl -n nativestor-system edit configmaps lvmdconfig-<node-name>
参数:
在编辑器中,删除整个 lvmd.yaml 和 status.json 部分。不要保留已移除节点的任何配置或状态。
步骤 7:启动 topolvm-operator
在控制平面节点上运行以下命令:
kubectl -n nativestor-system scale --replicas 1 deployment topolvm-operator
步骤 8:验证节点已移除
在控制平面节点上运行以下命令:
kubectl -n nativestor-system get topolvmclusters.topolvm.cybozu.com topolvm -o jsonpath="{.status.nodeStorageState}" | jq
确认目标节点不再显示在 status.nodeStorageState 中。例如,192.168.140.13 不应再出现在输出中。