16.5.6 本地存储与网络存储实践

本节聚焦生产环境中常见的本地存储与网络存储落地方式,覆盖选型、部署、使用与运维要点,强调性能、可用性与数据安全的权衡,并提供安装、命令、排错与练习示例。

一、本地存储(Local)实践

原理草图(本地PV与调度绑定)

文章图片
  • 适用场景:高性能、低延迟、数据可重建或可容忍节点级故障(如缓存、日志、临时计算数据、部分数据库热数据)。
  • 实现方式
  • local 卷 + nodeAffinity(生产建议)。
  • hostPath(仅开发测试,易误删/误挂载)。
  • 关键注意点
  • 调度约束:PVC 绑定后 Pod 必须调度到同一节点。
  • 故障处理:节点故障导致数据不可用,需应用层副本或重建。
  • 生命周期:结合 LVM/RAID,统一挂载点和命名规范。

安装与配置示例:Local PV 静态供给

1) 准备节点本地磁盘与目录

# 在 Node A 上执行
sudo mkdir -p /data/local1
sudo chmod 777 /data/local1
# 可选:通过 fstab 挂载独立磁盘到 /data/local1

2) 创建 StorageClass(禁止动态供给)

# /etc/k8s/manifests/sc-local.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-static
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

3) 创建 Local PV(绑定 Node A)

# /etc/k8s/manifests/pv-local.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-local-1
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-static
  local:
    path: /data/local1
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - node-a

4) 创建 PVC 与 Pod(自动绑定)

# /etc/k8s/manifests/pvc-local.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-local-1
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-static
  resources:
    requests:
      storage: 10Gi
---
# /etc/k8s/manifests/pod-local.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-local
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo local > /data/flag && sleep 3600"]
      volumeMounts:
        - mountPath: /data
          name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: pvc-local-1

5) 应用并验证

kubectl apply -f /etc/k8s/manifests/sc-local.yaml
kubectl apply -f /etc/k8s/manifests/pv-local.yaml
kubectl apply -f /etc/k8s/manifests/pvc-local.yaml
kubectl apply -f /etc/k8s/manifests/pod-local.yaml

kubectl get pv,pvc,pod -o wide
# 预期:PVC Bound,Pod 调度到 node-a

命令解释
- volumeBindingMode: WaitForFirstConsumer:延迟绑定,避免跨区调度。
- nodeAffinity:指定 PV 所在节点,确保 Pod 与 PV 同节点。

常见排错(本地存储)
- PVC Pending:检查 StorageClass 是否为 no-provisioner,PV 是否满足容量/SC。
- Pod Pending:检查节点标签与 nodeAffinity 是否匹配。
- 挂载失败:kubectl describe pod pod-local 查看事件,检查节点目录权限。


二、网络存储实践(NFS/iSCSI/分布式存储)

原理草图(NFS 共享存储)

文章图片
  • 适用场景:多节点共享、跨节点调度、有状态应用。
  • 常见方案
  • NFS:部署简单,适合中小规模。
  • iSCSI:块存储性能较好,但运维复杂。
  • 分布式存储:Ceph/Rook/Longhorn,高可用与弹性扩展。

安装与配置示例:NFS 服务器 + 静态 PV

1) NFS 服务器安装与导出

# 在 NFS Server 上
sudo yum install -y nfs-utils
sudo mkdir -p /export/k8s
sudo chmod 777 /export/k8s

# /etc/exports
/export/k8s *(rw,sync,no_root_squash)

sudo systemctl enable --now nfs-server
sudo exportfs -rv

2) 在 K8s 中创建 NFS PV 与 PVC

# /etc/k8s/manifests/pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-1
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 10.0.0.10
    path: /export/k8s
---
# /etc/k8s/manifests/pvc-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs-1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

3) 挂载验证

# /etc/k8s/manifests/pod-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nfs
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo nfs > /data/flag && sleep 3600"]
      volumeMounts:
        - mountPath: /data
          name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: pvc-nfs-1
kubectl apply -f /etc/k8s/manifests/pv-nfs.yaml
kubectl apply -f /etc/k8s/manifests/pvc-nfs.yaml
kubectl apply -f /etc/k8s/manifests/pod-nfs.yaml
kubectl exec -it pod-nfs -- cat /data/flag
# 预期输出:nfs

命令解释
- ReadWriteMany:允许多 Pod 跨节点读写。
- no_root_squash:避免容器内 root 写入受限(生产需谨慎)。

常见排错(NFS)
- mount.nfs: access denied:检查 /etc/exportsexportfs -rv
- Pod 卡在 ContainerCreating:检查节点是否安装 nfs-utils
- IO 慢:检查存储网络、NFS 线程/缓存参数。


三、本地与网络存储选型对比

  • 性能:本地存储优于网络存储。
  • 可用性:网络存储支持跨节点,容灾能力更强。
  • 复杂度:本地存储运维简单;分布式网络存储复杂。
  • 适配应用:数据库/状态服务优先网络存储;缓存/日志可选本地存储。

四、生产最佳实践(含命令)

1) 存储类型与数据等级匹配

kubectl label pvc pvc-nfs-1 data-tier=gold
kubectl label pvc pvc-local-1 data-tier=silver

2) 性能基线与告警

# 使用 fio 简易压测(在挂载 Pod 中)
kubectl exec -it pod-nfs -- sh -c "fio -name=randrw -rw=randrw -size=1G -bs=4k -runtime=30 -numjobs=1 -direct=1 -ioengine=libaio"

3) 统一命名规范

# 约定:pv-<app>-<env>-<idx>
kubectl get pv -o name | grep pv-

4) 备份与恢复演练

# 示例:打包并导出 NFS 数据
kubectl exec -it pod-nfs -- tar czf /data/backup.tar.gz /data

五、常见问题与处理思路(含排错命令)

  • PVC Pending
kubectl describe pvc pvc-local-1
kubectl get storageclass
# 排查:StorageClass 名称不一致、PV 容量不足、provisioner 不可用
  • 挂载失败
kubectl describe pod pod-nfs
kubectl logs -n kube-system <csi-plugin-pod>
# 排查:NFS 服务、CSI 驱动、节点依赖包
  • IO 性能不足
kubectl top node
kubectl exec -it pod-nfs -- iostat -xm 2 3
# 排查:存储后端瓶颈、网络拥塞、Pod 资源限制
  • 数据丢失风险
kubectl get pv pv-local-1 -o jsonpath='{.spec.persistentVolumeReclaimPolicy}{"\n"}'
# 建议:本地存储使用 Retain,并明确业务重建/备份策略

六、练习题

1) 使用本地 PV 创建一个 5Gi PVC,并确保 Pod 被调度到指定节点。
2) 搭建 NFS 服务并让两个 Pod 同时写入同一目录,验证 RWX。
3) 故意将 NFS 服务停掉,观察 Pod 事件并记录排错步骤。
4) 为 PVC 添加 data-tier 标签,并输出带标签的 PVC 列表。