LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

把存储的三层编在一起

在 LabHub 中继续学习

目标

亲手创建 StorageClass、PV、PVC 三层对象,掌握绑定条件,并确认 StatefulSet 如何处理卷。

为什么这很重要

PVC 处于 Pending 的原因始终是三者之一:class 名称不匹配、访问模式不匹配,或者容量不足。此外,还有因 provisioner 不存在而无法动态创建的情况。本实验环境没有真正的 CSI 驱动,因此会通过静态绑定逐一确认这些条件。虽然无法写入真实数据,但考试大多数题目检查的也正是对象 spec 和绑定状态。

提前了解 allowVolumeExpansion 这类事后修改也无效的字段,同样很重要。由值为 false 的 class 创建的 PVC,即使后来修改 class,也无法扩容。

步骤

  1. 创建 namespace cka-storage 和 StorageClass cka-fast。provisioner 为 nfs.csi.k8s.io,reclaimPolicy 为 Delete,volumeBindingMode 为 WaitForFirstConsumer,allowVolumeExpansion 为 true
  2. 创建 StorageClass cka-archive。provisioner 为 nfs.csi.k8s.io,reclaimPolicy 为 Retain,volumeBindingMode 为 Immediate。然后为 cka-fast 添加注解 storageclass.kubernetes.io/is-default-class: "true",将其设为默认 class。默认 class 必须恰好只有一个。
  3. 创建 PersistentVolume cka-pv-1。capacity 为 2Gi,accessModes 为 [ReadWriteOnce],persistentVolumeReclaimPolicy 为 Retain,storageClassName 为 cka-manual,卷源为 hostPath /mnt/cka-data
  4. cka-storage 中创建 PVC cka-pvc-1。请求 1Gi,accessModes 为 [ReadWriteOnce],storageClassName 为 cka-manual。它应与 cka-pv-1 绑定为 Bound。
  5. 创建 PersistentVolume cka-pv-rwx。capacity 为 5Gi,accessModes 为 [ReadWriteMany],storageClassName 为 cka-shared,卷源为 NFS(server 10.0.0.109,path /volume1/k8s)。然后创建 PVC cka-pvc-rwx(5Gi、RWX、cka-shared)并使其绑定为 Bound。
  6. 创建 headless Service db-headless(clusterIP None、port 5432、selector app=db)和 StatefulSet db。serviceName 为 db-headless,副本数为 2,镜像为 nginx:1.27,podManagementPolicy 为 Parallel;volumeClaimTemplates 名称为 data(accessModes [ReadWriteOnce]、storageClassName cka-fast、1Gi);persistentVolumeClaimRetentionPolicy 设置 whenDeleted Delete / whenScaled Retain。应自动创建 PVC data-db-0data-db-1
  7. cka-storage 中创建 Pod vol-demo(镜像 nginx:1.27)。卷 cache 使用 emptyDir,medium 为 Memory,sizeLimit 为 128Mi,挂载到 /cache。卷 hostlogs 使用 hostPath path /var/log,type 为 Directory,以 readOnly 方式挂载到 /hostlogs
  8. 创建 PersistentVolume cka-pv-static(capacity 1Gi、accessModes [ReadWriteOnce]、完全不设置 storageClassName、hostPath /mnt/cka-static),再创建 PVC cka-pvc-static(1Gi、RWO),明确将 storageClassName 设为空字符串,并使其绑定为 Bound。

参考

创建 StorageClass

创建 namespace cka-storage 和 StorageClass cka-fast。provisioner 为 nfs.csi.k8s.io,reclaimPolicy 为 Delete,volumeBindingMode 为 WaitForFirstConsumer,allowVolumeExpansion 为 true

provisioner 是字符串,即使驱动实际上不存在,也可以创建对象。reclaimPolicy、volumeBindingMode、allowVolumeExpansion 是 StorageClass 的顶层字段,不在 parameters 中。

创建第二个 class 并指定默认 class

创建 StorageClass cka-archive。provisioner 为 nfs.csi.k8s.io,reclaimPolicy 为 Retain,volumeBindingMode 为 Immediate。然后为 cka-fast 添加注解 storageclass.kubernetes.io/is-default-class: "true",将其设为默认 class。默认 class 必须恰好只有一个。

默认 class 通过注解指定。如果默认 class 超过一个,就无法预测会使用哪一个,因此必须恰好只有一个。

手动创建 PersistentVolume

创建 PersistentVolume cka-pv-1。capacity 为 2Gi,accessModes 为 [ReadWriteOnce],persistentVolumeReclaimPolicy 为 Retain,storageClassName 为 cka-manual,卷源为 hostPath /mnt/cka-data

PV 是集群作用域资源。请注意,它的回收策略字段名称与 StorageClass 不同。

确认静态绑定

cka-storage 中创建 PVC cka-pvc-1。请求 1Gi,accessModes 为 [ReadWriteOnce],storageClassName 为 cka-manual。它应与 cka-pv-1 绑定为 Bound。

绑定条件有三项:class 名称一致、包含所需访问模式、容量满足需求。任何一项不匹配,PVC 都会悄无声息地保持 Pending。

创建 RWX 卷

创建 PersistentVolume cka-pv-rwx。capacity 为 5Gi,accessModes 为 [ReadWriteMany],storageClassName 为 cka-shared,卷源为 NFS(server 10.0.0.109,path /volume1/k8s)。然后创建 PVC cka-pvc-rwx(5Gi、RWX、cka-shared)并使其绑定为 Bound。

PV 与 PVC 的 accessModes 必须匹配才能绑定。NFS 卷源要求 server 和 path 两个字段。

通过 volumeClaimTemplates 自动创建 PVC

创建 headless Service db-headless(clusterIP None、port 5432、selector app=db)和 StatefulSet db。serviceName 为 db-headless,副本数为 2,镜像为 nginx:1.27,podManagementPolicy 为 Parallel;volumeClaimTemplates 名称为 data(accessModes [ReadWriteOnce]、storageClassName cka-fast、1Gi);persistentVolumeClaimRetentionPolicy 设置 whenDeleted Delete / whenScaled Retain。应自动创建 PVC data-db-0data-db-1

PVC 名称由模板名称与 Pod 名称组合而成。需要改变默认行为,避免第一个 Pod 未 Ready 时阻止创建后续 Pod。

挂载 emptyDir 与 hostPath

cka-storage 中创建 Pod vol-demo(镜像 nginx:1.27)。卷 cache 使用 emptyDir,medium 为 Memory,sizeLimit 为 128Mi,挂载到 /cache。卷 hostlogs 使用 hostPath path /var/log,type 为 Directory,以 readOnly 方式挂载到 /hostlogs

卷定义位于 spec.volumes,挂载位于容器的 volumeMounts。内存型 emptyDir 通过 medium 字段指定。

综合:拒绝使用默认 StorageClass

创建 PersistentVolume cka-pv-static(capacity 1Gi、accessModes [ReadWriteOnce]、完全不设置 storageClassName、hostPath /mnt/cka-static),再创建 PVC cka-pvc-static(1Gi、RWO),明确将 storageClassName 设为空字符串,并使其绑定为 Bound。

省略字段与明确设置为空字符串并不相同。前者会注入默认值,后者表示拒绝使用默认值。