HiHuo
首页
博客
手册
工具
首页
博客
手册
工具
  • Kubernetes 进阶

    • /books/k8s/
    • Kubernetes 高阶学习手册
    • 01-架构与核心概念
    • 02-网络体系
    • 03-存储管理
    • 04-调度控制
    • 05-发布与弹性
    • 06-安全与治理
    • 07-观测与SRE
    • 08-可靠性运维
    • 09-成本与容量
    • 10-故障排查
    • 11-运维工具
    • 12-生产清单
    • 13-AI平台集成

03-存储管理

Kubernetes PV/PVC、StorageClass、StatefulSet 状态管理全体系

学习目标

通过本模块学习,你将掌握:

  • Kubernetes 存储体系五层抽象
  • Volume 类型和生命周期管理
  • PV/PVC 绑定机制和回收策略
  • StorageClass 动态卷分配
  • StatefulSet 有状态应用部署
  • 存储故障排查和最佳实践

一、存储体系总览

核心设计理念

Kubernetes 存储的核心思想是:Pod 是临时的,但数据可以是持久的。

五层存储抽象

Pod → Volume → PVC → PV → StorageClass → 真实存储
 │      │      │     │        │            │
 │      │      │     │        │            ├─ NFS
 │      │      │     │        │            ├─ Ceph
 │      │      │     │        │            ├─ 云盘
 │      │      │     │        │            └─ 本地盘
 │      │      │     │        │
 │      │      │     │        └─ 动态分配策略
 │      │      │     │
 │      │      │     └─ 存储资源池
 │      │      │
 │      │      └─ 存储申请单
 │      │
 │      └─ 挂载点
 │
 └─ 容器访问点

存储层级对比

层级名称功能生命周期
Volume最基础挂载点Pod 内数据访问Pod 生命周期
PV持久卷存储资源池独立于 Pod
PVC持久卷声明存储申请单绑定 PV 后独立
StorageClass存储类动态分配策略集群级别
CSI容器存储接口驱动标准插件级别

二、Volume 类型详解

2.1 emptyDir(临时存储)

特点:Pod 生命周期内有效,重启即清空

apiVersion: v1
kind: Pod
metadata:
  name: emptydir-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: cache
      mountPath: /tmp/cache
  volumes:
  - name: cache
    emptyDir: {}

emptyDir 配置选项

volumes:
- name: cache
  emptyDir:
    sizeLimit: 1Gi  # 大小限制
    medium: Memory   # 使用内存(tmpfs)

2.2 hostPath(宿主机存储)

特点:直接挂载宿主机目录

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
  volumes:
  - name: logs
    hostPath:
      path: /var/log/nginx
      type: DirectoryOrCreate  # 目录不存在则创建

hostPath 类型

volumes:
- name: data
  hostPath:
    path: /data
    type: DirectoryOrCreate  # 目录或创建
    # type: Directory        # 必须存在目录
    # type: FileOrCreate     # 文件或创建
    # type: File             # 必须存在文件
    # type: Socket           # Unix socket
    # type: CharDevice       # 字符设备
    # type: BlockDevice      # 块设备

️ 风险提示:hostPath 存在数据丢失风险,节点调度变化会导致数据丢失。

2.3 其他 Volume 类型

configMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  config.yaml: |
    database:
      host: localhost
      port: 3306
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: config
      mountPath: /etc/config
  volumes:
  - name: config
    configMap:
      name: app-config

secret

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  password: cGFzc3dvcmQ=  # base64 编码
---
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: secret
      mountPath: /etc/secret
  volumes:
  - name: secret
    secret:
      secretName: app-secret

三、PersistentVolume(PV)

3.1 PV 核心概念

PV 是集群管理员预先配置的存储资源池,独立于 Pod 生命周期。

3.2 PV 配置示例

NFS PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /mnt/data
    server: 192.168.1.10

本地存储 PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-local
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  local:
    path: /data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node1

云存储 PV(AWS EBS)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-ebs
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  awsElasticBlockStore:
    volumeID: vol-12345678
    fsType: ext4

3.3 访问模式(Access Modes)

模式说明适用场景
ReadWriteOnce (RWO)单节点可读写数据库、单实例应用
ReadOnlyMany (ROX)多节点只读配置文件、只读数据
ReadWriteMany (RWX)多节点可读写共享存储、文件系统

3.4 回收策略(Reclaim Policy)

策略行为适用场景
Retain删除 PVC 不删除 PV 数据重要数据,手动管理
Delete删除 PVC 时同时清理后端存储动态卷,自动清理
Recycle删除后清空目录(已废弃)临时用途(不推荐)

四、PersistentVolumeClaim(PVC)

4.1 PVC 核心概念

PVC 是用户对存储资源的申请单,系统会自动匹配合适的 PV。

4.2 PVC 配置示例

基本 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: ""  # 空字符串表示使用默认 StorageClass

指定 StorageClass 的 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-sc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-sc

绑定特定 PV 的 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-specific
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  volumeName: pv-nfs  # 指定特定 PV

4.3 PVC 绑定机制

绑定条件

  1. 存储容量:PVC 请求 ≤ PV 容量
  2. 访问模式:PVC 访问模式 ⊆ PV 访问模式
  3. StorageClass:PVC 和 PV 的 StorageClass 匹配
  4. 标签选择器:PVC 的 selector 匹配 PV 标签

绑定过程

graph TD
    A[PVC 创建] --> B[查找匹配 PV]
    B --> C{找到匹配 PV?}
    C -->|是| D[绑定 PV]
    C -->|否| E[等待匹配 PV]
    D --> F[PVC 状态变为 Bound]
    E --> G[PVC 状态保持 Pending]

️ 五、StorageClass(动态卷分配)

5.1 StorageClass 核心概念

StorageClass 定义了动态卷分配的策略,无需管理员手动创建 PV。

5.2 StorageClass 配置示例

NFS StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-sc
provisioner: example.com/nfs
parameters:
  server: nfs-server.example.com
  path: /mnt/data
  mountOptions: "nfsvers=4"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate

云存储 StorageClass(AWS EBS)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

本地存储 StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

5.3 StorageClass 参数说明

关键参数

  • provisioner:卷提供者
  • reclaimPolicy:回收策略
  • allowVolumeExpansion:是否允许扩容
  • volumeBindingMode:绑定模式
    • Immediate:立即绑定
    • WaitForFirstConsumer:等待第一个消费者

5.4 动态卷分配流程

graph TD
    A[PVC 创建] --> B[匹配 StorageClass]
    B --> C[调用 Provisioner]
    C --> D[创建后端存储]
    D --> E[创建 PV]
    E --> F[绑定 PVC 和 PV]
    F --> G[Pod 使用存储]

️ 六、StatefulSet(有状态应用)

6.1 StatefulSet 核心特性

StatefulSet 为有状态应用提供:

  • 稳定标识:Pod 名称固定(如 mysql-0、mysql-1)
  • 有序部署:从 0 → N 顺序启动
  • 有序删除:从 N → 0 顺序销毁
  • 持久卷绑定:Pod 与 PVC 一一绑定

6.2 StatefulSet 配置示例

MySQL StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: db
spec:
  clusterIP: None  # Headless Service
  selector:
    app: mysql
  ports:
  - port: 3306
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: db
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "root123"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 5Gi
      storageClassName: standard

Redis StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: cache
spec:
  clusterIP: None
  selector:
    app: redis
  ports:
  - port: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: cache
spec:
  serviceName: redis
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7
        ports:
        - containerPort: 6379
        command:
        - "redis-server"
        - "--appendonly"
        - "yes"
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 2Gi
      storageClassName: standard

6.3 StatefulSet 关键配置

更新策略

spec:
  updateStrategy:
    type: RollingUpdate  # 或 OnDelete
    rollingUpdate:
      partition: 1  # 从索引 1 开始更新

Pod 管理策略

spec:
  podManagementPolicy: OrderedReady  # 默认,有序启动
  # podManagementPolicy: Parallel    # 并行启动

6.4 StatefulSet 与 Deployment 对比

特性DeploymentStatefulSet
Pod 名称随机生成固定编号(有序)
存储共享或临时独立 PVC
调度可并行有序(默认)
用途无状态服务有状态数据服务
网络标识不固定稳定网络标识

七、CSI(容器存储接口)

7.1 CSI 核心概念

CSI 是云原生存储的标准接口规范,让不同厂商的存储插件统一化。

7.2 主流 CSI 驱动

厂商CSI 驱动存储类型
AWSebs.csi.aws.comEBS
阿里云diskplugin.csi.alibabacloud.com云盘
腾讯云com.tencent.cloud.csi.cbsCBS
华为云everest-csi-driverEVS
Cephrbd.csi.ceph.comRBD

7.3 CSI 安装示例(AWS EBS)

# 安装 AWS EBS CSI 驱动
kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.19"

# 验证安装
kubectl get pods -n kube-system -l app=ebs-csi-controller
kubectl get pods -n kube-system -l app=ebs-csi-node

7.4 CSI 工作原理

graph TD
    A[Pod 创建] --> B[kubelet]
    B --> C[CSI Node Plugin]
    C --> D[CSI Controller Plugin]
    D --> E[云存储 API]
    E --> F[创建存储卷]
    F --> G[挂载到 Pod]

️ 八、命令速记

存储资源管理

# 查看 PV、PVC、StorageClass
kubectl get pv,pvc,sc

# 查看存储详情
kubectl describe pv <pv-name>
kubectl describe pvc <pvc-name>
kubectl describe sc <sc-name>

# 查看 Pod 挂载的卷
kubectl describe pod <pod-name>

# 查看 StatefulSet
kubectl get sts
kubectl describe sts <sts-name>

存储操作

# 创建存储资源
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
kubectl apply -f storageclass.yaml

# 删除存储资源
kubectl delete pv <pv-name>
kubectl delete pvc <pvc-name>
kubectl delete sc <sc-name>

# 扩容 PVC
kubectl patch pvc <pvc-name> -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'

故障排查

# 查看存储事件
kubectl get events --sort-by=.lastTimestamp

# 查看 CSI 插件日志
kubectl logs -n kube-system -l app=ebs-csi-controller
kubectl logs -n kube-system -l app=ebs-csi-node

# 检查存储挂载
kubectl exec <pod> -- df -h
kubectl exec <pod> -- mount | grep <volume-name>

九、面试核心问答

Q1: PV 与 PVC 的关系是什么?

答案要点:

  • PVC 是存储申请单,PV 是存储资源池
  • 系统自动匹配 PVC 和 PV
  • 绑定条件:容量、访问模式、StorageClass
  • 绑定后 PVC 和 PV 生命周期独立

Q2: StatefulSet 与 Deployment 的区别?

答案要点:

  • StatefulSet:有唯一身份 + 稳定存储
  • Deployment:无状态服务
  • StatefulSet:有序部署、固定网络标识
  • Deployment:并行部署、随机网络标识

Q3: 如何实现动态卷创建?

答案要点:

  • 使用 StorageClass 定义分配策略
  • 配置 Provisioner 处理卷创建
  • PVC 自动触发 PV 创建
  • 支持云存储和本地存储

Q4: 如何防止存储数据丢失?

答案要点:

  • 设置 reclaimPolicy=Retain
  • 定期备份 PV 数据
  • 使用高可用存储后端
  • 配置数据复制策略

Q5: CSI 的作用是什么?

答案要点:

  • 统一存储插件接口标准
  • 支持云厂商和开源存储
  • 解耦存储逻辑和 Kubernetes
  • 提供标准化的存储操作

十、故障排查

常见存储问题

1. PVC 无法绑定 PV

# 检查 PVC 状态
kubectl describe pvc <pvc-name>

# 检查可用 PV
kubectl get pv

# 检查 StorageClass
kubectl get sc
kubectl describe sc <sc-name>

# 检查匹配条件
kubectl get pv -o custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage,ACCESSMODES:.spec.accessModes,STORAGECLASS:.spec.storageClassName

2. Pod 挂载失败

# 检查 Pod 状态
kubectl describe pod <pod-name>

# 检查 PVC 绑定状态
kubectl get pvc

# 检查存储插件
kubectl get pods -n kube-system | grep csi

# 查看存储插件日志
kubectl logs -n kube-system <csi-pod>

3. 动态卷创建失败

# 检查 Provisioner 状态
kubectl get pods -n kube-system -l app=<provisioner>

# 查看 Provisioner 日志
kubectl logs -n kube-system <provisioner-pod>

# 检查存储后端连接
kubectl exec <provisioner-pod> -- ping <storage-server>

4. StatefulSet 启动失败

# 检查 StatefulSet 状态
kubectl describe sts <sts-name>

# 检查 Pod 状态
kubectl get pods -l app=<app-name>

# 检查 PVC 状态
kubectl get pvc

# 查看事件
kubectl get events --sort-by=.lastTimestamp

十一、最佳实践

存储设计建议

  1. 存储类型选择

    • 数据库:RWO + 高性能存储
    • 文件共享:RWX + 网络存储
    • 配置数据:ConfigMap/Secret
  2. 容量规划

    • 合理设置存储大小
    • 预留扩容空间
    • 监控存储使用率
  3. 备份策略

    • 定期备份重要数据
    • 测试恢复流程
    • 多地存储备份
  4. 性能优化

    • 选择高性能存储
    • 优化挂载参数
    • 监控 IO 性能

安全建议

  1. 访问控制

    • 限制存储访问权限
    • 使用 RBAC 管理
    • 加密敏感数据
  2. 数据保护

    • 启用存储加密
    • 定期安全扫描
    • 审计存储访问

十二、总结

通过本模块学习,你已经掌握了:

  • Kubernetes 存储体系五层抽象
  • Volume 类型和生命周期管理
  • PV/PVC 绑定机制和回收策略
  • StorageClass 动态卷分配
  • StatefulSet 有状态应用部署
  • CSI 容器存储接口
  • 存储故障排查技能
  • 存储最佳实践

下一步建议:继续学习 04-调度控制,深入了解 Kubernetes 资源管理和调度策略。

Prev
02-网络体系
Next
04-调度控制