如何允许非 root 用户写入 EKS 中挂载的 EFS
How to allow a non-root user to write to a mounted EFS in EKS
我在配置静态配置的 EFS 时遇到问题,因此多个 pods 作为非 root 用户可以读写文件系统。
我正在使用 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 添加到一个不是 运行 作为根用户的 pod 时,该 pod 无法写入安装 EFS。
我已经尝试了其他一些方法来使它按照我的预期工作:
- 只需将此处描述的注释应用到持久卷定义中:https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#access-control。
- 应用上述注释并将 securityContext.runAsGroup 包含到 pod 定义(具有适当的值)
- 应用注解,运行AsGroup,以及 Pod 的 fsGroup
None 这些配置允许非 root 用户写入已安装的 EFS。
在配置静态配置的 EFS 方面我缺少什么,以便多个 pods,所有这些 运行 作为非 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 中指定的 runAsGroup
和 fsGroup
。在 运行 作为非根用户共享的 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 用户身份安装卷和 运行s 的任何 Pod 使用 fsGroup
和 runAsGroup
以确保用户是允许的一部分用户组。
总而言之,可能不要使用静态配置的 EFS,而是使用动态配置的 EFS。请注意,这特定于 Kubernetes 的 EFS CSI 驱动程序。查看 EKS CSI Driver GitHub 以获取更多示例和一些其他详细信息。
我在配置静态配置的 EFS 时遇到问题,因此多个 pods 作为非 root 用户可以读写文件系统。
我正在使用 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 添加到一个不是 运行 作为根用户的 pod 时,该 pod 无法写入安装 EFS。 我已经尝试了其他一些方法来使它按照我的预期工作:
- 只需将此处描述的注释应用到持久卷定义中:https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#access-control。
- 应用上述注释并将 securityContext.runAsGroup 包含到 pod 定义(具有适当的值)
- 应用注解,运行AsGroup,以及 Pod 的 fsGroup
None 这些配置允许非 root 用户写入已安装的 EFS。 在配置静态配置的 EFS 方面我缺少什么,以便多个 pods,所有这些 运行 作为非 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 中指定的 runAsGroup
和 fsGroup
。在 运行 作为非根用户共享的 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 用户身份安装卷和 运行s 的任何 Pod 使用 fsGroup
和 runAsGroup
以确保用户是允许的一部分用户组。
总而言之,可能不要使用静态配置的 EFS,而是使用动态配置的 EFS。请注意,这特定于 Kubernetes 的 EFS CSI 驱动程序。查看 EKS CSI Driver GitHub 以获取更多示例和一些其他详细信息。