docker容器卷与主机
docker官网关于容器卷的介绍文档:
https://docs.docker.com/storage/volumes/
Volumes have several advantages over bind mounts:
挂载容器卷有以下几个好处:
Volumes are easier to back up or migrate than bind mounts.
更容易备份或者迁移
You can manage volumes using Docker CLI commands or the Docker API.
可以通过Docker CLI命令或者Docker API管理容器卷
Volumes work on both Linux and Windows containers.
容器卷在Linux和Windows系统都可用
Volumes can be more safely shared among multiple containers.
容器卷可以在多个容器中更安全地共享(数据)
Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
容器卷驱动可以让你的存储放在远程主机或者云上,加密卷的内容
New volumes can have their content pre-populated by a container.
新的容器卷可以先写了数据(再挂载去用?)
Volumes on Docker Desktop have much higher performance than bind mounts from Mac and Windows hosts.
容器卷在Docker桌面版有更高的性能
可以用-v(–volume)或者–mount来使用容器卷,但是要管理容器卷必须使用–mount参数
本文先不讲–mount参数
容器的文件要持久的保存,就需要与主机交互,把容器里面的数据持久化到主机的磁盘
容器卷就是用来解决这个容器数据持久化的问题的
容器卷有一下特点:
注意第3点,卷中的更改不会包含在镜像中
我们写到容器卷中的数据,是容器操作的,数据是写在容器卷(磁盘)中,并不是写入镜像的,一定要区分这个
先启动docker run一个容器,命令格式
docker run -it -d -v 主机本地目录:容器内部目录 --name your_container_name IMAGE
[root@WIND ~]# docker run -it -d --privileged=true -v /tmp/host:/tmp/data/ --name=u001 ubuntu
c0c3e690575d0c332fbfe969bc81e9e73e0e36be3c54c76e28ca9cec076d253f
[root@WIND ~]#
[root@WIND ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
c0c3e690575d ubuntu "bash" 3 seconds ago Up 2 seconds
–privileged=true, 使用该参数,container内的root拥有真正的root权限。
否则,container内的root只是外部的一个普通用户权限。
privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
甚至允许你在docker容器中启动docker容器。
docker inspect 会返回docker相关的很多信息,包括挂载信息,我们看一下是否有挂载
[root@WIND ~]#docker inspect u001
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/host",
"Destination": "/tmp/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
这里只是截取了返回的一部分内容贴出来,还有很多的,看到有挂载了
ro参数是只读挂载,不加这个参数,默认是读写挂载的
[root@WIND host]# docker run -it -d --privileged=true -v /tmp/host:/tmp/data/:ro --name=u002 ubuntu
f473321ad5f612180d35c7380fe8f69b3a22d3df9f7e40160c6d4c3595e5065d
[root@WIND host]#
[root@WIND host]# touch read_only.txt
[root@WIND host]# docker exec -it u002 /bin/bash
root@f473321ad5f6:/# cd /tmp/data/
root@f473321ad5f6:/tmp/data# ls
file_from_docker.txt read_only.txt
root@f473321ad5f6:/tmp/data#
root@f473321ad5f6:/tmp/data# touch read_only_docker.txt
touch: cannot touch 'read_only_docker.txt': Read-only file system
root@f473321ad5f6:/tmp/data#
上面的命令是只读挂载,关注之后,想在容器里,新建一个read_only_docker.txt文件(写操作),是不允许的,直接提示:Read-only file system
只读挂载的时候,宿主机写入的内容,会同步给容器,容器内可以正常读
在主机外建的read_only.txt在容器里面就可以看到(读到)
容器卷是可以继承和共享的
前面已经有2个ubuntu了,我们再建一个u3
[root@WIND u3]# docker run -it -d --privileged=true -v /tmp/u3:/tmp/u3 --name=u3 ubuntu
[root@WIND u3]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
b9abd90313bb ubuntu "bash" About a minute ago Up About a minute
u3
root@b9abd90313bb:/# cd /tmp/u3/
root@b9abd90313bb:/tmp/u3# touch file_from_u3.txt
root@b9abd90313bb:/tmp/u3# echo "hello u3" >> file_from_u3.txt
[root@WIND u3]# touch file_from_host.txt
[root@WIND u3]# echo "hello host" >> file_from_host.txt
[root@WIND u3]#
[root@WIND ~]# cd /tmp/u3/
[root@WIND u3]# ls
file_from_u3.txt
[root@WIND u3]#
[root@WIND u3]# cat file_from_u3.txt
hello u3
[root@WIND u3]# docker exec -it u3 bash
root@b9abd90313bb:/# cat /tmp/u3/file_from_host.txt
hello host
建好之后,习惯性地docker ps看一眼容器是否真的起来了
进入容器,由于没有用ro参数,容器里可以正常地读写/tmp/u3目录
再主机外面也可以正常地读写这个目录,并且可以看到数据是共享的
容器卷的继承
[root@WIND u3]# docker run -it --privileged=true --volumes-from u3 --name u4 ubuntu
root@e9f97537fd82:/#
root@e9f97537fd82:/# ls /tmp/u3/
file_from_ file_from_host.txt file_from_u3.txt
root@e9f97537fd82:/#
root@e9f97537fd82:/# touch /tmp/u3/file_from_u4.txt
root@e9f97537fd82:/# echo "hello u4" >> /tmp/u3/file_from_u4.txt
[root@WIND u3]# ls /tmp/u3/
file_from_ file_from_host.txt file_from_u3.txt file_from_u4.txt
[root@WIND u3]#
[root@WIND u3]#
[root@WIND u3]# cat /tmp/u3/file_from_u4.txt
hello u4
[root@WIND u3]# docker exec -it u3 /bin/bash
root@b9abd90313bb:/# ls /tmp/u3/
file_from_ file_from_host.txt file_from_u3.txt file_from_u4.txt
root@b9abd90313bb:/#
root@b9abd90313bb:/# cat /tmp/u3/file_from_u4.txt
hello u4
运行一个容器u4,–volumes-from参数,从u3 继承容器卷
登录u4,直接就可以看到u3卷里的内容了,并且可以正常地读写继承的容器卷
再回到主机,也可以看到u4新写入的内容
登录u3,一样可以看到u4新写入的内容
继承的容器卷是共享的
[root@WIND u3]# docker stop u3
u3
[root@WIND u3]# docker exec -it u4 /bin/bash
root@e9f97537fd82:/# touch /tmp/u3/file_from_u4_02.txt
root@e9f97537fd82:/# echo "u4 02" >> /tmp/u3/file_from_u4_02.txt
root@e9f97537fd82:/#
root@e9f97537fd82:/# exit
exit
[root@WIND u3]# docker start u3
u3
[root@WIND u3]# docker exec -it u3 bash
root@b9abd90313bb:/# ls /tmp/u3/
file_from_ file_from_host.txt file_from_u3.txt file_from_u4.txt file_from_u4_02.txt
root@b9abd90313bb:/#
root@b9abd90313bb:/#
root@b9abd90313bb:/# cat /tmp/u3/file_from_u4_02.txt
u4 02
root@b9abd90313bb:/#
上面的代码,停了u3,登录容器卷在继承的卷里读写,再重新启动u3,原来的内容和新增的内容都在
u4 是继承u3的卷,也就是u3是父亲,父亲停了之后,去操作u4,啥时候想用u3了,在启动,数据依然在
这就是继承的好处