1. 程式人生 > >(三)Docker資料儲存卷

(三)Docker資料儲存卷

文章目錄

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

[[email protected] ~]# 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對應的目錄

[[email protected] ~]# docker inspect b2
......
        "Mounts": [
            {
                "Type": "volume",
                "Name": "ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c", 	#<==UUID名稱
                "Source": "/var/lib/docker/volumes/ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c/_data",		#<==這個是宿主機目錄
                "Destination": "/data",	#<==這個是容器內的目錄
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......
[[email protected] ~]# cd /var/lib/docker/volumes/ec54c347d920dcc7183d7e6b4235c086b603bab2c58146472e187ad6d6bd126c/_data/
[[email protected] _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

[[email protected] _data]# cat index.html 
hello world

1.2 繫結掛載卷(共享卷)

終端1

[[email protected] ~]# 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

[[email protected] ~]# docker inspect b2
......
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/volumes/b2",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
......
[[email protected] ~]# ll /data/volumes/b2/   # 宿主機會自動建立
total 0
[[email protected] ~]# cd /data/volumes/b2/
[[email protected] b2]# echo "busybox" >test.txt
[[email protected] b2]# cat test.txt
busybox

切換到終端1

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

這種支援持久化
退出b2,然後重新建立b2,這次換個容器目錄

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

Tips:快速查詢定位資訊

[[email protected] ~]# docker inspect -f {{.Mounts}} b2
[{bind  /data/volumes/b2 /data/web/html   true rprivate}]
[[email protected] ~]# docker inspect -f {{.NetworkSettings.IPAddress}} b2
172.17.0.2
[[email protected] ~]# 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同一個的卷

[[email protected] ~]# 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,開啟一個模板容器

[[email protected] ~]# docker run --name infracon -it -v /data/infracon/volume/:/data/web/html busybox
/ #

終端2,建立一個新容器,複製模板的volume,若使用–network則會把模板的網路也複製過來

[[email protected] ~]# docker run --name nginx --network container:infracon --volumes-from infracon -it busybox
/ #

終端3,檢視兩個容器的inspect資訊

[[email protected] ~]# docker inspect infracon
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/infracon/volume",
                "Destination": "/data/web/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
                    "IPAddress": "172.17.0.2",
[[email protected] ~]# 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: [email protected]: <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!