关于Docker目录挂载的总结

本文详细解析了Docker容器启动时挂载宿主机目录的方法,包括不同路径类型的处理方式、目录属主变更的影响及容器销毁后的目录状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定。

譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定:

# docker run -it -v /test:/soft centos /bin/bash

这样在容器启动后,容器内会自动创建/soft的目录。通过这种方式,我们可以明确一点,即-v参数中,冒号":"前面的目录是宿主机目录,后面的目录是容器内目录。

貌似简单,其实不然,下面我们来验证一下:

一、容器目录不可以为相对路径

[root@localhost ~]# docker run -it -v /test:soft centos /bin/bash
invalid value "/test:soft" for flag -v: soft is not an absolute path
See 'docker run --help'.

直接报错,提示soft不是一个绝对路径,所谓的绝对路径,必须以下斜线“/”开头。

二、宿主机目录如果不存在,则会自动生成

如果宿主机中存在/test目录,首先删除它

[root@localhost ~]# rm -rf /test
[root@localhost ~]# ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

启动容器

[root@localhost ~]# docker run -it -v /test:/soft centos /bin/bash
[root@a487a3ca7997 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  soft  srv  sys  tmp  usr  var

查看宿主机,发现新增了一个/test目录

[root@localhost ~]# ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test  tmp  usr  var

三、宿主机的目录如果为相对路径呢?

这次,我们换个目录名test1试试

# docker run -it -v test1:/soft centos /bin/bash

再到宿主机上查看是否新增了一个/test1目录,结果没有,是不是因为我用的是相对路径,所以生成的test1目录在当前目录下,结果发现还是没有。那容器内的/soft目录挂载到哪里去了?通过docker inspect命令,查看容器“Mounts”那一部分,我们可以得到这个问题的答案。

复制代码

    "Mounts": [
        {
            "Name": "test1",
            "Source": "/var/lib/docker/volumes/test1/_data",
            "Destination": "/soft",
            "Driver": "local",
            "Mode": "z",
            "RW": true
        }
    ],

复制代码

可以看出,容器内的/soft目录挂载的是宿主机上的/var/lib/docker/volumes/test1/_data目录

原来,所谓的相对路径指的是/var/lib/docker/volumes/,与宿主机的当前目录无关。

四、如果只是-v指定一个目录,这个又是如何对应呢?

启动一个容器

[root@localhost ~]# docker run -it -v /test2 centos /bin/bash
[root@ea24067bc902 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  test2  tmp  usr  var

同样使用docker inspect命令查看宿主机的挂载目录

复制代码

   "Mounts": [
        {
            "Name": "96256232eb74edb139d652746f0fe426e57fbacdf73376963e3acdb411b3d73a",
            "Source": "/var/lib/docker/volumes/96256232eb74edb139d652746f0fe426e57fbacdf73376963e3acdb411b3d73a/_data",
            "Destination": "/test2",
            "Driver": "local",
            "Mode": "",
            "RW": true
        }
    ],

复制代码

可以看出,同3中的结果类似,只不过,它不是相对路径的目录名,而是随机生成的一个目录名。

五、如果在容器内修改了目录的属主和属组,那么对应的挂载点是否会修改呢?

首先开启一个容器,查看容器内/soft目录的属性

[root@localhost ~]# docker run -it -v /test:/soft centos /bin/bash
[root@b5ed8216401f /]# ll -d /soft/
drwxr-xr-x 2 root root 6 Sep 24 03:48 /soft/

查看宿主机内/test目录的属性

[root@localhost ~]# ll -d /test/
drwxr-xr-x 2 root root 6 Sep 24 11:48 /test/

在容器内新建用户,修改/soft的属主和属组

[root@b5ed8216401f /]# useradd victor
[root@b5ed8216401f /]# chown -R victor.victor /soft/
[root@b5ed8216401f /]# ll -d /soft/
drwxr-xr-x 2 victor victor 6 Sep 24 03:48 /soft/

再来看看宿主机内/test目录的属主和属组是否会发生变化?

[root@localhost ~]# ll -d /test/
drwxr-xr-x 2 mycat mycat 6 Sep 24 11:48 /test/

竟然变为mycat了。。。

原来,这个与UID有关系,UID,即“用户标识号”,是一个整数,系统内部用它来标识用户。一般情况下它与用户名是一一对应的。

首先查看容器内victor对应的UID是多少,

[root@b5ed8216401f /]# cat /etc/passwd | grep victor
victor:x:1000:1000::/home/victor:/bin/bash

victor的UID为1000,那么宿主机内1000对应的用户是谁呢?

[root@localhost ~]# cat /etc/passwd |grep 1000
mycat:x:1000:1000::/home/mycat:/bin/bash

可以看出,宿主机内UID 1000对应的用户是mycat。

六、容器销毁了,在宿主机上新建的挂载目录是否会消失?

在这里,主要验证两种情况:一、指定了宿主机目录,即 -v /test:/soft。二、没有指定宿主机目录,即-v /soft

第一种情况:

复制代码

[root@localhost ~]# rm -rf /test    --首先删除宿主机的/test目录
[root@localhost ~]# ls /    --可以看到,宿主机上无/test目录
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@localhost ~]# docker run -it --name=centos_test -v /test:/soft centos /bin/bash  --启动容器,为了删除方便,我用--name参数指定了容器的名字
[root@82ad7f3a779a /]# exit
exit
[root@localhost ~]# docker rm centos_test   --删除容器
centos_test
[root@localhost ~]# ls /   --发现 /test目录依旧存在
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test  tmp  usr  var

复制代码

可以看出,即便容器销毁了,新建的挂载目录不会消失。进一步也可验证,如果宿主机目录的属主和属组发生了变化,容器销毁后,宿主机目录的属主和属组不会恢复到挂载之前的状态。

第二种情况,通过上面的验证知道,如果没有指定宿主机的目录,则容器会在/var/lib/docker/volumes/随机配置一个目录,那么我们看看这种情况下的容器销毁是否会导致相应目录的删除

首先启动容器

[root@localhost ~]# docker run -it --name=centos_test -v /soft centos /bin/bash
[root@6b75579ec934 /]# exit
exit

通过docker inspect命令查看容器在宿主机上生成的挂载目录

复制代码

    "Mounts": [
        {
            "Name": "b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301",
            "Source": "/var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301/_data",
            "Destination": "/soft",
            "Driver": "local",
            "Mode": "",
            "RW": true
        }
    ],

复制代码

对应的是/var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301/_data目录

销毁容器,看目录是否存在

[root@localhost ~]# docker rm centos_test
centos_test
[root@localhost ~]# ll /var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301
total 0
drwxr-xr-x 2 root root 6 Sep 24 14:25 _data

发现该目录依旧存在,即便重启了docker服务,该目录依旧存在

[root@localhost ~]# systemctl restart docker
[root@localhost ~]# ll /var/lib/docker/volumes/b53164cb1c9f1917788638692fb22ad11994cf1fbbc2461b6c390cd3e10ea301
total 0
drwxr-xr-x 2 root root 6 Sep 24 14:25 _data

七、挂载宿主机已存在目录后,在容器内对其进行操作,报“Permission denied”。

可通过两种方式解决:

1> 关闭selinux。

临时关闭:# setenforce 0

永久关闭:修改/etc/sysconfig/selinux文件,将SELINUX的值设置为disabled。

2> 以特权方式启动容器 

指定--privileged参数

如:# docker run -it --privileged=true -v /test:/soft centos /bin/bash

 

 

转自:https://www.cnblogs.com/ivictor/p/4834864.html

<think>好的,我需要帮助用户找到如何使用docker inspect命令查看Docker容器挂载目录。用户明确要求命令示例和教程,所以我要确保提供具体的步骤和示例。 首先,我记得docker inspect是用来查看容器、镜像等详细信息的命令。根据引用[1]和引用[3],用户可以通过该命令查看挂载信息,特别是使用--format参数或grep相关字段。需要确认正确的JSON字段,比如.Mounts或者.Config.Volumes。 引用[1]中提到,使用docker inspect http-web --format "{{.Config.Volumes}}"或者grep Volumes或Mounts。不过,可能.Config.Volumes显示的是容器内部定义的卷,而实际的挂载可能在.Mounts下,包括宿主机路径。需要验证这一。 引用[4]提到volumes配置可能涉及宿主机路径和容器路径,所以正确的命令应该显示这两者的映射。例如,使用--format参数提取.Mounts的信息,或者直接解析JSON输出。 可能需要注意不同Docker版本的输出差异,但通常.Mounts字段包含源(宿主机目录)和目标(容器目录)。因此,正确的命令应该是docker inspect --format='{{json .Mounts}}' 容器名,或者更友好的格式化方式,如使用{{range .Mounts}}循环展示每个挂载的Source和Destination。 另外,引用[2]展示了使用-f参数提取特定字段,例如镜像名,类似的可以应用到挂载目录。可能需要指导用户如何构造Go模板来提取所需信息。 总结步骤:1. 使用docker inspect查看容器详细信息,2. 通过--format过滤出挂载信息,3. 示例命令展示宿主机容器的路径映射。同时,可能需要提醒用户可以使用grep来查找相关行,如果不想处理JSON结构的话。 需要确保命令示例正确,比如使用.Mounts而不是.Config.Volumes,因为后者可能只显示容器内定义的卷,而不包括宿主机绑定挂载。因此,正确的字段应该是.Mounts,每个挂载对象的Source和Destination属性。 最后,生成相关问题,可能涉及其他查看挂载的方法,比如docker-compose文件检查,或者使用其他命令如docker volume inspect,以及如何优化命令输出等。</think>### 使用 `docker inspect` 查看容器挂载目录的步骤与示例 #### 1. **基础命令:查看完整挂载信息** 通过 `docker inspect` 可直接查看容器所有元数据(包括挂载信息),结合 `grep` 过滤关键字段: ```bash docker inspect 容器名/容器ID | grep -A 10 "Mounts" ``` 这会显示包含 `Mounts` 字段的上下文信息,适用于快速定位挂载配置[^1][^3]。 --- #### 2. **精准提取:使用 `--format` 参数** 通过 Go 模板语法提取关键字段,直接显示宿主机容器的路径映射: ```bash docker inspect --format='{{range .Mounts}}{{.Source}}:{{.Destination}} {{end}}' 容器名/容器ID ``` **示例输出**: ``` /home/user/app:/app /var/lib/data:/data ``` - `Source`:宿主机目录路径 - `Destination`:容器挂载路径[^4]。 --- #### 3. **结构化输出:展示详细挂载属性** 若需查看挂载类型(如 `bind` 或 `volume`)、读写权限等完整属性: ```bash docker inspect --format='{{json .Mounts}}' 容器名/容器ID | jq ``` **输出示例**(需安装 `jq` 工具美化 JSON): ```json [ { "Type": "bind", "Source": "/home/user/app", "Destination": "/app", "Mode": "rw", "RW": true } ] ``` - `Type: bind` 表示绑定挂载(宿主机目录- `Type: volume` 表示 Docker挂载[^4]。 --- #### 4. **对比 `Config.Volumes` 与 `Mounts` 的区别** - **`Config.Volumes`**:显示容器内声明为卷的目录(可能未绑定宿主机路径) ```bash docker inspect --format='{{.Config.Volumes}}' 容器名/容器ID ``` - **`Mounts`**:实际生效的挂载配置(包含宿主机路径)[^1][^3]。 --- #### 5. **扩展场景:批量查看所有容器挂载** 结合 `docker ps -aq` 列出所有容器挂载信息: ```bash docker ps -aq | xargs -I {} docker inspect --format='{{.Name}} 挂载: {{range .Mounts}}{{.Source}}:{{.Destination}} {{end}}' {} ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值