100

我正在使用 kops 在 AWS 上运行 Kubernetes 集群。我已将 EBS 卷安装到容器上,它在我的应用程序中可见,但它是只读的,因为我的应用程序没有以 root 身份运行。如何PersistentVolumeClaim以 root 以外的用户身份挂载 a?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
4

9 回答 9

80

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

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

更多信息在这里

于 2017-04-21T14:30:25.500 回答
70

我最终得到了一个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
于 2018-07-05T15:47:13.417 回答
28

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

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

请按照以下步骤进行操作。

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

    spec:
      securityContext:
        runAsUser: 1099
        runAsGroup: 1099
        fsGroup: 1099
    

作为用户运行

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

运行组

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

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

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

fs组

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

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

于 2019-09-13T04:46:04.753 回答
9

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

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

于 2018-07-04T16:44:30.213 回答
2

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

如果是emptydir,则可以使用securityContextin :spec

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

如果卷是 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
于 2020-09-23T06:33:44.907 回答
1
  • 在 minikube 中,它在initContainersroot用户身份运行后工作,通过设置runAsUser: 0
    initContainers:
      - name: change-ownership-container
        image: busybox
        command: ["/bin/chown","-R","1000:1000", "/home/jovyan/work"]
        securityContext:
          runAsUser: 0
          privileged: true
        volumeMounts:
        - name: notebook-data
          mountPath: /home/jovyan/work 

所以整个 Yaml 文件看起来像这样

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: jupyter
  labels:
    release: jupyter
spec:
  replicas:
  updateStrategy:
    type: RollingUpdate
  serviceName: jupyter-headless
  podManagementPolicy: Parallel
  selector:
    matchLabels:
      release: jupyter
  template:
    metadata:
      labels:
        release: jupyter
      annotations:
    spec:
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: jupyter
        image: "jupyter/base-notebook:ubuntu-20.04"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8888
          protocol: TCP
        - name: blockmanager
          containerPort: 7777
          protocol: TCP
        - name: driver
          containerPort: 2222
          protocol: TCP
        volumeMounts:
        - name: notebook-data
          mountPath: /home/jovyan/work
        resources:
          limits:
            cpu: 200m
            memory: 300Mi
          requests:
            cpu: 100m
            memory: 200Mi
      initContainers:
      - name: change-ownership-container
        image: busybox
        command: ["/bin/chown","-R","1000:1000", "/home/jovyan/work"]
        securityContext:
          runAsUser: 0
          privileged: true
        volumeMounts:
        - name: notebook-data
          mountPath: /home/jovyan/work
      volumes:
      - name: notebook-data
        persistentVolumeClaim:
          claimName: jupyter-pvc  
于 2021-10-06T18:12:20.090 回答
0

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

这里是弹性搜索 pod 的示例

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
于 2019-09-13T07:26:22.307 回答
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 {} \\;

你可能会感到惊讶!

于 2021-05-26T15:56:01.650 回答
0

在我的情况下,我用作scratch基本映像并将用户设置为 65543。我需要对目录的写入权限。我通过使用emptyDir音量来做到这一点,

spec:
  containers:
    ...
    volumeMounts:
      - mountPath: /tmp
        name: tmp
        # readOnly: true
  volumes:
  - name: tmp
    emptyDir: {}
于 2021-10-26T20:28:54.477 回答