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

时间:2017-04-21 13:44:19

标签: amazon-web-services docker kubernetes persistent-volume-claims

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

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

7 个答案:

答案 0 :(得分:18)

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

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

有关这方面的更多信息,请访问:https://kubernetes.io/docs/concepts/policy/security-context/

答案 1 :(得分:8)

最后,我得到了一个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

当pod中的主映像以root以外的用户身份运行并且需要对已装载的卷具有写权限时,这是必需的。

答案 2 :(得分:4)

当您必须以非root用户身份在容器内运行进程时,这成为Kubernetes Deployments / StatefulSets的挑战之一。但是,将卷装载到Pod时,总是在root:root的许可下装载该卷。

因此,非root用户必须有权访问要在其中读写数据的文件夹。

请按照以下步骤操作。

  1. 在Dockerfile中创建用户组并分配组ID。
  2. 使用用户ID创建用户并添加到Dockerfile中的组。
  3. 递归地更改用户进程要读取/写入的文件夹的所有权。
  4. 在pod spec上下文中的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的许可。

答案 3 :(得分:2)

对于k8s版本1.10 +,User已被fsGroup取代。

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

答案 4 :(得分: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: {}
        securityContext:
          privileged: true
        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

答案 5 :(得分:0)

请参考发布:https://github.com/kubernetes/kubernetes/issues/2630

如果为空目录,则规范级别的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

答案 6 :(得分:0)

经过几次迭代后,我最终使用了

{{- $root := . }}
...
      initContainers:
      - name: volume-mount-hack
        image: busybox
        command: ["sh", "-c", "find /data -user root -exec chown 33:33 {} \\;"]
        volumeMounts:
{{- range $key,$val := .Values.persistence.mounts }}
        - name: data
          mountPath: /data/{{ $key }}
          subPath: {{ $root.Values.projectKey }}/{{ $key }}
{{- end }}

与其他解决方案相比,它更简洁且可配置。此外,它更快 - find 命令只更改实际属于 root 用户的文件/目录的权限。

当您挂载包含大量文件的卷时,这会对您的容器启动/加载时间(几秒甚至几分钟!)产生重大影响。

尝试比较

的执行时间

chown www-data:www-data ./ -R

find /data -user root -exec chown 33:33 {} \\;

你可能会感到惊讶!