63·存储进阶

PersistentVolumeClaim

kubernetesstoragepvcpersistent-volume-claim

PersistentVolumeClaim

学习目标

  1. 理解 PersistentVolumeClaim (PVC) 的作用
  2. 掌握 PVC 如何绑定 PV
  3. 学会在 Pod 中使用 PVC

核心概念

PVC 是什么

PersistentVolumeClaim (持久卷声明):
┌─────────────────────────────────────┐
│  用户对存储资源的"申请"              │
│                                      │
│  - 描述需要什么样的存储              │
│  - 不关心底层实现                    │
│  - 类似于"我要 10G 的读写存储"       │
└─────────────────────────────────────┘

类比:
PV = 硬盘(供应方)
PVC = 购买申请(需求方)
系统自动匹配合适的 PV

PVC 与 PV 的关系

PVC(需求)              PV(供应)
┌──────────────┐        ┌──────────────┐
│ 需要 10Gi    │        │ 提供 10Gi    │
│ ReadWrite    │  匹配  │ ReadWrite    │
│ StorageClass │◄──────►│ StorageClass │
│   : fast     │        │   : fast     │
└──────────────┘        └──────────────┘

绑定条件:
1. 容量:PV.capacity >= PVC.request
2. 访问模式:PV 包含 PVC 请求的模式
3. StorageClass:名称一致(或都为空)
4. PV 状态:Available

PVC YAML 结构

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:           # 请求的访问模式
    - ReadWriteOnce
  resources:             # 资源需求
    requests:
      storage: 10Gi
  storageClassName: manual  # 指定存储类
  volumeName: my-pv      # 可选:直接指定 PV

绑定过程

步骤 1:创建 PVC
  kubectl apply -f pvc.yaml

步骤 2:Kubernetes 寻找匹配的 PV
  - 检查 PV 状态是否 Available
  - 检查容量是否满足
  - 检查访问模式是否匹配
  - 检查 StorageClass 是否一致

步骤 3:绑定
  PV 状态:Available → Bound
  PVC 状态:Pending → Bound

步骤 4:Pod 使用 PVC
  Pod 通过 volumeClaimRef 引用 PVC

PVC 状态

状态说明
Pending等待绑定,未找到合适的 PV
Bound已绑定到 PV
Lost绑定的 PV 不存在

在 Pod 中使用 PVC

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: my-storage
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc    # 引用 PVC

完整示例

创建 PV:
┌────────────────────────────┐
│ PV: local-pv               │
│ capacity: 10Gi             │
│ accessModes: ReadWriteOnce │
│ hostPath: /tmp/data        │
└────────────────────────────┘
            │
            │ 绑定
            ▼
创建 PVC:
┌────────────────────────────┐
│ PVC: local-pvc             │
│ request: 10Gi              │
│ accessModes: ReadWriteOnce │
└────────────────────────────┘
            │
            │ 挂载
            ▼
创建 Pod:
┌────────────────────────────┐
│ Pod: my-pod                │
│ volumeMounts:              │
│   - mountPath: /data       │
│     name: my-storage       │
│ volumes:                   │
│   - name: my-storage       │
│     pvc: local-pvc         │
└────────────────────────────┘

实践练习

练习 1:创建 PVC

# pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
# 先确保有匹配的 PV(参考 62-persistent-volume)
kubectl apply -f pvc-demo.yaml
kubectl get pvc pvc-demo

练习 2:使用 PVC 创建 Pod

# pod-with-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-pvc
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: web-data
  volumes:
    - name: web-data
      persistentVolumeClaim:
        claimName: pvc-demo
kubectl apply -f pod-with-pvc.yaml

# 写入数据
kubectl exec pod-with-pvc -- sh -c "echo 'Hello PVC' > /usr/share/nginx/html/index.html"

# 删除 Pod
kubectl delete pod pod-with-pvc

# 重新创建 Pod,数据仍然存在
kubectl apply -f pod-with-pvc.yaml
kubectl exec pod-with-pvc -- cat /usr/share/nginx/html/index.html

练习 3:查看绑定状态

# 查看 PVC 详情
kubectl describe pvc pvc-demo

# 查看 PV 与 PVC 的绑定关系
kubectl get pv,pvc

# 查看 Events 中的绑定信息
kubectl get events --field-selector involvedObject.name=pvc-demo

常见误解

1. PVC 不创建存储

PVC 只是对存储的"请求",不会创建实际的存储资源
存储由 PV(手动创建)或 StorageClass(动态创建)提供

2. 绑定是排他性的

一个 PV 只能绑定一个 PVC(除非使用 ReadWriteMany)
PVC 绑定后,其他 PVC 无法使用同一个 PV

小结

要点说明
PVC用户对存储的请求声明
绑定自动匹配满足条件的 PV
状态Pending → Bound(或 Lost)
使用Pod 通过 volumes.persistentVolumeClaim 引用
解耦用户不需要关心底层存储细节

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「StorageClass」 以巩固所学知识。