为什么无法将非 root 用户访问权添加到持久存储器?
经典基础结构
在 为持久存储添加非根用户访问权限 或部署指定了非根用户 ID 的Helm图表后,用户无法写入挂载的存储。
应用程序部署或Helm图表配置为 pod 的“fsGroup
(组 ID)和”runAsUser
(用户 ID)指定了 安全上下文。 通常,pod 的缺省安全上下文会设置 runAsNonRoot
,以便 pod 无法以 root 用户身份运行。 由于 fsGroup
设置不是针对共享存储器 (例如 NFS 文件存储器) 设计的,因此 fsGroup
设置不受支持,并且 runAsUser
设置会自动设置为 2020
。 这些缺省设置不允许其他非 root
用户写入已安装的存储器。
要允许非 root 用户对文件存储设备进行读写访问,必须在存储类中分配 补充组标识,在 PVC 中引用此存储类,并使用自动添加到补充组标识的 runAsUser
值来设置 pod 的安全上下文。 当您授予对文件存储器的补充组标识读写访问权时,将授予属于组标识
(包括 pod) 的任何非 root 用户对文件存储器的访问权。
您可以使用其中一个提供的 gid
存储类 或创建自己的存储类来定义自己的补充组标识。
仅单专区集群支持为文件存储设备的非 root 用户分配补充组标识,并且不能在多专区集群中使用。
-
选择其中一个 提供的
gid
存储类,以将缺省组标识65531
分配给要读写文件存储器的非 root 用户。 如果要分配定制组标识,请为定制存储类创建 YAML 文件。 在定制存储类 YAML 文件中,包含gidAllocate: "true"
参数,并在gidFixed
参数中定义组标识。用于分配缺省组标识
65531
的示例存储类。ibmc-file-bronze-gid
ibmc-file-silver-gid
ibmc-file-gold-gid
用于指定其他组标识的定制存储类示例。
apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: ibmc-file-bronze-gid-custom labels: kubernetes.io/cluster-service: "true" provisioner: ibm.io/ibmc-file parameters: type: "Endurance" iopsPerGB: "2" sizeRange: "[1-12000]Gi" mountOptions: nfsvers=4.1,hard billingType: "hourly" reclaimPolicy: "Delete" classVersion: "2" gidAllocate: "true" gidFixed: "65165"
要在集群中创建存储类,请运行
kubectl apply -f storageclass.yaml
。 -
为使用您创建的存储类的 PVC 创建 YAML 文件。
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: gid-pvc labels: billingType: "monthly" spec: accessModes: - ReadWriteMany resources: requests: storage: 20Gi storageClassName: ibmc-file-bronze-gid
-
在集群中创建 PVC。
kubectl apply -f pvc.yaml
-
等待几分钟,以便供应文件存储器和 PVC 更改为
Bound
状态。 请注意,如果在多专区集群中创建了 PVC,那么 PVC 仍处于pending
状态。kubectl get pvc
示例输出
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE gid-pvc Bound pvc-5e4acab4-9b6f-4278-b53c-22e1d3ffa123 20Gi RWX ibmc-file-bronze-gid 2m54s
-
为安装您创建的 PVC 的部署创建 YAML 文件。 在
spec.template.spec.securityContext.runAsUser
字段中,指定要使用的非 root 用户标识。 此用户标识将自动添加到存储类中定义的补充组标识,以获取对文件存储器的读写访问权。创建
node-hello
部署的示例。apiVersion: apps/v1 kind: Deployment metadata: name: gid-deployment labels: app: gid spec: selector: matchLabels: app: gid template: metadata: labels: app: gid spec: containers: - image: gcr.io/google-samples/node-hello:1.0 name: gid-container volumeMounts: - name: gid-vol mountPath: /myvol securityContext: runAsUser: 2020 volumes: - name: gid-vol persistentVolumeClaim: claimName: gid-pvc
-
在集群中创建部署。
kubectl apply -f deployment.yaml
-
确认 pod 处于运行状态。
kubectl get pods
示例输出
NAME READY STATUS RESTARTS AGE gid-deployment-5dc86db4c4-5hbts 2/2 Running 0 69s
-
登录到 pod。
kubectl exec <pod_name> -it -- bash
验证非 root 用户的读和写许可权
-
列出 pod 中当前用户的用户标识和组标识。 如果非 root 用户标识列示为
uid
,并且在存储类中定义的补充组标识列示在groups
下,那么设置正确。id
示例输出
uid=2020 gid=0(root) groups=0(root), 65531
-
列出您在部署中定义的卷安装目录的许可权。 如果您在存储类中定义的补充组标识在卷安装目录中以读写许可权列出,那么设置正确。
ls -l /<volume_mount_path>
示例输出
drwxrwxr-x 2 nobody 65531 4096 Dec 11 07:40 . drwxr-xr-x 1 root root 4096 Dec 11 07:30 ..
-
在挂载目录中创建一个文件。
echo "Able to write to file storage with my non-root user." > /myvol/gidtest.txt
-
列出卷安装目录中文件的许可权。
ls -al /mnt/nfsvol/
示例输出
drwxrwxr-x 2 nobody 65531 4096 Dec 11 07:40 . drwxr-xr-x 1 root root 4096 Dec 11 07:30 .. -rw-r--r-- 1 2020 4294967294 42 Dec 11 07:40 gidtest.txt .
在 CLI 输出中,将列出对您创建的文件具有读和写访问权的非 root 用户标识。
-
退出 pod。
exit
如果需要从 nobody
更改安装路径的所有权,请参阅 当非 root 用户拥有 NFS 文件存储器安装路径时应用程序失败。