Qingular

PersistentVolumeClaim(PVC)

·CKAk8s练习

CKA 考试 Domain 4 — PVC 创建、PV 绑定机制、Pod 挂载、扩容、Selector 绑定

← 返回 CKA 练习目录 PersistentVolumeClaim 是用户对存储的请求。Pod 使用 PVC 来请求存储资源,Kubernetes 会将 PVC 绑定到满足条件的 PV 上。


1. PVC 与 PV 绑定机制

PVC 绑定 PV 时需要满足以下条件:

  • 容量:PV 的 capacity.storage >= PVC 的 resources.requests.storage`
  • 访问模式:PV 必须支持 PVC 要求的访问模式
  • 存储类:如果 PVC 指定了 storageClassName,PV 必须匹配(或使用动态供给)
  • 选择器:如果 PVC 设置了 selector,PV 的标签必须匹配

注意:一个 PVC 只能绑定一个 PV,两者是一对一的关系。


2. PVC 示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: ""    # "" 表示使用静态 PV,省略则使用默认 StorageClass

3. 有 Selector vs 无 Selector 绑定

无 Selector 绑定

Kubernetes 自动匹配符合条件的 PV(容量、访问模式、存储类)。

spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

有 Selector 绑定

精确匹配带特定标签的 PV。

spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  selector:
    matchLabels:
      type: ssd
      environment: production
    matchExpressions:
      - key: tier
        operator: In
        values:
          - fast

对应的 PV 标签:

metadata:
  labels:
    type: ssd
    environment: production
    tier: fast

4. Pod 挂载 PVC

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: my-storage
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc

5. 完整示例:PV + PVC + Pod

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/pv

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi

Pod

apiVersion: v1
kind: Pod
metadata:
  name: storage-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo 'Hello CKA' > /data/index.html && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: example-pvc

6. PVC 扩容

需要 PV 后端支持扩容(如 AWS EBS、GCE PD 等),且 PV 的 allowVolumeExpansion: true

# 编辑 PVC,修改 storage 大小
kubectl edit pvc example-pvc
spec:
  resources:
    requests:
      storage: 2Gi   # 从 1Gi 扩容到 2Gi

扩容后使用 kubectl get pvc 查看状态,PVC 会显示 FileSystemResizePending 直到完成。


7. 实用命令

# 查看 PVC
kubectl get pvc

# 查看 PVC 详情(检查绑定的 PV)
kubectl describe pvc <pvc-name>

# 查看 PVC 的 YAML
kubectl get pvc <pvc-name> -o yaml

# 删除 PVC
kubectl delete pvc <pvc-name>

# 检查 PVC 是否已绑定
kubectl get pvc -o wide

8. 考试要点

  • PVC 必须和 PV 在同一命名空间下才能绑定
  • PVC 的 storageClassName: "" 表示使用静态 PV(不启用动态供给)
  • kubectl describe pvc 可以看到绑定失败的原因
  • 如果所有 PV 都不满足条件,PVC 将保持 Pending 状态
  • PVC 扩容只增不减

🧪 完整操作实例:Pod 挂载 PVC 实现持久化存储

场景描述

创建一个 PVC 绑定 PV,然后在 Pod 中使用该 PVC 存储数据。删除 Pod 后重建,验证数据是否持久保留。

前置条件

  • 集群中存在可用的 PV(或使用动态供给)
  • 能够创建和管理 Pod

操作步骤

Step 1: 创建 hostPath PV

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/pv-data
    type: DirectoryOrCreate
EOF

kubectl get pv
# NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   AGE
# pv-data  1Gi        RWO            Retain           Available           manual         5s

Step 2: 创建 PVC

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
EOF

Step 3: 验证 PVC 绑定状态

kubectl get pvc
# NAME         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
# claim-data   Bound    pv-data  1Gi        RWO            manual         10s

kubectl describe pvc claim-data
# Name:          claim-data
# Namespace:     default
# Status:        Bound
# Volume:        pv-data
# ...

Step 4: 创建 Pod 挂载 PVC 并发写数据

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: writer-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo 'CKA Data Persistence Test' > /data/test.txt && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: claim-data
EOF

# 等待 Pod 运行
kubectl get pod writer-pod -w

Step 5: 验证数据已写入

kubectl exec writer-pod -- cat /data/test.txt
# CKA Data Persistence Test

Step 6: 删除 Pod 并重建

kubectl delete pod writer-pod

# 重建一个同名 Pod 或新 Pod 挂载同一 PVC
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: reader-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "cat /data/test.txt && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: claim-data
EOF

# 等待新 Pod 运行
kubectl get pod reader-pod -w

验证结果

# 验证数据持久性(之前写入的数据仍然存在)
kubectl logs reader-pod
# CKA Data Persistence Test

# 或者直接执行命令
kubectl exec reader-pod -- cat /data/test.txt
# CKA Data Persistence Test

考试提示

  • PVC 绑定 PV 是一对一关系,绑定后其他 PVC 无法使用同一 PV
  • Pod 删除后 PVC 和 PV 依然存在,数据不会丢失
  • 多个 Pod 挂载同一 PVC 取决于 Access Mode(RWO 只允许单节点)
  • 考试中常见错误:忘记在 Pod 的 volumesvolumeMounts 中正确配置
  • 使用 kubectl describe pvc 查看 PVC 绑定的 PV 名称和状态

官方文档