使用中常会遇到,在不挂载数据卷(如PVC)时,容器就能正常运行,但是考虑到数据的持久化,把应用目录挂载到持久卷后,容器就无法启动,会报类似各种权限错误。
此处以jenkins为例:
yaml如下,非关键字段已做删减
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: default
spec:
selector:
matchLabels:
k8s-app: jenkins
qcloud-app: jenkins
template:
metadata:
labels:
k8s-app: jenkins
qcloud-app: jenkins
spec:
containers:
- image: jenkins:2.60.3
imagePullPolicy: Always
name: jenkins
结果:容器正常启动运行:
yaml如下,非关键字段已做删减
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: jenkins
qcloud-app: jenkins
name: jenkins
namespace: default
spec:
selector:
matchLabels:
k8s-app: jenkins
qcloud-app: jenkins
template:
metadata:
labels:
k8s-app: jenkins
qcloud-app: jenkins
spec:
containers:
- image: jenkins:2.60.3
imagePullPolicy: Always
name: jenkins
volumeMounts:
- mountPath: /var/jenkins_home
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: jenkins-pvc
结果:报权限错误
通常情况下,每个应用,会对该应用的应用文件所在文件夹属组或权限有要求,如果权限或者属组不对,就会导致此问题。
以这个jenkins实例为例,我们尝试将数据卷的挂载去掉,进入容器,可以看到,jenkins所使用的默认应用目录/var/jenkins_home
权限如下:
jenkins@jenkins-675c4bdb4-x7qkp:/var$ ls -ls /var |grep jenkins_home
4 drwxr-xr-x 12 jenkins jenkins 4096 Aug 5 03:44 jenkins_home
而将数据卷挂载至/var/jenkins_home
后,该路径会继承数据卷目录的属组和权限。
通常为:drwxr-xr-x 12 root root
不同环境可能有区别,但这不重要。想表达的意思就是,和应用所需的权限无法匹配,这是问题的根本原因!!!
目的:不论采取什么方法,目的就是希望所挂载卷的权限属组,要和应用所需的保持一致。
此处通过k8s中的initcontainers容器,来解决此问题。
去掉数据卷挂载,让容器在无任何数据卷的情况下启动,目的是为了获取所挂载目录的原始属组和权限信息。
以jenkins为例,原始权限如下
jenkins@jenkins-675c4bdb4-x7qkp:/var$ ls -ls /var |grep jenkins_home
4 drwxr-xr-x 12 jenkins jenkins 4096 Aug 5 03:44 jenkins_home
继续获取到用户/用户组所对应的ID信息
###获取用户id
jenkins@jenkins-675c4bdb4-x7qkp:/var$ cat /etc/passwd |grep jenkins
jenkins:x:1000:1000::/var/jenkins_home:/bin/bash
###获取组id
jenkins@jenkins-675c4bdb4-x7qkp:/var$ cat /etc/group |grep jenkins
jenkins:x:1000:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: jenkins
qcloud-app: jenkins
name: jenkins
namespace: default
spec:
selector:
matchLabels:
k8s-app: jenkins
qcloud-app: jenkins
template:
metadata:
labels:
k8s-app: jenkins
qcloud-app: jenkins
spec:
containers:
- image: jenkins:2.60.3
imagePullPolicy: Always
name: jenkins
volumeMounts:
- mountPath: /var/jenkins_home
name: data
initContainers:
- args:
- -c
- chmod 755 /var/jenkins_home && chown 1000:1000 /var/jenkins_home ### 这里将上一步所记录的权限属组进行更改
command:
- /bin/sh
image: centos
imagePullPolicy: IfNotPresent
name: chauth
securityContext:
privileged: true ### 建议开启特权模式
volumeMounts:
- mountPath: /var/jenkins_home ### initc也要对次数据卷进行挂载
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: jenkins-pvc
如是腾讯云tke环境,在页面可如此配置
修改后pod重建,问题解决。
根本目的在于所挂载卷的权限属组不对,思路即将该挂载点权限属组修改正确即可,因是k8s中的遇到的问题,本例也便是通过k8s自有的一个特性,增加initc的方式实现。当然,您也可以将此数据卷找个其他主机等挂载起来,修改好,然后再挂回来,其他方法可自行研究探讨,本文不在阐述。
等等。。。一系列原因,故此例使用centos,用什么都行,原则就是把权限改了。
4. chown为何非要使用用户/用户组的id,不能直接chown用户名/组名吗? 可以,但如上一条所说,这里使用的是centos镜像,里面并没有jenkins用户,故使用用户/用户组的id修改。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。