微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我在配置静态配置的 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",BuildDate:"2020-10-20T22:53:22Z",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 以便多个 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

解决方法

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

第一种可能更好的方法是使用 dynamically provisioned EFS PersistentVolume。这种方式在 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 中指定的 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 以获取更多示例和一些其他详细信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。