关于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. AJAX基础+Axios快速入门+JSON使用+综合案例

    目录 1. AJAX 1.1 概述 1.1.1 作用 1.1.2 同步和异步 1.2 快速入门 1.2.1 服务端实现 1.2.2 客户端实现 1.3 案例 1.3.1 需求 1.3.2 分析 1.3 ...

  2. SQL注入方法

    目录 前言 如何测试与利用注入点 手工 注入思路 工具 sqlmap -r -u -m --level --risk -v -p --threads -batch-smart --os-shell - ...

  3. mac idea快捷键整理

    抽取局部变量 option+commamd+v 生成方法内变量 option+commamd+f 生成类的静态变量 找方法 2次shift 优化import Ctrl + Alt + O 格式化代码 ...

  4. Linux-shell编程入门基础

    目录 前言 Shell编程 bash特性 shell作用域 变量 环境变量 $特殊变量 $特殊状态变量 $特殊符号(很重要) 其他内置shell命令 shell语法的子串截取 统计 指令执行时间 练习 ...

  5. 将传统应用带入浏览器的开源先锋「GitHub 热点速览」

    现代浏览器已经不再是简单的浏览网页的工具,其潜能正在通过技术不断地被挖掘和扩展.得益于 WebAssembly 等技术的出现,让浏览器能够以接近原生的速度执行非 JavaScript 语言编写的程序, ...

  6. socket通讯原理及例程(一看就懂

    来源:https://blog.csdn.net/jiushimanya/article/details/82684525 里面有疑问或者不正确的地方可以给我留言 对TCP/IP.UDP.Socket ...

  7. 数据仓库建模工具之一——Hive学习第二天

    Hive的概述 1.Hive基本概念 1.1 Hive简介 Hive本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据存储,说白了hive可以理解为一个将SQL转换为Map ...

  8. 安装docker并部署java项目

    docker部署springboot项目(详细教程)_使用docker部署springboot项目_流星007的博客-CSDN博客 ps:以下是部署到linux 服务器中的 案例(与chatgpt的对 ...

  9. 【Windows】搭建FTP服务器

    1.开启FTP服务和IIS服务 2.设置IIS服务 添加FTP站点[右键] 设置站点名称和物理路径 绑定IP地址和FTP端口号 可以自定义虚拟主机名称 下面勾选[无SSL]即可 身份验证和授权设置 在 ...

  10. DirectX9(D3D9)游戏开发:高光时刻录制和共享纹理的踩坑

    共享纹理 老游戏使用directx9无法直接与cc高光sdk(d3d11)对接,但是d3d9ex有共享纹理,我们通过共享纹理把游戏画面共享给cc录制,记录一些踩坑的笔记. 共享纹理示例: // 初始化 ...