Kubernetes:如何设置VolumeMount用户组和文件权限

Mik*_*ski 31 amazon-web-services docker kubernetes persistent-volume-claims

我正在使用kops在AWS上运行Kubernetes集群.我已经将一个EBS卷安装到一个容器上,它可以从我的应用程序中看到,但它是只读的,因为我的应用程序不是以root身份运行的.如何PersistentVolumeClaim以root用户身份登录?在VolumeMount似乎不具有任何选项来控制所安装的路径的用户,组或文件权限.

这是我的部署yaml文件:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: notebook-1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: notebook-1
    spec:
      volumes:
      - name: notebook-1
        persistentVolumeClaim:
          claimName: notebook-1
      containers:
      - name: notebook-1
        image: jupyter/base-notebook
        ports:
        - containerPort: 8888
        volumeMounts:
        - mountPath: "/home/jovyan/work"
          name: notebook-1
Run Code Online (Sandbox Code Playgroud)

Ale*_*and 28

Pod安全上下文支持设置a fsGroup,允许您设置拥有卷的组ID,从而设置可以写入的组ID.文档中的示例:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
  # specification of the pod's containers
  # ...
  securityContext:
    fsGroup: 1234
Run Code Online (Sandbox Code Playgroud)

更多信息请访问:https://kubernetes.io/docs/concepts/policy/security-context/

  • “securityContext”是执行此操作的有效方法,但是当它需要为“spec”时,您可以将其放在“spec.container”中。注意:“spec.container”中有一个“securityContext”,但这与规范级别的不同。`fsGroup` 在容器级别 `securityContext` 不可用。 (18认同)
  • 还要注意设置安全位的 `volumes.*.defaultMode` 字段 - https://v1-7.docs.kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a -荚 (2认同)
  • 您好,不能解决当软件需要时需要对某些文件设置只读权限的用例。我正在努力解决这个问题,试图避免创建一个宽松的 PSP,愿意保留 RunAsUser: MustRunAsNonRoot,因为这将适用于 Pod 中的所有容器。我正在考虑使用 sudoers 特定规则创建一个自定义映像,以便为非 root 用户使用 sudo 执行 chmod/chown ,我将其称为 initContainer image 。欢迎任何更好/可行的想法。 (2认同)

小智 24

当您必须以非 root 用户身份在容器内运行进程时,这是 Kubernetes Deployments/StatefulSets 面临的挑战之一。但是,当您将卷挂载到 pod 时,它总是在root:root.

因此,非 root 用户必须有权访问要读取和写入数据的文件夹。

请按照以下步骤操作。

  1. 在 Dockerfile 中创建用户组并分配组 ID。
  2. 使用用户 ID 创建用户并添加到 Dockerfile 中的组。
  3. 递归更改用户进程想要读/写的文件夹的所有权。
  4. 在 podspec上下文中的 Deployment/StatefulSet 中添加以下行。

    spec:
      securityContext:
        runAsUser: 1099
        runAsGroup: 1099
        fsGroup: 1099
    
    Run Code Online (Sandbox Code Playgroud)

以用户身份运行

指定对于 Pod 中的任何容器,所有进程都以用户 ID 1099 运行。

运行组

为 Pod 的任何容器内的所有进程指定主组 ID 1099。

如果省略此字段,则容器的主要组 ID 将为root(0)

创建的任何文件也将在runAsGroup指定时归用户 1099 和组 1099 所有。

指定连接的任何卷的所有者将是组 ID 1099 的所有者。

在它下创建的任何文件都将具有nonrootgroup:nonrootgroup.

  • 做上帝的工作!感谢您!fsGroup 正是我所需要的!谢谢你,先生! (2认同)

ssh*_*how 20

我最终使用initContainer与主容器相同的volumeMount来设置适当的权限,在我的情况下,为自定义Grafana图像.

initContainers:
- name: take-data-dir-ownership
  image: alpine:3.6
  # Give `grafana` user (id 472) permissions a mounted volume
  # https://github.com/grafana/grafana-docker/blob/master/Dockerfile
  command:
  - chown
  - -R  
  - 472:472
  - /var/lib/grafana
  volumeMounts:
  - name: data
    mountPath: /var/lib/grafana
Run Code Online (Sandbox Code Playgroud)

当pod中的主映像作为非root用户运行并且需要对已装入卷执行写入权限时,这是必需的.

  • 您不需要以 root 用户身份运行 initContainer 吗?否则它怎么会有权限对非 root 用户进行 chown 呢? (2认同)
  • @Oliver:在此示例中,initContainer 以 root 身份隐式运行。主容器将使用映像本身指定的用户运行,除非已将“container.securityContext.runAsUser”或“container.securityContext.runAsNonRoot”(或其他)显式设置为其他内容。[参考](https://kubernetes.io/docs/reference/ generated/kubernetes-api/v1.15/#securitycontext-v1-core) (2认同)
  • 你救了我的命 (2认同)

小智 8

对于k8s版本1.10+,runAsGroup已添加,它类似于fsGroup但工作方式不同。

可以在此处跟踪实现:https : //github.com/kubernetes/features/issues/213

  • 当您指定`runAsGroup`时,容器将作为该组启动,但卷的所有权不会更改。因此它们是不同的,我都曾使它们的卷可写。 (5认同)

小智 5

请参考这个问题:https ://github.com/kubernetes/kubernetes/issues/2630

如果是emptydir,则可以使用securityContext中的 :spec

spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 1000
containers: ...
Run Code Online (Sandbox Code Playgroud)

如果卷是 a hostpath,则 aninitContainer可用于chown卷中的路径:

initContainers:
    - name: example-c
      image: busybox:latest
      command: ["sh","-c","mkdir -p /vol-path && chown -R 1000:1000 /vol-path"]
      resources:
        limits:
          cpu: "1"
          memory: 1Gi
      volumeMounts:
        - name: vol-example
          mountPath: /vol-path
Run Code Online (Sandbox Code Playgroud)