LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

卷是分成三层的

在 LabHub 中继续学习

一句话总结

Kubernetes 存储分为 **StorageClass(蓝图)→ PersistentVolume(实物)→ PersistentVolumeClaim(需求单)**三层。它们分别代表不同角色的关注点,因此被拆开;只要不匹配,PVC 就会悄无声息地保持 Pending。

存储的三层——PVC 是开发者填写的需求单,PV 是实物,StorageClass 是管理员编写的蓝图。StorageClass 创建 PV,PV 与 PVC 绑定;storageClassName 必须相同,accessModes 必须包含所需模式,容量必须不小于请求。任一条件不符都会无错误地 Pending

概念图: 不想使用该类,不能省略 storageClassName,而要明确写为空字符串 · 案例 1——先确认 mount。 · 先确认能否从 Pod mount NFS · 案例 2——按用途拆分类别。

为什么需要它

开发者想要“一块 1Gi、可供多个节点同时使用的磁盘”。管理员决定“在 NAS 的 /volume1/k8s 下使用 NFS v4.1、hard mount、nconnect 4”。若把两种关注点混进同一对象,开发者就必须了解存储厂商。

所以 PVC 只写需求,StorageClass 定义把需求变成实物的方法,PV 代表实物。binding 条件很简单:storageClassName 相同,PV 的 accessModes 包含 PVC 的要求,并且 PV 容量不小于 PVC 请求,即可绑定。任一条件不符都会无错误地 Pending。

CSI 的出现也源于相同的解耦需求。过去存储插件位于 Kubernetes 核心代码内部(in-tree),添加新存储必须修改 Kubernetes 本身。CSI 解除了这种耦合,driver 分为 controller(Deployment,负责 volume 创建、删除、扩展、snapshot)和 node plugin(DaemonSet,负责 mount/unmount)。node plugin 使用 DaemonSet,是因为所有可能调度 Pod 的节点都必须具备它。

它如何运作

StorageClass 中有三个一旦写错就很难挽回的字段。

字段 含义 写错后果
reclaimPolicy PVC 删除后 PV 的命运 设为 Delete 会连数据一起消失
volumeBindingMode 何时创建 volume Immediate 可能让 volume 与 Pod 出现在不同 zone
allowVolumeExpansion 日后是否可以扩容 使用 false 类别的 PVC 永远无法扩容

WaitForFirstConsumer 会在得知 Pod 将调度到哪个节点后再创建 volume,是多 zone 环境的必需设置。

访问模式有四种:RWO(单节点读写)、ROX(多节点只读)、RWX(多节点读写)、RWOP(单 Pod 专用)。block storage 通常只支持到 RWO,RWX 属于 NFS 等 file storage 的领域。

在设有默认 StorageClass 的集群中,如果不想使用该类,不能省略 storageClassName,而要明确写为空字符串。省略时会注入默认值。这一区别也会出现在考试中。

在实际工作中会遇到的情况

案例 1——先确认 mount。家庭实验室运行 kubectl get sc 时得到 No resources found。没有 StorageClass,PVC 会永远 Pending,任何有状态 workload 都无法部署。决定接入家中的 Synology NAS 后,没有先装 driver,而是先确认能否从 Pod mount NFS。第一次失败了。

mount.nfs: Operation not permitted for 10.0.0.109:/volume1/k8s on /mnt/t

即使设置 privileged: true 仍被拒绝,缺少的是 hostNetwork: true。NFS mount 会与 rpcbind 通信,并使用低于 1024 的 reserved port 作为 source port,在 Pod network namespace 内这种行为会受限。**privileged 提供 capability,却无法解决 network namespace 问题。**因为遵循了顺序,所以很快确认原因不在 driver。

**案例 2——按用途拆分类别。**安装 csi-driver-nfs 4.13.4 后创建了两套 StorageClass。

选择 hard 的原因尤其重要。soft 会在 timeout 时向应用返回 I/O error,数据库写入途中收到错误,可能造成无声的数据损坏。hard 会无限重试直至 server 恢复,数据更安全;代价是 NAS 故障时 Pod 看似无错误地停住,难以判断原因。所有存储设置都有这种取舍。

subDir pattern 也设为 네임스페이스-PVC이름-PV이름。只使用 PV 名称,NAS file explorer 中只会看到 pvc-da6bb53d-... 这样的 UUID,日后无法判断哪些可以删除。

案例 3——容量不会被强制执行。PVC 请求 2Gi,但 NFS 没有强制它的手段。Pod 使用 100GB 也不会被阻止。PVC 容量只是用于 scheduling 和 accounting 的 metadata,真正限制必须由 backend 实现。block storage 的 volume size 本身就是物理限制,自然可以强制;NFS 子目录则不是。

还亲眼看到了 archive 策略的代价。打开 NFS export root 后,发现旧集群留下了 32 个目录,Prometheus 和 OpenSearch 数据仍在,19.9T 中已使用 9.4T。它虽然安全,但如果无人清理就会不断堆积。

后续实验要做什么

创建两套 StorageClass 并确认三个字段的差异,静态绑定 PV 与 PVC,创建 RWX volume,并观察 StatefulSet 的 volumeClaimTemplates 自动创建 PVC。最后一步是明确拒绝默认 StorageClass。