OpenEBS

OpenEBS OpenEBS 是 Kubernetes 的容器原生存储项目,把节点上的目录、块设备或存储池提供给持久卷。Hostpath 使用动态 Local PV provisioner,LVM、ZFS 和 Mayastor 使用各自的 CSI 驱动;它们的安装要求和数据保护能力不同。 1. 先

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 的迁移回退方案。

参考

评论