前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8S中容器应用目录挂载数据卷后,就无法启动,报错权限问题

K8S中容器应用目录挂载数据卷后,就无法启动,报错权限问题

原创
作者头像
铜锣烧
修改2021-08-05 18:12:16
9K2
修改2021-08-05 18:12:16
举报

背景

使用中常会遇到,在不挂载数据卷(如PVC)时,容器就能正常运行,但是考虑到数据的持久化,把应用目录挂载到持久卷后,容器就无法启动,会报类似各种权限错误。

示例

此处以jenkins为例:

未挂载数据卷:

yaml如下,非关键字段已做删减

代码语言:javascript
复制
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如下,非关键字段已做删减

代码语言:javascript
复制
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 权限如下:

代码语言:javascript
复制
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为例,原始权限如下

代码语言:javascript
复制
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信息

代码语言:javascript
复制
###获取用户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:

增加initcontainers,修改挂载点属组

代码语言:javascript
复制
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的方式实现。当然,您也可以将此数据卷找个其他主机等挂载起来,修改好,然后再挂回来,其他方法可自行研究探讨,本文不在阐述。

注意事项及其他说明

  1. 权限改完了,initc怎么办? 因为权限和属组是跟着目录走的,一次修改,理论上永久生效,故initc容器,后续可以删除,pod重建后,该数据卷也不会再有权限问题。 也可以保留,保留便会在pod每次重建的时候,都会执行一遍权限修改命令。但是执行结果一样,理论不会有任何影响。 去留请自行评估。
  2. initc中,修改权限所用命令chown/chmod时,不建议使用-R进行递归,因为目录下的文件,权限属组不一定和目录完全相同,有些应用对数据文件权限属组敏感,如果权限被改,会导致启动失败。
  3. initc为何使用的是centos的容器,而不是再创建一个jenkins容器?
    1. 有些容器在启动时,非root用户,无法操作和修改此目录。
    2. 有的容器过于精简,可能没有此命令

    等等。。。一系列原因,故此例使用centos,用什么都行,原则就是把权限改了。

  4. chown为何非要使用用户/用户组的id,不能直接chown用户名/组名吗? 可以,但如上一条所说,这里使用的是centos镜像,里面并没有jenkins用户,故使用组名修改。
  5. 想到再说

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 示例
    • 未挂载数据卷:
      • 挂载数据卷:
      • 问题原因
      • 解决方法
        • 确认应用目录原本所需的权限属组
          • 增加initcontainers,修改挂载点属组
          • 总结
          • 注意事项及其他说明
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档