k8s pod挂载hostPath执行写时报错Permission denied
关于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 卷
注意几个话术
- 当值为DirectoryOrCreate和FileOrCreate时,并且给定的路径或文件不存在时,kubelet会自动创建,并且会和kubelet拥有相同的用户与组,说白了,就是你用什么用户起的kubelet创建出来的就是此用户的属主数组。
- 必须在特权容器中以root身份运行进程,或修改主机上文件权限以便写入 hostPath 卷。如果你的容器不是以root用户运行的,这一点可要注意了。
问题的根源
查看发现,容器挂载hostPath写入时报错Permission denied时基本都是容器运行用户不是root的情况下,这就说明,启动容器的用户没有权限在宿主机中属主属组为root的目录或者文件中写入。
这就很清晰明了,只要赋予运行容器的用户写权限,这个问题就解决了。
可是,我们应该赋予哪个用户呢?在宿主机创建一个与启动容器相同的用户然后赋予权限吗?显然不行。
那么容器用户与宿主机用户的对应关系是什么呢?没错,是uid。
只要将宿主机的用户与启动容器用户的uid相对应上,并且给它写的权限,那这个问题就迎刃而解了。
做几个测试
先创建一个普通用户起的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
创建这个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
查看宿主机相对应目录的权限
# ll -dh /data/vfan/test/
drwxr-xr-x 2 root root 4.0K Mar 21 14:53 /data/vfan/test/
查看容器内用户的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
赋予宿主机对应uid用户权限,再次测试
## 宿主机
chown work:work test/ ## 容器内
httpd@hostpath-volume:/test-volume$ touch 11 22 33
httpd@hostpath-volume:/test-volume$ ls
11 22 33
容器内外权限分别是什么?
## 容器内
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的更多相关文章
- git提交时报错 permission denied
git push 时报错:permission denied xxx 目前很多解决办法是生成公钥和秘钥,这种方法安全可靠,比较适用于一台电脑对应一个git账户,但是多个账户在同一台电脑上提交使用git ...
- 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 ...
- Linux执行命令报错:Permission denied
原因:权限被拒 结局办法 chmod -R 777 目录名 更改目录内文件的权限即可
- 执行automake时报错 error while making link: Operation not supported
执行automake时报错: [root@localhost project]# automake --add-missingconfigure.in: installing `./install-s ...
- [转帖]Linux /tmp目录下执行脚本失败提示Permission denied
Linux /tmp目录下执行脚本失败提示Permission denied https://www.cnblogs.com/linyfeng/p/11087655.html 国产化的环境上 就有一个 ...
- linux 下执行.sh文件提示permission denied
linux 下执行.sh文件提示permission denied 在脚本文件目录下运行命令,赋予权限: chmod 777 *.sh or chmod +x *.sh
- Visual Studio Code 使用 Git插件报错 - Permission denied (publickey)
在使用GitHub的时候,为了避免每次输入用户名密码,都会使用SSH方式代替Https. 按网上教程,大多数使用SSH-KeyGen生成公私钥对,而后上传公钥至Github,并切换Repositori ...
- java sftp 报错 Permission denied (没有权限;拒绝访问)
解决办法: 1.检查账号密码是否错误 2.检查freeSSHD是否是以管理员身份运行的 3.检查sftp路劲有没有配置错误,java通过sftp将图片文件传输到指定文件夹,如果这个文件夹在配置的当前目 ...
- 【jvm】linux 调用 jmap 报错Permission denied
linux 调用 jmap 报错Permission denied 解决方案: 分别对java安装目录,java的bin目录以及jmap命令设置权限 chmod jdk1..0_79 chmod b ...
- IDEA中使用git报错Permission denied (publickey)
最近在使用idea开发时,使用git拉取远程仓库的代码时,报错Permission denied (publickey),原因是因为ssh的密钥失效,必须得重新设置下ssh的密钥即可. 命令很简单,在 ...
随机推荐
- pyside6 QThread 以及自定义信号 测试
import sys import random from time import sleep from PySide6 import QtCore as qc from PySide6 import ...
- 光伏储能电厂设备连接iec61850平台解决方案
在当今日益发展的电力系统中,光伏储能技术以其独特的优势逐渐崭露头角,成为可再生能源领域的重要组成部分.而在光伏储能系统的运行与监控中,通信协议的选择与实现则显得至关重要.本文将重点介绍光伏储能系统中的 ...
- 解决方案 | cvxpy成功安装过程及其使用攻略
背景: 由于需要研究KKT条件下的最优化问题,需要安装一个python的包cvxpy. 过程: 1.正常pip install cvxpy 不可取(不会成功,中间有报错): 2.主要错误在于:其依赖 ...
- tp5 为什么使用单例模式
首先我们要知道明确单例模式这个概念,那么什么是单例模式呢?单例模式顾名思义,就是只有一个实例.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例, 这个类我们 ...
- Django 跨域访问POST请求需预先发送option请求问题处理方案
跨域访问POST请求需预先发送option请求问题处理方案 By:授客 QQ:103355122 实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下 ...
- 2024 Selenium10个替代品
随着自动化测试需求的不断增长,Selenium作为广泛使用的自动化测试工具,虽然功能强大,但也存在一些限制和挑战.在2024年, 越来越多的替代工具涌现,它们提供了更高效.更易用的解决方案.那么,哪些 ...
- linux的一些常用端口
hdfs:9870 yarn:8088 sparkMaster的端口是:8080 worker的端口是:8081 历史服务器的默认端口是: 18080
- fragment基础
XML中调用fragment 属性包括: android:id="@+id/fragg" //ID android:name="com.example.subway.fr ...
- 用IO多路复用实现 nginx 静态资源代理(C/Java/Golang)
用IO多路复用实现 nginx 静态资源代理(C/Java/Golang) 效果展示 代理 HTML 代理图片 注意, 静态资源代理基于 HTTP, 可以了解上一篇文章: 几十行代码使用TCP简单实现 ...
- 安全可信,Solon v2.8.6 发布
Solon 框架! Java "纯血国产"应用开发框架.开放原子开源基金会,孵化项目.从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态. 追求: 更快.更小.更 ...