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

carvr3hs  于 2023-08-03  发布在  Kubernetes
关注(0)|答案(1)|浏览(98)

我在配置一个静态配置的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 repo(https://github.com/kubernetes-sigs/aws-efs-csi-driver/tree/master/examples/kubernetes/multiple_pods)中的示例适当地更新了volumeHandle。示例规范中定义的busybox容器能够读写文件系统,但是当我将相同的PVC添加到不以root用户身份运行的pod时,pod无法写入已装载的EFS。我已经尝试了一些其他的事情来让它像我期望的那样工作:

  • 只是应用这里描述的注解:https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#access-control添加到永久卷定义中。
  • 应用前面提到的注解,并将securityContext.runAsGroup包含到pod定义中(使用适当的值)
  • 为Pod应用注解、runAsGroup和fsGroup

这些配置都不允许非root用户写入装载的EFS。在配置静态配置的EFS时,我遗漏了什么,以便多个Pod(所有Pod都以非root用户身份运行)可以在装载的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

utugiqy6

utugiqy61#

我想出了两种解决这个问题的方法,并认为我应该更新这个,以防其他人遇到同样的问题。
第一种可能更好的方法是只使用dynamically provisioned EFS持久性卷。这种方式会在EFS中创建一个访问点,该访问点由使用PersistentVolumeClaim的所有容器共享。
下面是存储类、PersistentVolumeClaim和一个使用PVC的单元的示例。

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

字符串
请注意在存储类中指定的directoryPerms(775),以及在Pod中指定的runAsGroupfsGroup。在作为非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使用fsGrouprunAsGroup,以确保该用户是允许的用户组的一部分。
总之,可能不要使用静态配置的EFS,而应使用动态配置的EFS。请注意,这特定于Kubernetes的EFS CSI驱动程序。请查看EKS CSI Driver GitHub以了解更多示例和其他详细信息。

相关问题