我正在使用kops在AWS上运行Kubernetes集群。我已经将一个EBS卷安装到一个容器上,它可以从我的应用程序中看到,但它是只读的,因为我的应用程序不是以root身份运行的。如何以非root用户身份挂载PersistentVolumeClaim
? 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
答案 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用户必须有权访问要在其中读写数据的文件夹。
请按照以下步骤操作。
在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 {} \\;
你可能会感到惊讶!