使用 NFS 配置持久存储
Alauda Container Platform 集群支持使用 NFS 的持久存储。Persistent Volumes(PVs)和 Persistent Volume Claims(PVCs)为项目内存储卷的配置和使用提供了抽象层。虽然可以将 NFS 配置细节直接嵌入 Pod 定义中,但这种方式不会将卷创建为独立的、隔离的集群资源,增加了冲突的风险。
目录
前提条件
- 底层基础设施中必须存在存储,才能在 Alauda Container Platform 中挂载为卷。
- 要配置 NFS 卷,只需提供 NFS 服务器列表和导出路径。
操作步骤
创建 PV 的对象定义
- 卷的名称。
- 存储容量。
- 虽然看似用于控制对卷的访问,实际上它类似于标签,用于匹配 PVC 和 PV。目前,基于 accessModes 不会强制执行访问规则。
- 使用的卷类型,此处为 nfs 插件。
- NFS 服务器地址。
- NFS 导出路径。
- PVC 删除后卷的处理策略(Retain、Delete、Recycle)。
验证 PV 是否创建成功
创建引用该 PV 的 PVC
- 访问模式不用于安全控制,而是作为标签匹配 PV 和 PVC。
- 该声明请求容量为 1Gi 或更大容量的 PV。
- 要使用的 PV 名称。
验证持久卷声明是否创建成功
通过分区导出实现磁盘配额
要强制执行磁盘配额和大小限制,可以利用磁盘分区。将每个分区作为专用导出点,每个导出对应一个独立的 PersistentVolume(PV)。
虽然 Alauda Container Platform 要求 PV 名称唯一,但管理员需确保每个导出的 NFS 卷的服务器地址和路径唯一。
这种分区方式实现了精确的容量管理。开发者请求指定容量(例如 10Gi)的持久存储,ACP 会匹配容量至少满足该请求的分区/导出对应的 PV。请注意:配额限制作用于分配分区/导出内的可用存储空间。
NFS 卷安全性
本节介绍 NFS 卷的安全机制,重点是权限匹配。假设读者具备 POSIX 权限、进程 UID 和附加组的基础知识。
开发者通过以下方式请求 NFS 存储:
- 通过名称引用 PersistentVolumeClaim(PVC),或
- 在 Pod 规范的 volumes 部分直接配置 NFS 卷插件。
在 NFS 服务器上,/etc/exports 文件定义了可访问目录的导出规则。每个导出目录保留其原生的 POSIX 所有者/组 ID。
Alauda Container Platform 的 NFS 插件关键行为:
- 挂载卷到容器时,保留源目录的精确 POSIX 所有权和权限
- 运行容器时不强制进程 UID 与挂载所有权匹配——这是有意的安全设计
例如,考虑一个 NFS 目录的服务器端属性:
此时,容器必须以 UID 65534(nfsnobody 所有者)运行,或在其附加组中包含 5555,才能访问该目录。
注意
65534 所有者 ID 仅为示例。虽然 NFS 的 root_squash 会将 root(uid 0)映射为 nfsnobody(uid 65534),但 NFS 导出可以拥有任意所有者 ID。NFS 导出不强制必须是所有者 65534。
组 ID
推荐的 NFS 访问管理(当导出权限固定时)
当无法修改 NFS 导出权限时,推荐通过附加组管理访问。
在 Alauda Container Platform 中,附加组是控制共享文件存储(如 NFS)访问的常用机制。
与块存储对比:块存储卷(如 iSCSI)的访问通常通过在 Pod 的 securityContext 中设置 fsGroup 来管理,该方法依赖挂载时更改文件系统组所有权。
通常建议使用附加组 ID 而非用户 ID 来获得持久存储访问权限。
由于示例目标 NFS 目录的组 ID 是 5555,Pod 可以在其 securityContext 的 supplementalGroups 中定义该组 ID。例如:
- securityContext 必须定义在 Pod 级别,而非某个具体容器下。
- 这是为 Pod 定义的 GID 数组,此处仅包含一个元素,多个 GID 用逗号分隔。
用户 ID
用户 ID 可在容器镜像中定义,也可在 Pod 定义中指定。
通常建议使用附加组 ID 来获得持久存储访问权限,而非使用用户 ID。
以上示例目标 NFS 目录中,容器需要将 UID 设置为 65534(暂不考虑组 ID),可在 Pod 定义中添加:
- Pod 包含针对每个容器的 securityContext 定义,以及适用于所有容器的 Pod 级 securityContext。
- 65534 是 nfsnobody 用户。
导出设置
为使任意容器用户能读写卷,NFS 服务器上的每个导出卷应满足以下条件:
-
每个导出必须使用如下格式导出:
-
防火墙必须配置允许访问挂载点的流量。
- 对于 NFSv4,配置默认端口 2049(nfs)。
- 对于 NFSv3,需要配置三个端口:2049(nfs)、20048(mountd)和 111(portmapper)。
- 对于 NFSv4,配置默认端口 2049(nfs)。
-
NFS 导出和目录必须设置为目标 Pod 可访问。要么将导出所有权设置为容器的主 UID,要么通过 supplementalGroups 为 Pod 提供组访问权限,如上文组 ID 所示。
资源回收
NFS 实现了 Alauda Container Platform 的 Recyclable 插件接口。基于每个持久卷设置的策略,自动流程处理资源回收任务。
默认情况下,PV 的回收策略为 Retain。
当 PVC 的声明被删除且 PV 被释放后,该 PV 对象不应被重用。应创建一个新的 PV,使用与原 PV 相同的基本卷信息。
例如,管理员创建了名为 nfs1 的 PV:
用户创建 PVC1,绑定到 nfs1。用户删除 PVC1,释放对 nfs1 的声明,导致 nfs1 状态变为 Released。如果管理员想继续使用相同的 NFS 共享,应创建一个新的 PV,使用相同的 NFS 服务器信息,但 PV 名称不同:
不建议删除原 PV 并用相同名称重新创建。尝试手动将 PV 状态从 Released 改为 Available 会导致错误和潜在数据丢失。