论:docker数据卷和用户权限相关——所有坑

我自己折腾了两天,看到其他文章都是只讲零碎单点概念、只讲特定场景(暴力)解决办法,挺无奈。

自己有头绪了,来分享一番,通过主题打开思路,不要纠结细节。

相关的报错

1.Permission denied
2.docker xxx 'xxx' is not the name of a known user
3.Fatal error: Can't change to run as user 'xxx' please check that the user exists
4.xxx failed while attempting to check config  command was
5.Could not open file '/xxx/xxx/xxx.xxx' for error logging: Permission denied
等等等等等等,任何挂载的数据卷及其用户权限相关。

先提出几个问题:

如果是你,像docker容器这种套娃的工具,宿主机系统用户和容器系统用户的关系,你要怎么处理?

宿主机的文件夹挂载到容器的文件夹,权限你觉得该怎么处理?

容器数据卷3种挂载方式(指定目录挂载、匿名挂在、具名挂载)和相互之间各个情况下(宿主机和容器两边指定的目录下挂载前已存在目录或文件时)的继承方式,你搞清楚了吗?

我不是一个专门的运维人员,一直觉得linux配置管理,用户和用户组,文件的所属用户和所属用户组,是比较麻烦头痛的。因为,你首先要清楚一个软件,他的主进程或者说会涉及触碰服务器资源的进程,到底都会碰哪些文件,而且这个触碰不是只有启动时,也可能是运行时中途突然产生。那你就要搞清楚一个软件的底层运行原理,我觉得这太难了,或者说,太费时间了。一个linux就很麻烦了,又往里套了一层linux。买噶!这是我起初接触docker时的想法,很好奇,他会怎么解决?

说明几点概念:

  • 以面向对象的习惯和角度,我希望,我的权限管理,只对docker容器负责,我只要用当前用户假设为www,能启动docker容器A,那docker容器A就继承www的所有权限,至于容器系统中的用户及权限,我不管!那是不是这个容器,就从安全问题独立出来了?或者说,至少不会给原本宿主机的权限管理增加麻烦?根据我的理解,至少大方向是这样的。至于怎么继承,我猜应该是把容器中的用户uid映射到了容器被启动的宿主机用户uid上了。
  • 根据上一个点中要注意到,容器中叫www2的用户,和宿主机中www2的用户不是一个,或者说本质上不是一个,即使权限相同。因为像我说的,他们只是映射,两边是完全独立的用户管理系统。不要被网上其他文章中一些说法给搞蒙了。什么容器不指定用户默认就是root,什么两边uid一致权限就一致,所以设置成一致就可以。确实如他们所说,因为宿主机和容器共用内核,内核根据uid判断权限,所以设置成同一个uid,可以解决问题,但这不是长久之计。实际上,你需要做的是,设置好启动docker的用户及权限就可以了,不需要考虑容器中的用户。
  • 关于宿主机用户和容器用户,即使名称相同,但权限不一定相同,是因为,两边是完全独立的用户权限管理系统。就像我在docker网络文章( 论:docker的两个容器为什么默认不能通过服务名互通,而指定自定义bridge模式网络就可以_古稀开启编程世界的博客-CSDN博客 )中提过的一样,这里好像也有命名空间的概念。这是一种隔离思想,无处不在。
  • 数据卷会根据不同挂载情况,有两个反应,或者宿主机的覆盖容器的,或者容器的覆盖宿主机的。尤其是你如果属于如下两种情况,需要特别注意,并且一定要验证清楚。一,是你在一个半成品服务器上,拉下容器想把配置文件目录挂载到已存在的宿主机配置文件目录下;二,是你想动态扩展容器,挂载到同一个目录,这个目录已经被其他容器挂载。说白了,就是宿主机目录和要挂载的容器目录至少有一方非空,就是里面有内容
  • 挂载既然涉及到覆盖,那文件对应的所属用户和所属用户组,会随着覆盖目录内容继承。所以你要考虑到,如果是容器目录覆盖了宿主机目录,那很可能所属用户,不一定存在于宿主机上
  • 你如果属于像我一样习惯了二进制编译安装,希望把配置文件挂载到以前一直习惯用的指定路径下,如/usr/local/redis/conf,那要清楚,指定目录挂载和具名匿名挂载是有区别的,更容易出现用户权限对应问题。
  • 还有最后一个最最最最麻烦的点,宿主机中创建目录或文件,有两个阶段,一个是容器内应用根据配置参数初始化时,再一个是应用启动以后的进程成功运行后。比如mysql5.7.40容器启动时,第一阶段data-dir目录已经初始化并创建挂载的目录(不存在时),如/usr/local/mysql/data目录,此时进程有相关权限,并且创建的目录及文件所属用户为 systemd-coredump。但在第二阶段中,也就是log-error目录是在容器内的应用启动完成后才会触发,此时已经没有了相关权限,会使得宿主机创建该目录,如归属用户可能为root等,则容器想在此目录创建或写文件,就没有权限了。

看一个官网截图,解释容器启动中的内部流程:

1. 如果你本地没有对应镜像,则根据配置的仓库地址,拉取对应镜像到本地。命令相当于:docker pull ubuntu

2. 为你创建容器。命令相当于:docker container create

3. 给最上层(可叫容器层)分配一个可读写的文件系统(最上层以下镜像(可叫镜像层)都是只读),可创建修改文件或文件夹

4.如果没有指定网络参数,就默认分配一个网络(网络名叫bridge,它的网络类型也是bridge)。

5.启动容器,执行/bin/bash

-----------------------------------------------------

官网没找到挂载容器卷具体在哪个细节位置执行的,有找到的,麻烦告知位置,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值