PersistentVolumeClaim
学习目标
- 理解 PersistentVolumeClaim (PVC) 的作用
- 掌握 PVC 如何绑定 PV
- 学会在 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...