使用 NFS 配置持久存储
Alauda Container Platform 集群支持使用 NFS 的持久存储。Persistent Volumes (PVs) 和 Persistent Volume Claims (PVCs) 为项目内存储卷的配置和使用提供了抽象层。虽然可以直接在 Pod 定义中嵌入 NFS 配置细节,但这种方式不会将卷创建为独立的、隔离的集群资源,增加了冲突的风险。
前提条件
- 底层基础设施中必须先存在存储,才能在 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 会导致错误和潜在数据丢失。