关于Docker目录挂载的总结
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
关于Docker目录挂载的总结的更多相关文章
- 关于Docker目录挂载的总结(转)
关于Docker目录挂载的总结 Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过 ...
- 转:Docker学习---挂载本地目录
原文: http://my.oschina.net/piorcn/blog/324202 docker可以支持把一个宿主机上的目录挂载到镜像里 docker run -it -v /home/dock ...
- docker:(3)docker容器挂载宿主主机目录
有一项重要的参数 -v 目录挂载,就是让容器内部目录和宿主主机目录关联起来,这样就可以直接操作宿主主机目录而不用再操作具体容器了 比如在2中,我们要发布一个war包,是通过 sudo docker c ...
- Docker容器挂载宿主目录的情形分析
Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定: # docker ...
- docker 设置映射端口 目录挂载
docker run -p 3092:9092 -p 3093:9093 -p 3094:9094 -p 3181:2181 --name="kafka_map_port_3092_4_31 ...
- 将宿主主机上的目录挂载到Docker中
docker run -it -v /home/zhouqun/文档/workplace:/var/www/html ubuntu64 /bin/bash 将宿主主机中/home/文档/workpla ...
- docker安装MySQL8,目录挂载、配置用户名密码、忽略表名大小写、连接数、特殊字符、时区
原文:docker安装MySQL8,目录挂载.配置用户名密码.忽略表名大小写.连接数.特殊字符.时区 一.环境配置 1.系统:centos7.3 2.docker版本:Docker version 1 ...
- 如何更改Docker已经挂载的目录
更改docker已经挂载的目录,主要有两种方式:一是重新创建容器,二是更改配置文件.第一种方式较为简单,下面具体演示第二种方式,通过更改配置文件来更换目录 挂载. 安装docker yum -y in ...
- 【docker】挂载web应用
现在将webapps目录挂载在宿主机目录,方便运维 docker run -p 8090:8080 --name app -v /usr/app:/usr/local/tomcat/webapps d ...
随机推荐
- 【Telerik】<telerik:RadComboBox>导出列表数据
近来在做项目,做到导出功能.使用<telerik:RadComboBox>的下拉框来实现导出部分或导出所有数据的功能.
- mac与windows通过ftp传输文件
1.两个系统相互传文件,比较通用的方式是用QQ,两台电脑一台各登陆一个qq,发文件就行了,在同一个网段时,qq会自动转换为按局域网的方式传输. 2.本人不愿安装qq,以ftp方式进行传输,先在wndo ...
- SQL 表的完整性
建立:主外键,约束.(删除主表的时候,同时删除子表:更新主表的时候更新子表) 1.建表时定义主键 Create table 表名 ( Sno int identity(1,1), Sname nvar ...
- js原生代码实现轮播图案例
一.轮播图是现在网站网页上最常见的效果之一,对于轮播图的功能,要求不同,效果也不同! 我们见过很多通过不同的方式,实现这一效果,但是有很多比较麻烦,而且不容易理解,兼容性也不好. 在这里分享一下,用j ...
- 如何识别一个字符串是否Json格式
前言: 距离上一篇文章,又过去一个多月了,近些时间,工作依旧很忙碌,除了管理方面的事,代码方面主要折腾三个事: 1:开发框架(一整套基于配置型的开发体系框架) 2:CYQ.Data 数据层框架(持续的 ...
- 在Visual Studio中将现有.NET Framework项目迁移至.NET Core 1.1 Preview 1
1)下载安装包含 .NET Core 1.1 Preview 1 的 SDK:Windows x64 安装包(下载地址列表) 2)下载最新 VS 2015 NuGet 插件:https://dist. ...
- Nova PhoneGap框架 第九章 控件
我们的框架中也提供了一些常用的控件,这些控件大多都依赖于我们的框架,也正是在我们的框架下才使得实现这些控件的变得更简单.但是我们的框架是不依赖与这些控件的,如果你用不上这些控件,你完全可以把相关的代码 ...
- 一个App完成入门篇(六)- 完成通讯录页面
第五章和第六章间隔时间有点长,对不起大家了.下面继续. 本节教程将要教会大家如何加载本地通讯录. 导入项目 导入通讯录 自定义js模块 发送和订阅page消息 将要学习的demo效果图如下所示 1. ...
- C语言 · 删除数组0元素
从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移动.注意,CompactIntegers函数需要接受数组及其元素个数作为参数,函数 ...
- Redis系列-好玩的用法
分布式锁 客户端执行如下命令,来获取锁和释放锁. random = random() ok = (Set key random PX 2000ms NX) if (ok) { //do somethi ...