详述docker任意容器,指定目录挂载时,启动失败原因。出现no such file or directory或permission denied等现象。

该现象在 任何需要挂载数据卷的容器中都可能会出现

提出两个主体点:

  1. 一个容器挂载多个数据卷时,有先后顺序的,且可能会被应用的多个进程或线程(本文中后面都会直接叫进程),在不同时间被操作。
  2. 挂载的数据卷中产生的文件,所在目录层级超过两级以上时,会对所属用户及权限产生影响。

官网实在找不到相关描述,只能自己测试。

下面会拿mysql为例,一步步观察,其他应用中也会是一样的原理。


当前my.cnf配置如下:

[mysqld]
### 基础配置 ###
user=mysql
bind_address=::
port=3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
tmpdir=/usr/local/mysql/logs/tmp
log_error=/usr/local/mysql/logs/mysql-error.log
pid_file=/usr/local/mysql/logs/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
explicit_defaults_for_timestamp=1

尝试启动容器, 失败,查看相关状态及日志:

图1:

在这里插入图片描述
关注点已经标出,尤其注意其中的挂载目录: /usr/local/mysql

整理一下信息:
1.只挂载 /usr/local/mysql 目录的情况下,其子目录中 /usr/local/mysql/data ,/usr/local/mysql/logs/mysql-error.log 都被创建和生成,而 /usr/local/mysql/logs/tmp 没有被创建,并报错:找不到 /usr/local/mysql/logs/tmp/ib27CTxy。
2.不知道底层具体运行流程原理的情况下,我们只能猜测有两种情况:①.跨越两个目录没法自动创建。 ②.两边是被两个不同身份的进程操作,权限不同。

先看,其他不变仅增加一条挂载命令,使其启动 成功

图2:

在这里插入图片描述
上级目录 /usr/local/mysql 的挂载,没有对 /usr/local/mysql/logs/tmp 目录产生影响,故而增加对该目录的挂载,启动成功,似乎情理之中,意料之中。

但,这远远不够消除我们的疑虑。

下面继续尝试,其他都不变,仅在my.cnf给msyql-error.log文件增加一层上级目录
如下:
/usr/local/mysql/logs/ test1/ mysql-error.log
/usr/local/mysql/logs/ test1/ mysqld.pid

看下图中的状态及日志:

图3:

在这里插入图片描述
竟然失败了!!!!!

整理一下信息:

  1. /usr/local/mysql/logs/test1/mysql-error.log 文件成功生成,说明跨两级目录对文件生成并没有什么影响。
  2. 这次图3和图1图2对比一下,logs目录的所属用户,从systemd-coredump变成了root,两极目录对文件生成没有影响,可是对相关目录所属用户有影响了
  3. 对于 /usr/local/mysql/logs/tmp/ib27CTxy 的报错,从找不到变成了没有权限,联合第二条所属用户变为root来看,没权限很正常。
  4. 图1时的 /usr/local/mysql/logs/tmp/ib27CTxy 和 图3时的 /usr/local/mysql/logs/test1/mysql-error.log,从目录等级上并没有区别,但却有一个一直可以成功,有一个一有风吹草动就失败,很明显,操作两边目录和文件的是两个进程,权限不一致。
  5. 图3中 /usr/local/mysql/logs 目录,所属用户变为root,有两种可能性,①因为tmp和test1两边操作时间先后顺序问题,被覆盖操作 ②logs目录脱离了test1那边可控范围。

下面继续尝试,其他都不变,仅在my.cnf给msyql-error.log文件再增加一层上级目录
如下:
/usr/local/mysql/logs/test1/ test2/ mysql-error.log
/usr/local/mysql/logs/test1/ test2/ mysqld.pid

图4:

在这里插入图片描述
整理一下信息:

  1. 其他反应都没变,图3时所属用户为 systemd-coredump的test1目录,在这图4中变成了root,仔细观察就会发现,是操作mysql-error.log这个文件的进程,只能影响它的上一级目录的所属用户为systemd-coredump,再往上就影响不到。
  2. 同时,也说明logs目录的所属用户root,不是被tmp目录文件的进程覆盖操作而形成的。

至此,虽然不知道具体底层运行流程及原理。但我们可以知道,只要把tmp目录,放在与mysql-error.log同一级目录就会继承或者说享受systemd-coredump所属用户的权限。

进一步确认结论,根据前一步,把tmp目录放至test2目录下。
修改my.cnf:
tmpfile=/usr/local/mysql/logs/test1/test2
修改挂载路径:
/usr/local/mysql/logs/test1/test2:/usr/local/mysql/logs/test1/test2

看图,看反应:

图5:

在这里插入图片描述
反应如预料之中,启动成功。


因本人对Linux很多模块的底层原理不太清楚,只能通过这种对各种猜测进行测试的方式。希望能给到你们,不一样的思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值