系列导航
本系列从 K8s 存储模型入手,逐步展开到 CSI 插件实现与云原生存储全景。
① 概念 → ② Volume 生命周期 → ③ CSI 架构 → ④ FlexVolume 演进 → ⑤ 对比 → ⑥ 排障 ‖ ⑦ 开发 → ⑧ 高级特性 → ⑨ 演进展望
重要
存储排障按 Volume 生命周期逐阶段定位:PVC 是否 Pending → PV 是否 Bound → Attach 是否成功 → Mount 是否成功 → 文件系统是否可读写。每一步都有对应的 kubectl 命令和日志检查点。
1. 基础诊断工具链
| 工具 | 用途 | 示例 |
|---|
kubectl get pvc/pv/sc | 查看 PVC/PV/StorageClass 状态 | kubectl get pvc -A |
kubectl describe pvc/pv | 查看事件和绑定状态 | kubectl describe pvc data-pvc |
kubectl get volumeattachment | 查看 Attach 状态 | kubectl get volumeattachment |
kubectl get pod -o yaml | 查看 Pod 的 Volume 挂载配置 | kubectl get pod web -o yaml |
kubectl logs | 查看 CSI Sidecar 日志 | kubectl logs csi-provisioner -n kube-system |
kubectl describe pod | 查看 Pod 事件(Mount 失败信息) | kubectl describe pod web |
lsblk | 节点上查看块设备 | ssh node-1 && lsblk |
df -h | 节点上查看挂载点 | df -h /var/lib/kubelet |
| `mount | grep kubelet` | 查看 kubelet 相关挂载 |
findmnt | 查看挂载树 | findmnt /var/lib/kubelet/pods/<id> |
dmesg | 内核日志(I/O 错误) | `dmesg |
2. 按现象排查
2.1 PVC 一直 Pending
1
2
3
| kubectl get pvc
#NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
#data-pvc Pending fast 5m
|
| 原因 | 检查方法 | 解决方案 |
|---|
| StorageClass 不存在 | kubectl get sc fast | 创建 StorageClass |
| provisioner 未运行 | kubectl get pods -n kube-system | grep provisioner | 检查 CSI Controller Pod |
WaitForFirstConsumer 延迟绑定 | kubectl get sc fast -o yaml | grep bindingMode | 创建 Pod 后才会绑定 |
| IPAM/容量不足 | kubectl logs csi-provisioner -n kube-system | 扩展存储后端容量 |
| CSI 插件 CreateVolume 失败 | kubectl logs csi-plugin -n kube-system | 查看插件日志定位 |
2.2 Pod 卡在 ContainerCreating
1
2
3
4
5
6
7
| kubectl get pod web
#NAME READY STATUS RESTARTS AGE
#web 0/1 ContainerCreating 0 3m
kubectl describe pod web
# Events:
# Warning FailedMount ... Unable to attach or mount volumes: ...
|
| 原因 | 检查方法 | 解决方案 |
|---|
| Attach 失败 | kubectl get volumeattachment | 检查 CSI attacher 日志 |
| Mount 失败 | kubectl describe pod 中的 Events | 检查节点上 CSI Node Pod 是否运行 |
| 设备路径不存在 | ssh node && lsblk | 检查块设备是否已 Attach |
| 文件系统损坏 | dmesg | tail | fsck 修复或重建 Volume |
| 权限不足 | kubectl logs csi-node -n kube-system | 确认 DaemonSet 以 privileged 运行 |
2.3 PV 无法删除
1
2
3
| kubectl get pv
#NAME STATUS CLAIM ... REASON
#pv-abcde Terminating default/data-pvc ... Volume detachment is pending
|
| 原因 | 检查方法 | 解决方案 |
|---|
| VolumeAttachment 未删除 | kubectl get volumeattachment | 手动删除 VolumeAttachment |
| finalizer 卡住 | kubectl get pv pv-abcde -o yaml | grep finalizer | 手动移除 finalizer(谨慎) |
| CSI 插件 DeleteVolume 失败 | kubectl logs csi-provisioner | 检查底层存储是否已删除 |
1
2
| # 手动移除 finalizer(最后手段)
kubectl patch pv pv-abcde -p '{"metadata":{"finalizers":null}}'
|
2.4 Volume 只读(Read-only filesystem)
| 原因 | 检查方法 | 解决方案 |
|---|
| 底层存储故障 | dmesg | grep "I/O error" | 修复存储或迁移数据 |
| 文件系统损坏 | fsck 检查 | 修复文件系统 |
| 磁盘空间满 | df -h | 扩容或清理数据 |
3. 性能排查
3.1 IOPS / 延迟测量
1
2
3
4
5
6
7
| # 在 Pod 内用 fio 测量
kubectl exec -it pod-with-volume -- fio --name=test --ioengine=libaio --rw=randwrite --bs=4k --size=1G --runtime=60
# 节点上用 iostat 查看设备级 I/O
iostat -x 1 /dev/xvdf
#Device r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await
#xvdf 100.00 200.00 800.00 1600.00 8.00 0.50 1.67
|
3.2 常见性能瓶颈
| 瓶颈 | 现象 | 排查方向 |
|---|
| 网络带宽 | Ceph/NFS 跨节点延迟高 | iperf3 测节点间带宽 |
| 磁盘 I/O | Local PV IOPS 不达标 | fio 裸盘测试 vs 挂载测试对比 |
| CSI 插件开销 | Attach/Mount 耗时 >30s | 检查 CSI 插件日志是否有重试 |
| 内核参数 | 大量并发 I/O 时延迟尖峰 | tuned 调整 I/O scheduler |
4. 各 CSI 插件常用排障命令
4.1 Ceph-CSI
1
2
3
4
5
6
7
8
9
10
11
| # 查看 Ceph 集群状态
ceph -s
ceph osd df
# 查看 RBD 镜像
rbd ls -p kubernetes
rbd info kubernetes/csi-vol-xxx
# 查看 Ceph 日志
kubectl logs csi-rbd-plugin -n kube-system
kubectl logs csi-rbd-provisioner -n kube-system
|
4.2 Longhorn
1
2
3
4
5
6
7
8
9
10
| # 查看 Longhorn Volume
kubectl get volumes.longhorn.io -n longhorn-system
kubectl describe volume <name> -n longhorn-system
# 查看副本状态
kubectl get replicas.longhorn.io -n longhorn-system
# Longhorn UI
# 端口转发到本地
kubectl port-forward -n longhorn-system svc/longhorn-frontend 8080:80
|
4.3 NFS-CSI
1
2
3
4
5
6
7
8
| # 检查 NFS 服务可达性
showmount -e <nfs-server>
# 手动挂载测试
mount -t nfs <server>:<path> /mnt/test
# 查看 NFS 挂载
mount | grep nfs
|
参考链接