简介
docker镜像下载就是分层的。
最下面是底层的,与Linux的系统内核一致。
再下载的就是往上叠加。
下面的这种情况7就会把5覆盖。
下载镜像会出现already exists 已经存在。
1 | 7 |
我们不可以修改镜像,我们启动的容器的最底层就是我们所指定的镜像,我们再修改的时候,是在镜像新建了一层,如果有重复就会覆盖。就像上面7覆盖5一样。
查看容器卷
通过docker inspect id
查看容器详细信息
Mounts:就是对应容器挂载。可使用docker inspect id | grep "Mounts" -A 20
来进行快捷查看
Source:Linux
Destination:容器
挂载之后,docker rm -f id删除容器之后,本地的卷依然存在,(–rm 匿名挂载的卷除外,但是 –rm 的具名挂载就会依然存在)。
容器卷命令
1 | docker volume --help 查看数据卷帮助 |
具名挂载创建
1 | [root@localhost ~]# docker volume ls |
具名挂载【-v 卷名:容器路径】docker run -P --name nginx01 -v juming-nginx:/etc/nginx -d nginx
1 | [root@localhost ~]# docker volume ls |
查看卷的信息
docker volume inspect 卷名
查看卷的信息
docker的所有信息默认/var/lib/docker,其中/var/lib/docker/volumes就是放所有卷的。
默认把-v指定的容器路径的东西映射到/var/lib/docker/volumes/xxx/_data
三种挂载方式
1 | 匿名挂载:-v 容器路径 |
说明:
1、匿名挂载:如果 Dockerfile 指定了VOLUME PATH1 [PATH2] ...
,若 docker run 时不使用 具名挂载,或路径挂载,默认使用匿名挂载,相当于 docker run ... -v PATH1 [-v PATH2] ...
2、路径挂载在使用docker volume ls
不会显示,因为它是 路径挂载,而不会拥有 卷名。
3、匿名挂载会随机分配一下卷名 xxx,匿名挂载/具名挂载对应的路径就是 /var/lib/docker/volumes/卷名/_data
4、在使用--rm
与匿名挂载一起使用时,也就是docker run --rm ... -v 容器路径
,容器不在了,卷也会不在。只有这一种情况的卷才是非持久化的。
5、匿名挂载,具名挂载都是容器路径下的东西挂载到本地的/var/lib/docker/volumes/卷名/_data
,而路径挂载是Linux路径下的内容挂载到容器路径下
6、匿名挂载可以使用docker rm -fv 容器id
进行删除容器并移除卷,具名挂载则不可以。因为docker rm -fv
只会移除与容器绑定的匿名卷。
拓展:只读
1 | 容器路径后面跟:ro 或 :rw |
测试Dockerfile
docker镜像是一层一层的,Dockerfile就是一层一层的,每个命令就是一层
1 | FROM nginx |
docker build -t taopanfeng/nginx:1.0 .
docker images
就可以查看到新生成的镜像了
docker run --name x01 -it taopanfeng/nginx:1.0 /bin/bash
启动之后,就会进入容器
此时我们在容器的/
根目录,我们ls -l
就可以看到我们的volume01 volume02。
因为默认 WORKDIR 工作目录就是 /
根目录,而容器启动时,卷指定的目录不存在,就自动创建目录。
我们exit
退出容器,在容器外执行docker inspect 容器id | grep "Mounts" -A 20
查看Mounts模块就可以看到volume01 volume02映射的本地路径。
容器卷是在/var/lib/docker/volumes/xxx/_data
,其中xxx
就是卷名
多容器共享卷
多个容器共享容器卷
docker run --name x02 -it --volumes-from x01 taopanfeng/nginx:1.0 /bin/bash
此时x02容器也会有x01的内容
docker inspect 容器id
查看x01 与 x02的Mounts本地挂载地址是不是同一个。验证:是同一个
使用场景:多个mysql进行数据共享,
mysql01容器指定了-v ,
mysql02容器指定–volumes-from mysql01
注意(持久化):上面已经说过了,只有映射到了本地容器卷,容器删除之后,本地也会存在数据。
下面是之前的笔记,一次测试
1 | docker run --name x01 -v /a:/a -d 镜像名称 |
关于挂载路径问题
1 | 匿名挂载:-v 容器路径 |
不挂载,仅为了查看容器默认内容
1 | ------------------------docker run --name centos00 -itd centos |
匿名挂载:容器路径不存在
》》》会把容器路径当做目录进行多层创建,类似于 mkdir -p 容器路径
》》》为该匿名卷随机取一个字符串当做卷名,在Linux本地创建目录/var/lib/docker/volumes/卷名/_data
》》》把容器路径下的内容挂载到Linux 路径的/var/lib/docker/volumes/卷名/_data
。(此时复制是空,因为容器路径不存在,创建的是空目录,所以挂载也是空)
》》》聪明的会发现,他们两个目录的 inode号码是一致的。
》》》可以理解为两个目录的硬链接,而这个硬链接,是由Linux执行容器的,也就是先有容器,再根据容器建立硬链接/var/lib/docker/volumes/卷名/_data
。
1 | ------------------------docker run --name centos01 -itd -v /abc/def/g centos |
匿名挂载:路径是文件
》》》启动容器报错:不能挂载已存在的文件,文件已经存在 /var/lib/docker/devicemapper/mnt/…
1 | ------------------------docker run --name centos02 -itd -v /root/original-ks.cfg centos |
匿名挂载:路径是目录
》》》同匿名挂载:容器路径不存在
类似,只不过匿名挂载:容器路径不存在
会递归创建目录,
》》》把容器路径/root
下的内容挂载到Linux路径下/var/lib/docker/volumes/卷名/_data
》》》此时/var/lib/docker/volumes/卷名/_data
中是有数据的,因为/root
下是存在数据的
1 | ------------------------docker run --name centos03 -itd -v /root centos |
具名挂载:卷名规则
》》》具名挂载的名称规定:(至少两个字符)大小写字母或数字开头,内容只能包含大小写字母和数字,以及 _.- 下划线,小数点,减号 这三个特殊字符
》》》具名挂载与匿名挂载原理类似,只不过它为容器卷自定义了一个名称而已,在 docker volume ls
中方便查看
1 | ------------------------docker run --name centos04 -itd -v abc/def:/root centos |
路径挂载:容器路径不存在
》》》把不存在的路径递归创建目录,并把Linux路径下的内容挂载到容器路径下
》》》ln Linux路径 容器路径,把 Linux 路径建立一个硬链接(容器路径),
1 | ------------------------ls -lid /root/ |
路径挂载:Linux路径不存在
》》》会递归创建 Linux目录,再 ln Linux路径 容器路径
1 | ------------------------docker run --name centos06 -itd -v /q/w:/root centos |
路径挂载:Linux路径与容器路径一个是文件,一个是目录
》》》不可以创建,会报错:类型映射不正确
1 | #===> Linux路径是文件,容器路径是目录 |
路径挂载:Linux路径是文件/目录,容器路径不存在
》》》依旧如此,ln Linux路径 容器路径,只不过 容器路径中不存在的目录会自动创建
1 | ------------------------ls -li /root/ |
路径挂载:Linux路径不存在,容器路径是文件/目录
》》》当Linux路径不存在时,容器路径是只能是目录,而不可以是文件,会报错:类型映射不正确
1 | #===> Linux路径不存在,容器路径是目录 |