Docker鏡像由多個(gè)只讀層疊加而成,啟動(dòng)容器時(shí),Docker會(huì)加載只讀鏡像層并在鏡像棧頂部添加一個(gè)讀寫(xiě)層。
如果運(yùn)行中的容器修改了現(xiàn)有的一個(gè)已經(jīng)存在的文件,那該文件將會(huì)從讀寫(xiě)層下面的只讀層復(fù)制到讀寫(xiě)層,該文件的只讀版本仍然存在,只是已經(jīng)被讀寫(xiě)層中該文件的副本所隱藏,這個(gè)就是寫(xiě)時(shí)復(fù)制(COW)機(jī)制。
創(chuàng)新互聯(lián)公司是一家從事企業(yè)網(wǎng)站建設(shè)、成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、行業(yè)門(mén)戶網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)制作的專業(yè)網(wǎng)絡(luò)公司,擁有經(jīng)驗(yàn)豐富的網(wǎng)站建設(shè)工程師和網(wǎng)頁(yè)設(shè)計(jì)人員,具備各種規(guī)模與類型網(wǎng)站建設(shè)的實(shí)力,在網(wǎng)站建設(shè)領(lǐng)域樹(shù)立了自己獨(dú)特的設(shè)計(jì)風(fēng)格。自公司成立以來(lái)曾獨(dú)立設(shè)計(jì)制作的站點(diǎn)上1000家。
Docker 容器數(shù)據(jù)的存儲(chǔ),存在以下問(wèn)題:
關(guān)閉并重啟容器,容器的數(shù)據(jù)不受影響。但刪除容器會(huì)是之前的更改全部丟失。
解決方案:卷(volume),或者便于區(qū)分叫做存儲(chǔ)卷。
卷是容器上的一個(gè)或多個(gè)目錄,此類目錄可繞過(guò)聯(lián)合文件系統(tǒng),與宿主機(jī)上的某個(gè)目錄綁定(關(guān)聯(lián))。
Volume在容器初始化之時(shí)就會(huì)創(chuàng)建,由base image提供的卷中的數(shù)據(jù)會(huì)于此期間完成復(fù)制。
Volumn的初衷就是獨(dú)立于容器的生命周期實(shí)現(xiàn)數(shù)據(jù)持久化,因此刪除容器之時(shí)既不會(huì)刪除卷,也不會(huì)對(duì)哪怕未被引用的卷做垃圾回收操作。
卷為docker提供了獨(dú)立于容器的數(shù)據(jù)管理機(jī)制:
現(xiàn)在,在創(chuàng)建容器時(shí),加上volumes的相關(guān)選項(xiàng)。
Docker有兩種類型的卷,每種類型都在容器中存在一個(gè)掛載點(diǎn),但是在宿主機(jī)上的位置有所不同:
為docker run命令使用-v選項(xiàng),即可使用Volume。
開(kāi)一個(gè)會(huì)話創(chuàng)建容器并綁定volume:
$ docker run --name v1 --rm -it -v /data busybox
在宿主機(jī)上操作目錄
在另一個(gè)會(huì)話中查詢這個(gè)容器的inspect,不過(guò)內(nèi)容比較多。在Volumes里能看到卷的信息:
"Volumes": {
"/data": {}
},
還有掛載點(diǎn)的信息,這里使用-f參數(shù)只看Mounts的內(nèi)容:
$ docker inspect -f '{{json .Mounts}}' v1
[{"Type":"volume","Name":"bdd48fb729e802b7d3a067da74b748037e83ff770a84f7215c657f6cc2af2c9d","Source":"/var/lib/docker/volumes/bdd48fb729e802b7d3a067da74b748037e83ff770a84f7215c657f6cc2af2c9d/_data","Destination":"/data","Driver":"local","Mode":"","RW":true,"Propagation":""}]
$
宿主機(jī)自動(dòng)分配的卷的路徑在Source字段中,下面的方法直接獲取路徑并調(diào)用ls命令:
$ docker inspect -f '{{range .Mounts}}{{.Source}} {{end}}' v1 | xargs ls
$ docker inspect -f '{{with index .Mounts 0}}{{.Source}}{{end}}' v1 | xargs ls
Mounts里是一個(gè)數(shù)組,可能有多個(gè)掛載點(diǎn)。第一行的命令是遍歷所有的目錄,第二行的命令是只輸出第一個(gè)目錄。
在掛載點(diǎn)的目錄中,容器和宿主機(jī)可以共享數(shù)據(jù)。容器中對(duì)目錄的修改,在宿主機(jī)中可以查看到。反之,在宿主機(jī)中對(duì)這個(gè)目錄的修改,容器也能夠查看到。
刪除鏡像
上面創(chuàng)建容器的命令使用了--rm參數(shù),這樣一旦容器停止,該容器也就會(huì)自動(dòng)被刪除。容器刪除后,Docker-managed volume也會(huì)一并被刪除。
所以這是一個(gè)臨時(shí)的卷,卷內(nèi)存儲(chǔ)的數(shù)據(jù)依然會(huì)隨著容器的刪除而丟失。沒(méi)有解決容器內(nèi)數(shù)據(jù)持久保存的目的,但是現(xiàn)在容器的數(shù)據(jù)可以和宿主機(jī)共享,并且數(shù)據(jù)存儲(chǔ)的I/O也直接是由宿主機(jī)的文件系統(tǒng)決定。好處是用戶不用額外來(lái)管理這個(gè)卷,卷內(nèi)存放的臨時(shí)數(shù)據(jù)會(huì)隨著容器的刪除而刪除。適合用于存放臨時(shí)性的但是需要在容器外的共享的數(shù)據(jù)。
使用的參數(shù)還是和之前一樣,但是-v參數(shù)的內(nèi)容提供兩部分,宿主機(jī)的目錄和卷的目錄,中間用冒號(hào)分隔:-v HOSTDIR:VOLUMEDIR
。
綁定 Bind-mount Volme
開(kāi)一個(gè)會(huì)話創(chuàng)建容器并綁定Bind-mount Volme:
$ docker run --name v2 --rm -it -v ~/data/volumes/v2:/data busybox
仍然可以使用docker inspect命令來(lái)查看詳細(xì)信息,這里就不演示了。
這里指定的宿主機(jī)的路徑如果不存在,docker會(huì)自動(dòng)創(chuàng)建。
刪除容器
容器刪除后,宿主機(jī)上的文件會(huì)依然存在。這樣就實(shí)現(xiàn)了數(shù)據(jù)在容器刪除后依然可以使用。
前面說(shuō)了,docker有兩種類型的卷,兩種都已經(jīng)說(shuō)了。這里的共享卷本質(zhì)上還是上面兩種類型中的某一種,只是是實(shí)現(xiàn)了容器間共享同一個(gè)卷的兩種方法。
多個(gè)容器卷使用同一個(gè)主機(jī)目錄
這個(gè)沒(méi)什么問(wèn)題,主機(jī)上同一個(gè)目錄是允許被多個(gè)容器同時(shí)使用的。
復(fù)制使用其他容器的卷
使用--volumes-from選項(xiàng):
$ docker run --name v3.0 --rm -itd -v /data busybox
e24397fffb44717a7f140010c829ec88f540ed7d95f7c8fb328a35a819becfb0
$ docker run --name v3.1 --rm -itd --volumes-from v3.0 busybox
28543eb6fc13e972a000ab955b9623630ebb9d90c8d3dc37a8b7608f24188926
$ docker container attach v3.0
/ # touch /data/test_v3_0
/ # exit
$ docker container attach v3.1
/ # ls /data
test_v3_0
/ # exit
$
這里的示例復(fù)制的是Docker-managed volume,對(duì)于Bind-mount Volme也是一樣的。
共享網(wǎng)絡(luò)
網(wǎng)絡(luò)也可以共享,即聯(lián)盟式網(wǎng)絡(luò)。這里,卷也可以共享。在有些場(chǎng)景下,兩個(gè)或幾個(gè)容器有可能需要共享同一個(gè)網(wǎng)絡(luò)并且共享同一個(gè)卷。