关于hostPath的权限说明

最近项目中经常遇到pod中container挂载主机hostPath报错无权限问题:

httpd@hostpath-volume:/test-volume$ touch  123
touch: cannot touch '123': Permission denied

于是又复习了一遍hostPath使用方法,发现没有什么新知识的涌入:

行为
空字符串(默认)用于向后兼容,这意味着在挂载hostPath卷之前不会进行任何检查
DirectoryOrCreate 如果给定的路径没有任何东西存在,那将根据需要在此创建一个空目录,权限设置为0755,与kubelet拥有相同的用户与组
Directory 指定路径下必须存在此目录
FileOrCreate 如果给定的路径没有任何东西存在,那将根据需要在此创建一个空文件,权限设置为0644,与kubelet拥有相同的用户与组
File 给定的路径下必须存在文件
Socket 给定的路径下必须存在Unix套接字
CharDevice 给定的路径下必须存在字符设备
BlockDevice 给定的路径下必须存在块设备

使用这种卷类型时请注意:

  • 由于每个节点上的文件不同,具有相同配置(例如从 podTemplate创建的)的pod在不同节点上的行为可能会有所不同
  • 当Kubernetes按照计划添加资源感知调度时,将无法考虑hostPath使用的资源
  • 在底层主机上创建的文件或目录只能由root写入。必须在特权容器中以root身份运行进程,或修改主机上文件权限以便写入 hostPath 卷

注意几个话术

  1. 当值为DirectoryOrCreate和FileOrCreate时,并且给定的路径或文件不存在时,kubelet会自动创建,并且会和kubelet拥有相同的用户与组,说白了,就是你用什么用户起的kubelet创建出来的就是此用户的属主数组。
  2. 必须在特权容器中以root身份运行进程,或修改主机上文件权限以便写入 hostPath 卷。如果你的容器不是以root用户运行的,这一点可要注意了。

问题的根源

查看发现,容器挂载hostPath写入时报错Permission denied时基本都是容器运行用户不是root的情况下,这就说明,启动容器的用户没有权限在宿主机中属主属组为root的目录或者文件中写入。

这就很清晰明了,只要赋予运行容器的用户写权限,这个问题就解决了。

可是,我们应该赋予哪个用户呢?在宿主机创建一个与启动容器相同的用户然后赋予权限吗?显然不行。

那么容器用户与宿主机用户的对应关系是什么呢?没错,是uid。

只要将宿主机的用户与启动容器用户的uid相对应上,并且给它写的权限,那这个问题就迎刃而解了。

做几个测试

  1. 先创建一个普通用户起的container

    apiVersion: v1
    kind: Pod
    metadata:
    name: hostpath-volume
    namespace: default
    spec:
    containers:
    - name: hostpath-container
    image: nginx-test:v1
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /test-volume
    name: dir-volume
    volumes:
    - name: dir-volume
    hostPath:
    path: /data/vfan/test/
    type: DirectoryOrCreate
  2. 创建这个pod,测试写入

    ##
    kubectl create -f hostpath-test.yaml ##
    httpd@hostpath-volume:/$ cd /test-volume/
    httpd@hostpath-volume:/test-volume$ touch 11 22 33
    touch: cannot touch '11': Permission denied
    touch: cannot touch '22': Permission denied
    touch: cannot touch '33': Permission denied
  3. 查看宿主机相对应目录的权限

    # ll -dh /data/vfan/test/
    drwxr-xr-x 2 root root 4.0K Mar 21 14:53 /data/vfan/test/
  4. 查看容器内用户的uid,并查看宿主机的此uid用户是谁

    ## 容器内
    httpd@hostpath-volume:/test-volume$ id
    uid=1000(httpd) gid=1000(httpd) groups=1000(httpd) ## 容器外
    # grep 1000 /etc/passwd
    work:x:1000:1000::/home/work:/bin/bash

    如果没有相同uid的用户,则创建一个对应用户即可:useradd -u 1000 xxx

  5. 赋予宿主机对应uid用户权限,再次测试

    ## 宿主机
    chown work:work test/ ## 容器内
    httpd@hostpath-volume:/test-volume$ touch 11 22 33
    httpd@hostpath-volume:/test-volume$ ls
    11 22 33
  6. 容器内外权限分别是什么?

    ## 容器内
    httpd@hostpath-volume:/test-volume$ ls -ld /test-volume/
    drwxr-xr-x 2 httpd httpd 4096 Mar 21 07:27 /test-volume/ ## 容器外
    [root@gzbh-intel002.gom vfan]# ll -dh /data/vfan/test/
    drwxr-xr-x 2 work work 4.0K Mar 21 15:27 /data/vfan/test/

k8s pod挂载hostPath执行写时报错Permission denied的更多相关文章

  1. git提交时报错 permission denied

    git push 时报错:permission denied xxx 目前很多解决办法是生成公钥和秘钥,这种方法安全可靠,比较适用于一台电脑对应一个git账户,但是多个账户在同一台电脑上提交使用git ...

  2. Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.

    一.git push origin master 时出错 错误信息为: Permission denied(publickey). fatal: Could not read from remote ...

  3. Linux执行命令报错:Permission denied

    原因:权限被拒 结局办法 chmod -R 777 目录名 更改目录内文件的权限即可

  4. 执行automake时报错 error while making link: Operation not supported

    执行automake时报错: [root@localhost project]# automake --add-missingconfigure.in: installing `./install-s ...

  5. [转帖]Linux /tmp目录下执行脚本失败提示Permission denied

    Linux /tmp目录下执行脚本失败提示Permission denied https://www.cnblogs.com/linyfeng/p/11087655.html 国产化的环境上 就有一个 ...

  6. linux 下执行.sh文件提示permission denied

    linux 下执行.sh文件提示permission denied 在脚本文件目录下运行命令,赋予权限: chmod 777 *.sh or chmod +x  *.sh

  7. Visual Studio Code 使用 Git插件报错 - Permission denied (publickey)

    在使用GitHub的时候,为了避免每次输入用户名密码,都会使用SSH方式代替Https. 按网上教程,大多数使用SSH-KeyGen生成公私钥对,而后上传公钥至Github,并切换Repositori ...

  8. java sftp 报错 Permission denied (没有权限;拒绝访问)

    解决办法: 1.检查账号密码是否错误 2.检查freeSSHD是否是以管理员身份运行的 3.检查sftp路劲有没有配置错误,java通过sftp将图片文件传输到指定文件夹,如果这个文件夹在配置的当前目 ...

  9. 【jvm】linux 调用 jmap 报错Permission denied

    linux 调用 jmap  报错Permission denied 解决方案: 分别对java安装目录,java的bin目录以及jmap命令设置权限 chmod jdk1..0_79 chmod b ...

  10. IDEA中使用git报错Permission denied (publickey)

    最近在使用idea开发时,使用git拉取远程仓库的代码时,报错Permission denied (publickey),原因是因为ssh的密钥失效,必须得重新设置下ssh的密钥即可. 命令很简单,在 ...

随机推荐

  1. pyside6 QThread 以及自定义信号 测试

    import sys import random from time import sleep from PySide6 import QtCore as qc from PySide6 import ...

  2. 光伏储能电厂设备连接iec61850平台解决方案

    在当今日益发展的电力系统中,光伏储能技术以其独特的优势逐渐崭露头角,成为可再生能源领域的重要组成部分.而在光伏储能系统的运行与监控中,通信协议的选择与实现则显得至关重要.本文将重点介绍光伏储能系统中的 ...

  3. 解决方案 | cvxpy成功安装过程及其使用攻略

    背景:  由于需要研究KKT条件下的最优化问题,需要安装一个python的包cvxpy. 过程: 1.正常pip install cvxpy 不可取(不会成功,中间有报错): 2.主要错误在于:其依赖 ...

  4. tp5 为什么使用单例模式

    首先我们要知道明确单例模式这个概念,那么什么是单例模式呢?单例模式顾名思义,就是只有一个实例.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例, 这个类我们 ...

  5. Django 跨域访问POST请求需预先发送option请求问题处理方案

    跨域访问POST请求需预先发送option请求问题处理方案   By:授客 QQ:103355122 实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下 ...

  6. 2024 Selenium10个替代品

    随着自动化测试需求的不断增长,Selenium作为广泛使用的自动化测试工具,虽然功能强大,但也存在一些限制和挑战.在2024年, 越来越多的替代工具涌现,它们提供了更高效.更易用的解决方案.那么,哪些 ...

  7. linux的一些常用端口

    hdfs:9870 yarn:8088 sparkMaster的端口是:8080 worker的端口是:8081 历史服务器的默认端口是: 18080

  8. fragment基础

    XML中调用fragment 属性包括: android:id="@+id/fragg" //ID android:name="com.example.subway.fr ...

  9. 用IO多路复用实现 nginx 静态资源代理(C/Java/Golang)

    用IO多路复用实现 nginx 静态资源代理(C/Java/Golang) 效果展示 代理 HTML 代理图片 注意, 静态资源代理基于 HTTP, 可以了解上一篇文章: 几十行代码使用TCP简单实现 ...

  10. 安全可信,Solon v2.8.6 发布

    Solon 框架! Java "纯血国产"应用开发框架.开放原子开源基金会,孵化项目.从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态. 追求: 更快.更小.更 ...