如何允许非root用户写入EKS中已安装的EFS

问题描述 投票:0回答:2

我在配置静态配置的 EFS 时遇到问题,以便以非 root 用户身份运行的多个 pod 可以读取和写入文件系统。

我正在使用 AWS EFS CSI 驱动程序。我的版本信息如下:

Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.18", GitCommit:"6f6ce59dc8fefde25a3ba0ef0047f4ec6662ef24", GitTreeState:"clean", BuildDate:"2021-04-15T03:31:30Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.9-eks-d1db3c", GitCommit:"d1db3c46e55f95d6a7d3e5578689371318f95ff9", GitTreeState:"clean", BuildDate:"2020-10-20T22:53:22Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}

我按照 github 存储库 (https://github.com/kubernetes-sigs/aws-efs-csi-driver/tree/master/examples/kubernetes/multiple_pods) 中的示例适当更新了volumeHandle。该示例规范中定义的 busybox 容器能够读取和写入文件系统,但是当我将相同的 PVC 添加到不以 root 用户身份运行的 pod 时,该 pod 无法写入已安装的 EFS。 我尝试了其他一些方法来使其按我的预期工作:

这些配置都不允许非 root 用户写入已安装的 EFS。 在配置静态配置的 EFS 以便所有以非 root 用户身份运行的多个 pod 都可以在已安装的 EFS 中读取和写入方面,我缺少什么?

以下是 pod 定义供参考:

apiVersion: v1
kind: Pod
metadata:
  name: app1
spec:
  containers:
  - name: app1
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out1.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim
---
apiVersion: v1
kind: Pod
metadata:
  name: app2
spec:
  containers:
  - name: app2
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out2.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim
---
apiVersion: v1
kind: Pod
metadata:
  name: app3
spec:
  containers:
  - name: app3
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out3.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  securityContext:
    runAsUser: 1000
    runAsGroup: 1337
    fsGroup: 1337
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim

还有 SC/PVC/PV:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi  
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-pv
  annotations:
    pv.beta.kubernetes.io/gid: {{ .Values.groupId | quote }}
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: efs-sc
  csi:
    driver: efs.csi.aws.com
    volumeHandle: fs-asdf123
kubernetes kubernetes-helm amazon-eks amazon-efs
2个回答
1
投票

我想出了两种解决此问题的方法,并认为我应该更新此方法,以防其他人遇到同样的问题。

第一种可能更好的方法是仅使用动态配置的 EFSPersistentVolume。这种方式会在 EFS 中创建一个访问点,该访问点由使用 PersistentVolumeClaim 的所有容器共享。

这是 StorageClass、PersistentVolumeClaim 和使用 PVC 的 pod 的示例。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap
  fileSystemId:  {{ .Values.efsVolumeHandle }}
  directoryPerms: "775"
reclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi  # Not actually used - see https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/
---
apiVersion: v1
kind: Pod
metadata:
  name: app3
spec:
  containers:
  - name: app3
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out3.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  securityContext:
    runAsUser: 1000
    runAsGroup: 1337
    fsGroup: 1337
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim

注意 StorageClass 中指定的

directoryPerms
(775),以及 Pod 中指定的
runAsGroup
fsGroup
。当在以非 root 用户身份运行的 Pod 中使用此 PVC 时,共享用户组编号是关键。

指定

runAsUser
只是为了确保
busybox
内容不会以 root 身份运行


第二种方法是我最初研究出来的,可能是“核”选项,但确实适用于静态配置的 EFS。

为了简洁起见,我省略了 pod 定义的其余部分。您可以使用

initContainer
确保在已安装的 EFS 卷上设置某些权限。

      initContainers:
      - name: fs-permission-update
        image: busybox
        command:
        - chown
        - "root:{{ .Values.groupId }}"
        - "/efs-fs"
        volumeMounts:
        - mountPath: /efs-fs
          name: efs-storage

再次确保挂载该卷并以非 root 用户身份运行的任何 Pod 使用

fsGroup
runAsGroup
来确保该用户属于允许的用户组。


总而言之,可能不要使用静态配置的 EFS,而是使用动态配置的 EFS。请注意,这是特定于 Kubernetes 的 EFS CSI 驱动程序的。查看 EKS CSI 驱动程序 GitHub 了解更多示例和一些其他详细信息。


0
投票

Arctor,我现在正在努力解决这个问题,唯一的不同是我正在使用 WordPress 的 bitnami 图表,这不应该改变主要问题,但它对我不起作用。我仍然收到权限错误,但我已按照您的所有指示进行操作。

- name: efs-sc
  parameters:
    basePath: /dynamic_provisioning
    directoryPerms: "775"
    fileSystemId: fs-03e624c219db1ad90
    provisioningMode: efs-ap

并为我的 pod 提供相同的配置。

podSecurityContext:
  enabled: true
  runAsUser: 1000
  runAsGroup: 1337
  fsGroup: 1337
  seccompProfile:
    type: "RuntimeDefault"

但仍然没有运气,我在这里缺少什么吗?

提前致谢。

© www.soinside.com 2019 - 2024. All rights reserved.