OpenEBS
OpenEBS 是 Kubernetes 的容器原生存储项目,把节点上的目录、块设备或存储池提供给持久卷。Hostpath 使用动态 Local PV provisioner,LVM、ZFS 和 Mayastor 使用各自的 CSI 驱动;它们的安装要求和数据保护能力不同。
1. 先选存储引擎
| 引擎 | 数据位置 | 节点故障后的数据可用性 | 适用场景 |
|---|---|---|---|
| Local PV Hostpath | 某个节点的目录 | 不能自动跨节点恢复 | 单节点服务、缓存、测试、应用自身负责复制 |
| Local PV LVM | 节点上的 LVM 卷组 | 不能自动跨节点恢复 | 需要块设备和 LVM 管理的本地卷 |
| Local PV ZFS | 节点上的 ZFS pool | 不能自动跨节点恢复 | 已有 ZFS、需要本机快照或校验 |
| Replicated PV Mayastor | 多个节点的专用块设备 | 通过副本在其他节点重建 | 三节点以上、需要 CSI 块存储副本 |
Hostpath、LVM 和 ZFS 都是本地卷。修改 PV 的 nodeAffinity、删除 PV 或把 Pod 调度到另一台机器,都不会搬运原来的数据。Mayastor 的复制卷也需要应用、CSI 控制面、网络和副本重建共同工作,副本不等于异地备份。
PVC 是应用的容量申请,StorageClass 定义供给策略,PV 记录实际卷及其节点或 CSI 标识。控制面负责创建、删除、挂载和调度卷;数据面负责读写。Hostpath 的数据路径是 Pod → 节点文件系统 → 数据盘,Mayastor 则经 NVMe-TCP 目标把写入同步复制到其他节点。容器原生存储并不保证一定比外部存储快,性能取决于磁盘、网络、文件系统、复制数和同步写策略。
2. 安装前检查
下面的命令以 OpenEBS Helm chart 4.6.2 为基线。准备 Kubernetes 管理员权限和 Helm 3.7 以上版本,并核对该版本与集群、内核的兼容性;chart 版本与各存储引擎的版本不完全相同。
kubectl version
helm version
kubectl get nodes -o wide
Hostpath 只使用目录时,在每一台可能调度卷的节点准备独立数据盘。下面假定数据盘已挂载到 /data/openebs;不要让目录在数据盘未挂载时自动落到系统盘:
sudo mkdir -p /data/openebs/local
findmnt -T /data/openebs/local
df -hT /data/openebs/local
先把独立数据盘按 UUID 挂载到 /data/openebs,再创建 local 子目录,并在 /etc/fstab 配置持久挂载。用 findmnt 确认 SOURCE、FSTYPE、TARGET 是预期数据盘,开机挂载失败时阻止 kubelet 启动。Hostpath 的 PVC 容量请求默认不是磁盘配额;4.6 系列提供可选 project quota,需要满足文件系统和挂载参数要求,不能仅把 requests.storage 当成硬隔离。
3. 只安装 Hostpath
默认 chart 会同时启用 LVM、ZFS、Hostpath、Mayastor 以及观测组件。单机或只需要目录卷时,保存以下 values-hostpath.yaml,只启用 Hostpath:
openebs-crds:
csi:
volumeSnapshots:
enabled: false
keep: true
engines:
local:
hostpath:
enabled: true
lvm:
enabled: false
zfs:
enabled: false
rawfile:
enabled: false
replicated:
mayastor:
enabled: false
loki:
enabled: false
alloy:
enabled: false
localpv-provisioner:
localpv:
basePath: /data/openebs/local
hostpathClass:
enabled: false
本方案不使用 CSI 快照,因此不安装 Snapshot CRD。集群已由其他组件管理这些 CRD 时,同样应避免重复接管。Hostpath 不因为安装 CRD 就获得 CSI 快照能力。
helm repo add openebs https://openebs.github.io/openebs
helm repo update
helm show chart openebs/openebs --version 4.6.2
helm template openebs openebs/openebs \
--version 4.6.2 --namespace openebs \
-f values-hostpath.yaml > rendered-openebs.yaml
helm upgrade --install openebs openebs/openebs \
--version 4.6.2 --namespace openebs --create-namespace \
-f values-hostpath.yaml --wait --timeout 10m
kubectl get pods -n openebs
kubectl get crd | grep -E 'openebs|snapshot' || true
不要把示例的 values 直接覆盖已有生产 release。升级时先执行 helm get values openebs -n openebs 保存显式配置,再用 -a 对照旧版默认值,合并新版本配置后用 helm template 检查结果。helm diff 需要另装插件。
4. 创建 Hostpath StorageClass
先确保每个允许调度的节点都已挂载数据盘、创建 /data/openebs/local,将下面内容保存为 openebs-hostpath-retain.yaml。Retain 用于避免删除 PVC 时自动清理数据,目录初始权限设为 0770:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: openebs-hostpath-retain
annotations:
openebs.io/cas-type: local
cas.openebs.io/config: |
- name: StorageType
value: "hostpath"
- name: BasePath
value: "/data/openebs/local"
- name: FilePermissions
data:
mode: "0770"
provisioner: openebs.io/local
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: false
kubectl apply -f openebs-hostpath-retain.yaml
kubectl get storageclass openebs-hostpath-retain -o yaml
WaitForFirstConsumer 会等使用 PVC 的 Pod 创建后再选择节点,PVC 在此之前处于 Pending 是正常现象。不要给 Pod 设置 spec.nodeName 绕过调度器;需要限制节点时使用 nodeSelector、亲和性或 StorageClass 的 allowedTopologies。例如只允许 worker-2 和 worker-3:
allowedTopologies:
- matchLabelExpressions:
- key: kubernetes.io/hostname
values:
- worker-2
- worker-3
NodeAffinityLabels 只改变 PV 记录的节点身份,不负责调度应用 Pod;allowedTopologies 才会参与调度约束。Hostpath 目录如果不存在,provisioner 可能会创建它,所以必须在创建 PVC 前检查数据盘挂载状态。
5. PVC 和持久化验证
下面的测试会写入文件,删除并重建 Pod 后再次读取。它验证的是同一节点上的本地卷持久化,不代表节点故障后可以跨节点恢复。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: openebs-test-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: openebs-hostpath-retain
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: openebs-test-writer
spec:
restartPolicy: Always
containers:
- name: writer
image: busybox:1.36
command: ["sh", "-c"]
args:
- while true; do date >> /data/heartbeat.log; sleep 30; done
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: openebs-test-pvc
kubectl apply -f openebs-test.yaml
kubectl wait --for=condition=Ready pod/openebs-test-writer --timeout=120s
kubectl get pvc,pv,pod -o wide
kubectl exec openebs-test-writer -- sh -c 'echo first-write > /data/check.txt; sync; cat /data/check.txt'
kubectl delete pod openebs-test-writer
kubectl apply -f openebs-test.yaml
kubectl wait --for=condition=Ready pod/openebs-test-writer --timeout=120s
kubectl exec openebs-test-writer -- cat /data/check.txt
ReadWriteOnce 表示卷以读写方式挂载到一个节点,同一节点可以有多个 Pod 使用,并不等于只能有一个 Pod。它也不是 ReadWriteMany;不能仅修改 PVC 字段就把本地目录变成跨节点共享存储。测试结束后,确认数据已备份再删除资源:
kubectl delete pod openebs-test-writer
kubectl delete pvc openebs-test-pvc
kubectl get pv
因为 StorageClass 是 Retain,删除 PVC 后 PV 会进入 Released,目录数据不会自动删除。确认无用后按 PV 对应节点和目录人工清理。
Redis 持久化示例
仅挂载 /data 不等于每次写入都已经持久化。下面显式启用 AOF,配置 fsGroup 以便 Redis 进程访问卷目录,并使用单副本 StatefulSet:
apiVersion: v1
kind: Service
metadata:
name: redis-headless
spec:
clusterIP: None
selector:
app: redis-openebs
ports:
- name: redis
port: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-openebs
spec:
serviceName: redis-headless
replicas: 1
selector:
matchLabels:
app: redis-openebs
template:
metadata:
labels:
app: redis-openebs
spec:
securityContext:
fsGroup: 999
runAsUser: 999
runAsGroup: 999
containers:
- name: redis
image: redis:7.4-bookworm
command: ["redis-server"]
args: ["--appendonly", "yes", "--appendfsync", "everysec", "--dir", "/data"]
ports:
- name: redis
containerPort: 6379
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 512Mi
readinessProbe:
exec:
command: ["redis-cli", "ping"]
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: openebs-hostpath-retain
resources:
requests:
storage: 5Gi
保存为 redis-openebs.yaml 后验证:
kubectl apply -f redis-openebs.yaml
kubectl rollout status statefulset/redis-openebs --timeout=180s
kubectl exec redis-openebs-0 -- redis-cli SET openebs-check persisted
kubectl exec redis-openebs-0 -- redis-cli INFO persistence
kubectl exec redis-openebs-0 -- sh -c 'sleep 2; test -d /data/appendonlydir'
kubectl delete pod redis-openebs-0
kubectl rollout status statefulset/redis-openebs --timeout=180s
kubectl wait --for=condition=Ready pod/redis-openebs-0 --timeout=180s
kubectl exec redis-openebs-0 -- redis-cli GET openebs-check
应返回 persisted,并检查 aof_enabled:1、aof_last_write_status:ok。everysec 在掉电时仍可能损失约一秒写入;Pod 正常重建成功不能替代断电或节点故障演练。示例仅供隔离测试,不暴露 NodePort/LoadBalancer;生产需增加 Redis ACL、NetworkPolicy、备份与内存策略。不要把 StatefulSet 副本数改成 3 就当成 Redis 主从或集群。
6. LVM、ZFS 和扩容
LVM 和 ZFS 只有在节点已准备好对应工具和专用存储池时才启用。生产环境不要用 loopback 文件模拟块设备,也不要把系统盘、已有 PV 或仍被其他服务使用的设备交给 OpenEBS。
LVM 的准备重点:
sudo apt-get install -y lvm2
sudo modprobe dm-snapshot
LVM_DEVICE=/dev/disk/by-id/REPLACE_WITH_DATA_DISK
sudo pvcreate "$LVM_DEVICE"
sudo vgcreate openebs-vg "$LVM_DEVICE"
ZFS 的准备重点:
sudo apt-get install -y zfsutils-linux
ZFS_DEVICE=/dev/disk/by-id/REPLACE_WITH_DATA_DISK
sudo zpool create openebs-zpool "$ZFS_DEVICE"
sudo zpool status openebs-zpool
这些命令会初始化设备,执行前必须确认设备路径。LVM、ZFS 和 Hostpath 的本地卷都不具备跨节点复制能力;需要副本时使用 Mayastor 或由应用层复制。
安装驱动时只启用需要的 engines.local.lvm.enabled 或 engines.local.zfs.enabled,并按对应驱动文档创建引用实际卷组或 pool 的 StorageClass。以上 apt-get 命令针对 Debian/Ubuntu;其他发行版按系统包管理器安装,ZFS 还需确认模块与运行内核匹配。不要把这些命令直接用于已有数据的设备。
Local PV 的扩容取决于底层驱动和文件系统,不能只把 PVC 的 requests.storage 改大就假设完成。先查看 StorageClass 的 allowVolumeExpansion,再按对应驱动文档测试。Hostpath 不支持通过 CSI 扩容目录卷;扩大底层磁盘不会自动更新 PV/PVC 标称容量,配额也需单独核对。容量监控应直接检查挂载点:
df -hT /data/openebs/local
du -xhd1 /data/openebs/local | sort -h
kubectl get pvc,pv -A
7. Mayastor 复制卷
Mayastor 适用于需要 Kubernetes CSI 复制块存储的场景。4.6.x 的关键前提如下:
- x86-64 CPU 支持 SSE4.2;NVMe-TCP 路径要求内核至少 5.13,部署优先选择官方支持范围内的 5.15 或更高版本。
- io-engine 节点需要
nvme-tcp,文件系统使用 ext4 或可选 xfs。 - 每个 io-engine 需要独占约 2 个 CPU、1 GiB 普通内存和至少 2 GiB 的 2 MiB HugePages。
- 最少 3 个 worker;三副本至少需要 3 个有独立 DiskPool 的节点。
- 磁盘必须是空闲的专用块设备,推荐
/dev/disk/by-id或/dev/disk/by-path,不能用/dev/sdX、系统盘或现有 PV。 - HA 需要按官方要求配置 NVMe multipath;只启用
repl: "3"不代表所有故障都能无感恢复。
下面的 worker-1、worker-2、worker-3 必须替换成实际节点名。HugePages 修改和 kubelet 重启需要安排节点维护:
sudo modprobe nvme-tcp
grep HugePages /proc/meminfo
echo 1024 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
echo 'vm.nr_hugepages = 1024' | sudo tee -a /etc/sysctl.conf
kubectl label node worker-1 openebs.io/engine=mayastor
kubectl label node worker-2 openebs.io/engine=mayastor
kubectl label node worker-3 openebs.io/engine=mayastor
修改 HugePages 后重启 kubelet 或节点,让 kubelet 上报新的可用资源。确认端口 10124、8420 和 4421 未被防火墙阻断,并确认应用节点能加载 nvme-tcp。
在所有应用节点确认 cat /sys/module/nvme_core/parameters/multipath 返回 Y。如需调整,按发行版方法设置 nvme_core.multipath=Y 并持久化,在维护窗口重启;不要对正在挂载卷的节点直接卸载 NVMe 模块。4.6.x 官方文档明确当前 HA 不支持 RHEL 10 及其移除该参数的衍生发行版。
下面是全新三节点集群的 Mayastor 安装入口,与前面的 Hostpath-only 方案二选一。它会部署控制面、etcd 和 CSI 组件,并保留 Hostpath provisioner 支撑 etcd;不要直接对已有 release 执行来切换引擎。生产配置应保存为完整 values 并纳入版本管理:
helm upgrade --install openebs openebs/openebs \
--version 4.6.2 --namespace openebs --create-namespace \
--set engines.local.hostpath.enabled=true \
--set engines.local.lvm.enabled=false \
--set engines.local.zfs.enabled=false \
--set engines.local.rawfile.enabled=false \
--set engines.replicated.mayastor.enabled=true \
--set loki.enabled=false --set alloy.enabled=false \
--wait --timeout 15m
Mayastor 的 etcd 默认使用 mayastor-etcd-localpv,数据路径为 /var/local/openebs/localpv-hostpath/etcd,应为其准备可靠磁盘并备份控制面元数据。应用 PVC 仍使用下面的 Mayastor StorageClass。若已有外部 etcd,可按 chart values 配置外部地址后再关闭对应本地依赖。
集群已有 Snapshot CRD 时,安装命令追加 --set openebs-crds.csi.volumeSnapshots.enabled=false;已有集群级 snapshot-controller 时,追加 --set mayastor.csi.controller.snapshotController.enabled=false。两者分别控制 CRD 和 controller,不可混为一项。
创建 DiskPool 时,spec.disks 目前每个池只支持一个设备。池会独占并可能清除设备上的已有数据;maxExpansion 必须创建时设置,之后不能修改:
apiVersion: openebs.io/v1beta3
kind: DiskPool
metadata:
name: pool-worker-1
namespace: openebs
spec:
node: worker-1
disks:
- aio:///dev/disk/by-id/REPLACE_WITH_DATA_DISK
maxExpansion: 5x
kubectl apply -f diskpool-worker-1.yaml
kubectl get dsp -n openebs
替换节点名、池名和磁盘稳定标识,在另外两个节点各创建一个 DiskPool。三个池都 Online 后再测试三副本卷。maxExpansion: 5x 只是允许池未来增长到初始容量的五倍,不会自动扩大硬盘;设置过大还会增加池元数据开销。
三副本 StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mayastor-3
provisioner: io.openebs.csi-mayastor
reclaimPolicy: Retain
allowVolumeExpansion: true
parameters:
protocol: nvmf
repl: "3"
fsType: ext4
volumeBindingMode: WaitForFirstConsumer
保存为 mayastor-3.yaml 后执行 kubectl apply -f mayastor-3.yaml。使用 xfs 时,所有可能挂载应用卷的节点需具备 xfs 支持及所需工具。
repl: "1" 不容忍副本节点故障;repl: "3" 需要至少三个可用副本池,并且副本应落在不同节点。它不代表整个集群可以任意失去两个节点:etcd 多数派、控制面、目标切换和应用调度仍影响恢复。复制卷通常仍是 ReadWriteOnce,不等于通用 RWX 文件系统。三副本 10Gi 卷约需三个池各 10Gi 数据空间,还要预留元数据、快照和重建空间。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mayastor-test-pvc
spec:
accessModes: [ReadWriteOnce]
storageClassName: mayastor-3
resources:
requests:
storage: 10Gi
kubectl apply -f mayastor-test-pvc.yaml
# 将第 5 节 Pod 示例另存为 mayastor-test-pod.yaml:
# Pod 改名 mayastor-test-writer,claimName 改为 mayastor-test-pvc,只保留 Pod 文档
kubectl apply -f mayastor-test-pod.yaml
kubectl wait --for=condition=Ready pod/mayastor-test-writer --timeout=180s
kubectl get pvc,pv -o wide
# 下列 mayastor 命令需先安装官方 kubectl mayastor 插件
kubectl mayastor get volumes -n openebs
PV_NAME=$(kubectl get pvc mayastor-test-pvc -o jsonpath='{.spec.volumeName}')
VOLUME_ID=$(kubectl get pv "$PV_NAME" -o jsonpath='{.spec.csi.volumeHandle}')
kubectl mayastor get volume-replica-topology "$VOLUME_ID" -n openebs
此处同样使用 WaitForFirstConsumer,所以仅创建 PVC 时 Pending 正常。Mayastor 可复用第 5 节写入、删除和重建 Pod 的验证过程;节点故障演练还需观察副本降级、目标切换、应用恢复时长和副本重建,安排在测试环境进行。
扩容 PVC 与 DiskPool
扩容前要求所有卷副本 Online、所有承载池有足够空间,且 StorageClass 已启用 allowVolumeExpansion。例如把上面的 10Gi PVC 扩到 20Gi:
kubectl patch pvc mayastor-test-pvc --type=merge \
-p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
kubectl get pvc mayastor-test-pvc
kubectl describe pvc mayastor-test-pvc
kubectl exec mayastor-test-writer -- df -h /data
PVC 扩容与池扩容不同。前者增加单个卷容量,后者增加可分配的后端容量。4.6 系列支持在 maxExpansion 范围内扩大 DiskPool:先按基础设施流程扩底层设备,确认设备稳定标识和可见容量正确,再触发池扩容:
kubectl annotate dsp pool-worker-1 -n openebs openebs.io/expand=true
kubectl get dsp pool-worker-1 -n openebs -o yaml
检查池的 capacity、diskCapacity 和 maxExpandableSize。不要在不支持原地扩容的物理盘上尝试修改分区来代替换盘迁移,也不要在引擎升级未完成时扩卷。PVC 只支持增大,不能缩容;修改 PV 的 capacity 不会实际扩容底层设备。
8. 快照、恢复和备份
Hostpath-only 安装不要使用 CSI VolumeSnapshot 示例。Hostpath 目录的备份应由 Velero、文件级备份或应用自身的导出机制完成,并且备份目标应在其他节点、集群或对象存储中。
Mayastor 快照需要集群只运行一个 snapshot-controller。已有集群级 controller 时,应在 Mayastor values 中关闭内置 controller;不要安装两套 controller。示例:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-mayastor-snapshotclass
driver: io.openebs.csi-mayastor
deletionPolicy: Retain
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: mayastor-test-snapshot
spec:
volumeSnapshotClassName: csi-mayastor-snapshotclass
source:
persistentVolumeClaimName: mayastor-test-pvc
kubectl apply -f mayastor-snapshot.yaml
kubectl get volumesnapshot
kubectl describe volumesnapshot mayastor-test-snapshot
快照是卷副本的时间点视图,不是独立备份;快照副本不能像卷副本一样在节点故障后自动重建。创建后应等待 readyToUse: true,同时监控所有副本池的可用空间。本例使用 Retain,删除 VolumeSnapshot 后仍需人工管理底层快照,避免长期占用空间。
Mayastor 默认执行文件系统一致性快照,但这不等于数据库事务一致性。创建快照前应按应用要求停写、刷盘或使用数据库原生备份机制。恢复到新 PVC 时,使用 dataSource 指向同一命名空间的 VolumeSnapshot。默认严格恢复策略要求有足够可用的快照副本;恢复卷容量不得小于快照 restoreSize。以下按原始 10Gi 卷举例,如果已经执行了前面的 20Gi 扩容,应改为 20Gi:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mayastor-restored-pvc
spec:
accessModes: [ReadWriteOnce]
storageClassName: mayastor-3
resources:
requests:
storage: 10Gi
dataSource:
name: mayastor-test-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
kubectl apply -f mayastor-restored-pvc.yaml
kubectl get pvc mayastor-restored-pvc -w
由于 StorageClass 使用 WaitForFirstConsumer,创建消费新 PVC 的测试 Pod 后才开始绑定和恢复。恢复完成后校验应用数据,再把数据备份到独立目标。VolumeSnapshot 本身仍依赖原集群和其存储池,不能作为唯一备份副本。异地备份至少需要保存应用配置、数据、加密密钥及恢复步骤,并定期验证恢复耗时和数据完整性。
9. 故障排查
下面的 $NAMESPACE、$PVC_NAME、$POD_NAME、$NODE 替换为故障工作负载的实际值,$PV_NAME、$VOLUME_ID 可按第 7 节从 PVC 获取。
# PVC 长时间 Pending
kubectl describe pvc "$PVC_NAME" -n "$NAMESPACE"
kubectl describe pod "$POD_NAME" -n "$NAMESPACE"
kubectl get events -A --sort-by=.lastTimestamp | tail -50
# 检查本地卷落在哪个节点和目录
kubectl get pv "$PV_NAME" -o yaml
kubectl get pod "$POD_NAME" -o wide
ssh "$NODE" 'findmnt -T /data/openebs/local; df -hT /data/openebs/local'
# 检查 OpenEBS 控制器和 CSI
kubectl get pods -n openebs -o wide
kubectl logs -n openebs deploy/openebs-localpv-provisioner --all-containers --tail=200
kubectl get csidrivers
# Mayastor 状态和事件
kubectl get dsp -n openebs -o wide
kubectl get events -n openebs --sort-by=.lastTimestamp | tail -80
kubectl mayastor get volumes -n openebs
kubectl mayastor get volume-replica-topology "$VOLUME_ID" -n openebs
排查本地卷时先检查节点是否 Ready、PV 的 nodeAffinity、BasePath 是否真实挂载,以及 kubelet 是否能访问该路径。排查 Mayastor 时按 io-engine Pod、DiskPool 状态、NVMe-TCP、HugePages、网络端口和副本重建顺序检查。不要通过删除 PV、清空目录或格式化设备来“修复” Pending 或故障卷。
| 现象 | 优先检查 |
|---|---|
| PVC Pending,提示等待首个消费者 | 先创建引用 PVC 的 Pod,再检查 Pod 调度事件 |
| Pod 提示 volume node affinity conflict | 本地卷所在节点是否可用,调度约束是否冲突;不要直接改 PV 节点身份 |
| Hostpath 数据突然为空 | 数据盘是否漏挂载,BasePath 是否误落系统盘,实际 PV 目录是否一致 |
| Mount 失败或 Permission denied | 文件系统/路径权限、运行 UID/GID、fsGroup、SELinux、kubelet 目录 |
| Mayastor io-engine Pending | 节点标签、HugePages、CPU/内存请求、污点和节点架构 |
| 副本 Degraded、重建失败 | 所有池容量、剩余健康副本、节点网络和设备错误 |
监控至少覆盖文件系统空间与 inode、DiskPool 已用/可用容量、卷副本状态、重建进度、I/O 延迟、磁盘错误和备份成功率。设置容量预警并预留一次副本重建所需空间;不要等池满才增加容量。性能测试应在独立测试 PVC 上运行,分别记录同步写延迟、随机 IOPS 和顺序吞吐,避免对业务数据直接压测。
10. 升级和卸载
helm list -n openebs
helm get values openebs -n openebs -a > openebs-values-backup.yaml
helm history openebs -n openebs
升级前备份应用数据和 Helm values,在测试集群先用同版本 chart 执行 helm template。卸载 chart 不等于删除卷数据;Hostpath 的 Retain PV、Mayastor DiskPool 和块设备都要按数据保留策略处理。没有确认备份和恢复演练结果时,不要删除 CRD、PV、DiskPool 或底层磁盘。
一次只维护一个存储节点,等待卷恢复完整副本后再处理下一个。Local PV 所在节点 drain 后,Pod 可能因为本地数据无法调度到其他节点;需要停机或由应用自身副本接管。旧 cStor、Jiva、Device LocalPV 文档和当前 chart 不能混用,跨大版本升级应按官方迁移路径执行;helm rollback 不能代替数据格式和 CRD 的迁移回退方案。
评论