(三)Docker数据存储卷

版权声明:本文为博主原创文章,转载请指明地址。 https://blog.csdn.net/Mr_rsq/article/details/84840211

1 Docker数据卷

前言:

  • Docker镜像是由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。
  • 如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制。
  • 关闭并重启容器,其数据不受影响;但删除Docker容器,则其更改将会全部丢失。

存在的问题:

  1. 存储于联合文件系统中,不易于宿主机访问;
  2. 容器间数据共享不方便。
  3. 删除容器其数据会丢失
  • “卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某目录“绑定(关联)”
  • “卷”的初衷是独立于容器的生命周期实现数据持久化。因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作。

Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但其在宿主机上的位置有所不同。
1. Docker管理卷
docker run -it -v HOSTDIR:VOLUMEDIR --name bbox2 busybox
docker inspect -f {{.Mounts}} bbox2

2. 绑定挂载卷
docker run -it -name bbox1 -v /data busybox
docker inspect -f {{.Mounts}} bbox1

1.1 Docker管理的卷

需要打开两个终端来测试,终端1

[root@docker-node1 ~]# docker run --name b2 -it -v /data busybox:latest
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # ls -l data
total 0

切换终端2,找到mounts对应的目录

[root@docker-node1 ~]# docker inspect b2
......
        "Mounts": [
            {
                "Type": "volume",
                "Name": "ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c", 	#<==UUID名称
                "Source": "/var/lib/docker/volumes/ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c/_data",		#<==这个是宿主机目录
                "Destination": "/data",	#<==这个是容器内的目录
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......
[root@docker-node1 ~]# cd /var/lib/docker/volumes/ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c/_data/
[root@docker-node1 _data]# touch index.html

切换终端1

/ # ls -l data
total 0
-rw-r--r--    1 root     root             0 Nov 14 08:30 index.html
/ # echo "hello world" >data/index.html 
/ # cat data/index.html 
hello world

切换终端2

[root@docker-node1 _data]# cat index.html 
hello world

1.2 绑定挂载卷(共享卷)

终端1

[root@docker-node1 ~]# docker run --name b2 -it --rm -v /data/volumes/b2:/data busybox:latest
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var

切换到终端2

[root@docker-node1 ~]# docker inspect b2
......
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/volumes/b2",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
......
[root@docker-node1 ~]# ll /data/volumes/b2/   # 宿主机会自动创建
total 0
[root@docker-node1 ~]# cd /data/volumes/b2/
[root@docker-node1 b2]# echo "busybox" >test.txt
[root@docker-node1 b2]# cat test.txt
busybox

切换到终端1

/ # cd data/
/data # ls
test.txt
/data # cat test.txt 
busybox

这种支持持久化
退出b2,然后重新创建b2,这次换个容器目录

[root@docker-node1 ~]# docker run --name b2 -it --rm -v /data/volumes/b2:/data/web/html busybox:latest
/ # cat /data/web/html/test.txt 
busybox

Tips:快速查找定位信息

[root@docker-node1 ~]# docker inspect -f {{.Mounts}} b2
[{bind  /data/volumes/b2 /data/web/html   true rprivate}]
[root@docker-node1 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} b2
172.17.0.2
[root@docker-node1 ~]# docker inspect --help

Usage:	docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Return low-level information on Docker objects

Options:
  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type

使不同容器共享宿主机同一个卷
再创建一个容器,绑定和b2同一个的卷

[root@docker-node1 ~]# docker run --name b3 -it --rm -v /data/volumes/b2/:/data/ busybox:latest
/ # ls /data/
test.txt
/ # echo "This is b3 Container" >> /data/test.txt 
/ # cat /data/test.txt 
busybox
This is b3 Container

切换到b2查看

/ # cat /data/web/html/test.txt 
busybox
This is b3 Container

docker支持复制别的容器的存储卷

  • 可以创建一个模板,专供别的容器来复制存储卷的位置或网络等信息

多个容器的卷使用同一个主机目录,如

docker run -it --name c1 -v /dacker/volumes/v1:/data busybox
docker run -it --name c2 -v /dacker/volumes/v2:/data busybox

复制使用其它容器的卷,为docker run命令使用–volumes-from选项

docker run -it --name bbox1 -v /docker/volumes/v1:/data busybox
docker run -it --name bbox2 --volumes-from bbox1 busybox

终端1,开启一个模板容器

[root@docker-node1 ~]# docker run --name infracon -it -v /data/infracon/volume/:/data/web/html busybox
/ #

终端2,创建一个新容器,复制模板的volume,若使用–network则会把模板的网络也复制过来

[root@docker-node1 ~]# docker run --name nginx --network container:infracon --volumes-from infracon -it busybox
/ #

终端3,查看两个容器的inspect信息

[root@docker-node1 ~]# docker inspect infracon
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/infracon/volume",
                "Destination": "/data/web/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
                    "IPAddress": "172.17.0.2",
[root@docker-node1 ~]# docker inspect nginx
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/infracon/volume",
                "Destination": "/data/web/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
            "IPAddress": "",

可以发现复制volume的容器nginx inspect不能查到IP地址,但显示不出来并不是没有IP地址,去nginx容器上查看IP地址

/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

END!

猜你喜欢

转载自blog.csdn.net/Mr_rsq/article/details/84840211