4. PowerStore CSI集成实战

本节把前面学到的 CSI 原理落到 Dell PowerStore 上,完成一条从阵列侧到 Pod 侧的完整链路:先在 PowerStore 上准备可供 CSI 使用的 NAS 服务器与文件系统,再在 Kubernetes 集群中安装 PowerStore CSI 驱动,接着定义 StorageClass,最后通过 PVC 触发动态卷供给,并把卷挂载进 Pod 验证读写。整条链路的判断依据是:PVC 能 Bound、PV 在 PowerStore 上真实存在、Pod 内可读写且数据落盘。

一、PowerStore 阵列侧准备

PowerStore CSI 驱动同时支持块(iSCSI/FC)与文件(NFS)两种访问方式。本节以 NFS 文件卷为例,因为它对实验环境最友好,不需要在每台节点上配置多路径。阵列侧需要准备三样东西:一个 NAS 服务器、一个文件系统、一个供 CSI 使用的存储网络地址。

登录 PowerStore Manager,进入 Storage → NAS Servers,创建一个 NAS 服务器,例如命名为 nas-k8s,选择文件系统所在的数据网络。随后进入 Storage → File Systems 创建文件系统,示例参数如下:名称 fs-k8s-csi,容量 200 GB,所属 NAS 服务器 nas-k8s,访问策略允许 Kubernetes 节点网段 192.168.30.0/24 读写。创建完成后记录 NAS 服务器 IP,例如 192.168.30.50,这个地址会作为 CSI 的 NFS 服务端。

还需要在 PowerStore 上创建一个供 CSI 调用的本地用户,例如 csi-user,赋予其管理文件系统的权限。CSI 驱动通过 REST API 与该用户通信,因此要记录用户名和密码,后续写入 Secret。若使用块存储,则改为准备主机组、iSCSI 或 FC 启动器,并确保节点已登录到阵列;文件方式无需这一步。

阵列侧准备的核心是“地址 + 凭据 + 容量”三要素:NAS 服务器 IP 给驱动连接,用户名密码给驱动认证,文件系统容量决定可供给的上限。三者缺一,后续 PVC 都会卡在 Pending。

二、安装 PowerStore CSI 驱动

PowerStore CSI 驱动以 Helm Chart 形式发布,官方仓库为 https://dell.github.io/csm-helm-charts。安装前先确认集群版本与驱动版本匹配,并确认所有工作节点都能访问 NAS 服务器 IP 的 2049 端口。

helm repo add dell https://dell.github.io/csm-helm-charts
helm repo update
helm search repo dell/powerstore --versions | head -5

创建命名空间并写入连接凭据。PowerStore 的凭据以 Secret 形式提供,包含阵列管理 IP、用户名和密码:

kubectl create namespace powerstore
kubectl -n powerstore create secret generic powerstore-config \
  --from-literal=username='csi-user' \
  --from-literal=password='YourPassword' \
  --from-literal=endpoint='https://192.168.30.50'

随后安装驱动。文件卷场景需要显式开启 NFS 能力,并指定 NAS 服务器地址:

helm -n powerstore install powerstore dell/powerstore \
  --set nfs.enabled=true \
  --set nfs.nasServerIP=192.168.30.50 \
  --set controller.replicas=1 \
  --set node.replicas=3

安装完成后检查 Pod 状态,应看到 controller 与 node 两类组件全部 Running:

kubectl -n powerstore get pods
# powerstore-controller-0        5/5  Running
# powerstore-node-xxxxx          3/3  Running   (每个节点一个)

controller 负责与 PowerStore REST API 交互,完成卷的创建、删除、扩容和快照;node 以 DaemonSet 形式运行在每个节点上,负责把远端文件系统挂载到本地路径。两者都 Running,才说明驱动已就绪。

PowerStore CSI 集成链路:阵列 → 驱动 → StorageClass → PVC → Pod PowerStore 阵列 NAS Server: nas-k8s FS: fs-k8s-csi 200GB NFS 192.168.30.50 PowerStore CSI 驱动 controller: REST API 调用 node: DaemonSet 挂载 Secret: csi-user / endpoint StorageClass provisioner: powerstore reclaimPolicy: Delete volumeBinding: Immediate PVC / PV pvc-data 10Gi 状态 Bound PV 已创建 Pod 挂载验证 app-pod volumeMounts: /data claimName pvc-data 验证:写入 /data/test.txt → 卸载重挂 → 数据仍在 PowerStore 上可见对应文件系统目录 PVC 绑定后挂载 常见卡点 • PVC Pending:SC 名称不匹配 • 挂载失败:2049 端口不通 • 认证失败:Secret 密码错误 • 容量不足:FS 剩余空间不够 • node Pod 未就绪:驱动未装全

三、配置 StorageClass

StorageClass 是 PVC 与驱动之间的“契约”,它告诉 Kubernetes:这类 PVC 应该由哪个 provisioner 供给、用什么参数、回收策略是什么。PowerStore 驱动的 provisioner 名称为 csi-powerstore.dellemc.com。文件卷场景的示例如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: powerstore-nfs
provisioner: csi-powerstore.dellemc.com
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  csi.storage.k8s.io/fstype: nfs
  arrayID: "APM00123456789"

其中 arrayID 是 PowerStore 阵列的唯一标识,可在阵列管理界面或 REST API 中查询;fstype: nfs 表示走文件卷路径。若使用块卷,则去掉 fstype 并改为指定协议类型。创建后执行 kubectl get sc,应看到 powerstore-nfs 且 provisioner 正确。

四、动态卷供给与 Pod 挂载验证

动态供给的关键在于:用户只声明 PVC,不手动创建 PV。先写一个 PVC,指定 storageClassName 与容量:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-data
spec:
  accessModes: ["ReadWriteMany"]
  storageClassName: powerstore-nfs
  resources:
    requests:
      storage: 10Gi

应用后观察状态变化:kubectl get pvc pvc-data -w。正常情况下会从 Pending 变为 Bound,同时 kubectl get pv 会出现一个自动创建的 PV,其名称通常带有阵列生成的卷 ID。此时回到 PowerStore Manager,在文件系统下应能看到 CSI 自动创建的子目录或卷对象,容量为 10Gi。这就是“动态供给”的直接证据:PV 不是人写的,而是驱动调用阵列 API 创建的。

接着创建 Pod 挂载该 PVC:

apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: busybox:1.36
    command: ["sh","-c","sleep 3600"]
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-data

Pod Running 后进入容器验证:

kubectl exec -it app-pod -- sh
/ # echo "powerstore-csi-test" > /data/test.txt
/ # cat /data/test.txt
powerstore-csi-test

为了确认数据真正落在 PowerStore 而非节点本地,可以删除 Pod 再重建,重新挂载同一 PVC 后再次读取 /data/test.txt。如果内容仍在,说明卷是持久化的、由阵列承载的。进一步可在 PowerStore 侧查看该文件系统已用容量增加,或通过 NFS 客户端从节点直接挂载 NAS 服务器 IP 查看同一目录,形成交叉验证。

验证时不要只看 Pod 是否 Running。Running 只说明容器起来了,不代表卷挂载成功。必须进入容器实际写入并读取文件,再通过删除重建 Pod 确认数据不丢,才算完成闭环。若 PVC 一直 Pending,优先检查 StorageClass 名称、provisioner 拼写和 controller Pod 日志。

五、结果判读与常见问题

整条链路的成功标志可以归纳为四个可观察点:PVC 状态为 Bound;PV 自动出现且容量与请求一致;Pod 内 /data 可读写;删除重建 Pod 后数据仍在。任何一点不满足,都说明链路某处断开。

常见问题中,PVC Pending 多因 StorageClass 名称不匹配或 provisioner 未就绪;挂载失败多因节点到 NAS 服务器 2049 端口不通或防火墙拦截;认证失败则检查 Secret 中的用户名密码与阵列是否一致。排查时按“阵列 → 驱动 → StorageClass → PVC → Pod”的顺序逐段确认,比盲目重启组件更有效。

完成本节后,你已经打通了 PowerStore CSI 从阵列准备到 Pod 挂载的完整路径。这条路径也是后续快照、扩容、克隆等高级能力的基础:只要动态供给链路是通的,其余操作都只是在同一套 CSI 接口上增加参数与调用。