4.11.3. NFS 卷安全

这部分论述了 NFS 卷安全性,其中包括匹配的权限和 SELinux 考虑。用户需要了解 POSIX 权限、进程 UID 、supplemental 组和 SELinux 的基本知识。

软件开发人员可以使用 PVC 名称,或直接在 Pod 定义中 volumes 部分使用 NFS 插件来请求 NFS 存储。

NFS 服务器中的 /etc/exports 文件包含可访问的 NFS 目录。目标 NFS 目录有 POSIX 拥有者和组群 ID。OpenShift Container Platform NFS 插件使用相同的 POSIX 所有者权限及在导出的 NFS 目录中找到的权限挂载容器的 NFS 目录。然而,容器实际运行时所使用的 UID 与 NFS 挂载的所有者的 UID 不同。这是所需的行为。

例如,目标 NFS 目录在 NFS 服务器中,如下所示:

$ ls -lZ /opt/nfs -d

输出示例

drwxrws---. nfsnobody 5555 unconfined_u:object_r:usr_t:s0   /opt/nfs

$ id nfsnobody

输出示例

uid=65534(nfsnobody) gid=65534(nfsnobody) groups=65534(nfsnobody)

为了可以访问目录,容器必须匹配 SELinux 标签,并使用 UID65534nfsnobody的所有者,或其 supplemental 组的 5555 运行。

注意

所有者 ID 65534 只是一个示例。虽然 NFS 的 root_squashroot,uid 0 映射到 nfsnobody,uid 65534,但 NFS 导出的所有者 ID 可能是任意值。NFS 导出的所有者不需要是 65534

4.11.3.1. 组 ID

用来控制 NFS 访问(假设不能在 NFS 导出中修改权限)的建议方法是使用附加组(supplemental group)。OpenShift Container Platform 中的附件组的功能是用于共享存储(NFS 是一个共享存储)。相对块存储(如 iSCSI),使用 fsGroup SCC 策略和在 Pod 的 securityContext 中的fsGroup 值。

注意

在访问持久性存储时,一般情况下最好使用 supplemental 组 ID 而不是使用用户 ID。

因为示例目标 NFS 目录上的组 ID 是 5555,Pod 可以使用 Pod 的 securityContext 定义中的 supplementalGroups 来设置组 ID。例如:

spec:
  containers:
    - name:
    ...
  securityContext: 1
    supplementalGroups: [5555] 2
1
securityContext 必须在 pod 一级定义,而不是在某个特定容器中定义。
2
为 pod 定义的 GID 数组。在这种情况下,是阵列中的一个元素。使用逗号将不同 GID 分开。

假设没有可能满足 pod 要求的自定义 SCC,pod 可能与受限 SCC 匹配。这个 SCC 把 supplementalGroups 策略设置为 RunAsAny。这代表提供的任何组群 ID 都被接受,且不进行范围检查。

因此,上面的 pod 可以通过,并被启动。但是,如果需要进行组 ID 范围检查,使用自定义 SCC 就是首选的解决方案。可创建一个定义了最小和最大组群 ID 的自定义 SCC,这样就会强制进行组 ID 范围检查,组 ID 5555 将被允许 。

注意

要使用自定义 SCC,需要首先将其添加到适当的服务帐户(service account)中。例如,在一个特定项目中使用 default 服务账户(除非在 Pod 规格中指定了另外一个账户)。