docker(三)--存儲卷
為什么需要存儲卷?
- Docker鏡像由多個只讀層疊加而成,啟動容器時,docker會加載只讀鏡像并在鏡像棧頂部添加一個讀寫層。
- 如果運行的容器修改了一個已有的文件,那么該文件會從只讀層復制到讀寫層,該文件的只讀版本依然存在,只是已經被讀寫層中該文件的副本所隱藏,即“寫時復制 COW”機制。
存在的問題
存儲于聯合文件系統中,不易于宿主機訪問;
容器間數據共享不便;
刪除容器其數據會丟失
存儲卷 volume
“卷”是容器上的一個或多個“目錄”,此類目錄可繞過聯合文件系統,與宿主機上的某個目錄“綁定(關聯)”;
類似于掛載一樣,宿主機 /data/web目錄與容器中的/container/data/web目錄建立綁定關系,然后容器中的進程向這個目錄中寫數據時,是直接寫在宿主機的目錄上的,繞過容器文件系統與宿主機的文件系統建立關聯關系, 宿主機和容器內可以共享數據庫內容,讓容器直接訪問宿主機中的內容,宿主機也可以訪問容器內容,兩者是同步的。即使容器被刪除,數據也不會丟失。
數據卷的最大特點是:其生存周期獨立于容器的生存周期
- volume于容器初始化之時會創建,由base image提供的卷中的數據會于此期間完成復制
- volume的初衷是獨立于容器的生命周期實現數據持久化,因此刪除容器之時既不會刪除卷,也不會對哪怕未被引用的卷做垃圾回收操作
- 卷為docker提供了獨立于容器的數據管理機制
Docker卷類型
Docker存儲卷有兩種類型,每種類型都在容器中存在一個掛載點,但其在宿主機上位置有所不同
第一種:綁定掛載卷: 在宿主機上的路徑需要人工指定,在容器中的路徑也需要指定,兩個已知的路徑建立關聯關系。
第二種:docker管理卷: 只需要指定容器的掛載點,而被綁定宿主機下的那個目錄,是由容器引擎daemon自行創建一個空的目錄,或者使用一個已經存在的目錄,與存儲卷建立存儲關系,這種方式極大解脫用戶在使用卷時的耦合關系,缺陷是用戶無法指定那些使用目錄,臨時存儲比較適合
在容器中使用volumes
1.docker管理卷
在一個終端運行容器:
docker run -it --name vbox1 -v /data busybox
/ # touch /data/test
另一個終端查看:
docker inspect vbox1 #查看容器詳細信息
"Mounts": [
{"Type": "volume",
"Name": "257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3",
"Source": "/var/lib/docker/volumes/257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3/_data",
"Destination": "/data",
# cd /var/lib/docker/volumes/257ff9d7f0822606560fc21f8bd63b784cd2db72e410c8634ef361df3f5157b3/_data
# ls
test
# echo "hello" > a.txt #在容器中也可看到
2.綁定掛載卷
docker run -it --rm --name vbox2 -v /host/volumes/b2:/data busybox
docker inspect vbox2
"Mounts": [
{"Type": "bind",
"Source": "/host/volumes/b2",
"Destination": "/data",
在宿主機/host/volumes/b2 做的操作和容器內/data的操作會同步。下次啟動容器綁定掛在此卷時,文件依然存在。
使用golang模板查看
docker inspect -f {{.Mounts}} vbox2
[{bind /host/volumes/b2 /data1 true rprivate}]
docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} vbox2
172.17.0.5
多個容器共享同一個存儲卷
可以讓兩個docker容器同時關聯到同一個宿主機的目錄中,實現共享使用同一個存儲卷,容器之間的數據共享
docker run -it --rm --name vbox3 -v /host/volumes/b2:/data3 busybox
# ls /data3
docker run -it --rm --name vbox2 -v /host/volumes/b2:/data2 busybox
# ls /data2
復制存儲卷 --volumes-from
當需要多個容器同進使用多個卷,卷在那里寫每次初始化時都要使用-v來指定,如果不想記錄這個路徑,docker還支持復制其他的存儲卷路徑
制定一個容器,不執行任何任務,創建時,只要指定它的存儲路徑,作為其他容器的基礎容器,其他的容器啟動時去復制它的存儲卷設置,但是這樣的點浪費,不過使用joined container的基礎的話,幾個容器本來就有密切的關系,如nginx+tomcat,nginx的容器和tomcat容器共享一個底層的網絡,有一個對外的接口,有一個loop接口,這樣80給nginx,在內loop給tomcat,請求進來,nginx作為反射代理轉給tomcat就可以了,再加一個mysql,即可實現一個NMT架構。 讓它們共享名稱空間中的uts,net,ipc, 還可以共享存儲卷,ngInx處理靜態,tomcat處理動態的,在同一個目錄下,使用存儲卷來解決這個問題,這種組織方式使用構建應用。
nginx tomcat mysql
共享uts,net,ipc
共享volume
docker run -it --rm --name vbox4 --volumes-from vbox2 busybox
\ # ls data1/
b.txt vbox2 vbox3
制定基礎鏡像(網上有專門制作基礎架構容器的,不用啟動,只要創建就可以了)
# docker run --name infracon -it --rm -v /data/basic/volume/:/data/web/html busybox
# docker run --name nginx --network container:infracon --volumes-from infracon -it busybox #加入網絡名稱空間,同時復制卷

浙公網安備 33010602011771號