关于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. 新品来袭,全国产ARM+FPGA--"RK3568J+Logos-2"工业核心板,让您的硬件设计“更简单”!

    如需选购,请登录创龙科技天猫旗舰店: tronlong.tmall.com! 欢迎加入RK3568J技术交流群:567208221 欢迎加入Logos-2技术交流群:311416997 更多产品详情以 ...

  2. 数据特征采样在 MySQL 同步一致性校验中的实践

    作者:vivo 互联网存储研发团队 - Shang Yongxing 本文介绍了当前DTS应用中,MySQL数据同步使用到的数据一致性校验工具,并对它的实现思路进行分享. 一.背景 在 MySQL 的 ...

  3. LVS介绍与配置

    目录 LVS(Linux Virtual Server) 1. 概述 1.1 LVS简介 1.2 LVS架构 2. LVS工作模式 2.1 NAT模式(Network Address Translat ...

  4. P1546

    [USACO3.1]最短网络 Agri-Net 题意描述 FJ 已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最小的消费,他想铺设最短的光纤去连接所有的农场. 你将得到一 ...

  5. 数据存储为json或数据库

    1.数据存储 In [ ]: import requests from bs4 import BeautifulSoup rqq = requests.get('http://www.tipdm.co ...

  6. 4 安卓h5分享功能未实现

    安卓h5点击分享没有复制链接到剪切板

  7. PHP str_replace() 函数详解

    PHP str_replace() 函数详解 1.前言: str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写). 该函数区分大小写.请使用 str_ireplace() 函数 ...

  8. centos7安装pcntl扩展

    查看PHP扩展加载的目录php -i | grep extension_dir Centos下使用yum安装php默认是都不带pcntl扩展,需要安装扩展需要下载安装包,编译安装. 首先查看你的服务器 ...

  9. Nginx使用upstream实现动静分离

    一.为什么要进行动静分离 分离资源,减少不必要到的请求消耗,减少请求延时. 注:我这里,是nginx处理静态资源,apache处理动态资源. 场景分析: 1.未分离之前的场景步骤 (1)客户端请求ur ...

  10. 微信小程序热门选题

    一.大体实现思路 微信小程序,现在是非常热门的,基于微信生态开发的.现在很多计算机毕业的同学,都会选择微信小程序作为毕业设计 小程序端通常都是展示数据给用户去看的,大多数情况下,这些数据不是写死的,而 ...