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


82

我正在使用kops在AWS上运行Kubernetes集群。我已经将EBS卷安装到了容器上,并且可以从我的应用程序中看到它,但是由于我的应用程序没有以root用户身份运行,因此它是只读的。我如何PersistentVolumeClaim以root以外的用户身份挂载a ?在VolumeMount似乎不具有任何选项来控制的用户,组或文件权限安装路径。

这是我的Deployment 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

Answers:


58

Pod Security Context支持设置fsGroup,允许您设置拥有该卷的组ID,从而确定谁可以写入该卷。文档中的示例:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
  # specification of the pod's containers
  # ...
  securityContext:
    fsGroup: 1234

更多信息在这里


2
还要注意的volumes.*.defaultMode领域设置安全位- v1-7.docs.kubernetes.io/docs/concepts/configuration/secret/...
文森特·迪斯

嗨,在软件需要时,您不需要在某些文件上设置readOnly权限的情况下使用cas。我正在努力解决该问题,试图避免创建允许的PSP,并希望保留RunAsUser:MustRunAsNonRoot,因为这将适用于Pod中的所有容器。我正在考虑使用特定于sudoers的规则创建自定义映像,以对非root用户执行smod的chmod / chown,我将其称为initContainer image。欢迎任何下注者/工作思路。
tisc0

很棒的答案!TY!
杰森·休斯

45

最后,我以与主容器initContainer相同的方式volumeMount为我的自定义Grafana图像设置了适当的权限。

当Pod中的容器以除用户之外的其他用户身份运行root并且需要对已安装卷的写许可权时,这是必需的。

initContainers:
- name: take-data-dir-ownership
  image: alpine:3
  # 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

您不是必须以root用户身份运行initContainer吗?否则,它将如何授予非root用户权限?
奥利弗

@Oliver:在此示例中,initContainer隐式作为root运行。除非已将container.securityContext.runAsUsercontainer.securityContext.runAsNonRoot(或其他)显式设置为其他内容,否则主容器将与映像本身中指定的用户一起运行。裁判
sshow

1
您拯救了我的一天
Sarasa Gunawardhana

当我部署grafana(像你一样)securityContextfsGroup: 472就够了。
Tamas Foldi

18

当您必须以非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
    

runAsUser

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

runAsGroup

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

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

runAsGroup指定时,用户1099和组1099也将拥有所有创建的文件。

fsGroup

指定附加的任何卷的所有者将是组ID 1099的所有者。

在该文件下创建的任何文件都将具有的许可nonrootgroup:nonrootgroup


做上帝的工作!谢谢!fsGroup正是我所需要的!谢谢你,先生!
David Roth

7

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

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


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

1
也添加fsgroup。一旦添加了fsgroup上下文,则只有它还会看到runasgroup上下文来设置文件夹的所有权。您可以将与runasgroup相同的用户添加到fsgroup或将附加用户组添加到fsgroup。
rajdeepbs19

0

要更改文件系统权限,请initcontainer在实际容器启动之前运行

弹性搜寻广告连播的范例

initContainers:
      - command:
        - sh
        - -c
        - chown -R 1000:1000 /usr/share/elasticsearch/data
        - sysctl -w vm.max_map_count=262144
        - chgrp 1000 /usr/share/elasticsearch/data
        image: busybox:1.29.2
        imagePullPolicy: IfNotPresent
        name: set-dir-owner
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:                         #Volume mount path
        - mountPath: /usr/share/elasticsearch/data
          name: elasticsearch-data

更改容器中的用户组

spec:
      containers:
      securityContext:
          privileged: true
          runAsUser: 1000

嗨,Harsh,您使用了两次“特权”指令,这在这里是无用的,并且绝对是[安全]做法。
tisc0

@ tisc0抱歉,但是更新后的答案无需在init容器中使用。
Harsh Manvar

1
@ tisc0非常感谢您指出并纠正我,希望它也对其他人有所帮助。
Harsh Manvar

1
别客气。但是,在第二部分代码中,“更改容器中的用户组”,您仍在使用特权,并且看不到runAsGroup或fsGroup之类的内容。(不想打扰,只是吹毛求疵)。
tisc0

0

请参阅问题:https : //github.com/kubernetes/kubernetes/issues/2630

如果它是Emptydir,则规范级别的securityContext可以帮助您:

spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 1000
containers: ...

如果该卷是主机路径,则建议使用initContainer来添加卷路径:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.