本篇文章給大家?guī)砹岁P于docker中數(shù)據(jù)卷管理和convoy卷插件的相關知識,希望對大家有幫助。
1.什么是Docker數(shù)據(jù)卷
-
數(shù)據(jù)卷是一個或多個容器中專門指定的目錄,它能夠繞過聯(lián)合文件系統(tǒng)。
卷被設計用作數(shù)據(jù)持久化、并且是獨立于容器的生命周期的。 -
因此,Docker不會在刪除容器時自動刪除數(shù)據(jù)卷卷,也不會主動“垃圾回收”掉容器不再使用的卷。
-
數(shù)據(jù)卷的存在就是想讓的容器的數(shù)據(jù)持久化存在,而且可以實現(xiàn)容器之間的數(shù)據(jù)共享。
-
通俗地來說,docker容器數(shù)據(jù)卷可以看成使我們生活中常用的u盤,它存在于一個或多個的容器中,由docker掛載到容器,但不屬于聯(lián)合文件系統(tǒng),Docker不會在容器刪除時刪除其掛載的數(shù)據(jù)卷。
2.為什么要用數(shù)據(jù)卷
docker分層文件系統(tǒng):
- 性能差
- 生命周期與容器相同
docker數(shù)據(jù)卷:
- mount到主機中,繞開分層文件系統(tǒng)
- 和主機磁盤性能相同,容器刪除后依然保留
- 僅限本地磁盤,不能隨容器遷移
3.docker數(shù)據(jù)卷提供兩種卷
bind mount
是將主機上的目錄或文件mount到容器里
- 使用直觀高效,易于理解。
- 使用 -v 選項指定路徑,格式 :
- bind mount 默認權限是讀寫rw,可以在掛載時指定只讀ro。
- -v選項指定的路徑,如果不存在,掛載時會自動創(chuàng)建。
docker managed volume
bind mount必須指定host文件系統(tǒng)路徑,限制了移植性。
docker managed volume 不需要指定mount源
bind mount 和docker managed volume對比
相同點:兩者都是host文件系統(tǒng)中的某個路徑
不同點:
4.bind mount應用
docker network prune docker network ls docker run -d --name vm1 -v /opt/website:/usr/share/nginx/html nginx docker ps
docker inspect vm1 #查看到ip為172.17.0.2 curl 172.17.0.2
發(fā)現(xiàn)是403頁面:
cd /opt/website/ ls #發(fā)現(xiàn)沒有默認發(fā)布頁面 echo www.westos.org > index.html curl 172.17.0.2
此時訪問nginx,就有www.westos.org內(nèi)容了:
掛載時還可以指定權限:
docker run -it --rm -v /opt/website:/data1 -v /etc/passwd:/data2/passwd:ro busybox
可以看到默認權限為rw讀寫,所以我們可以更改index.html的內(nèi)容;而指定passwd為只讀后,我們就無法修改其內(nèi)容,只能讀
5.docker managed volume
查看現(xiàn)有的管理卷:
docker volume ls
我們有些是時候在刪除了容器后會有殘存的管理卷存在,這是我們就需要去清理它,不然會占用我們的資源:
docker volume prune docker volume ls
docker run -d --name registry registry cd /var/lib/docker/volumes/ ls docker history registry:latest
通過docker volume可以將容器內(nèi)的內(nèi)容復制到掛載點:
docker run -d --name vm2 -v /usr/share/nginx/html nginx cd /var/lib/docker/volumes/ ls cd 674c999f99b7b524d8f5769b65cb5411d11e3fa855da695a5fdd3494e4342d89/ cd _data/ ls #查看到默認發(fā)布目錄被復制到了這里
docker inspect vm2 curl 172.17.0.3 #nginx默認發(fā)布頁
echo hello docker! > index.html curl 172.17.0.3 #可以直接在掛載的目錄修改默認發(fā)布頁
6.docker卷插件簡介
docker卷默認使用的是local類型的驅(qū)動,只能存在宿主機,
跨主機的volume就需要使用第三方的驅(qū)動,可以查看鏈接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
Docker Plugin 是以Web Service的服務運行在每一臺Docker Host上的,通過HTTP協(xié)議傳輸RPC風格的JSON數(shù)據(jù)完成通信。Plugin的啟動和停止,并不歸Docker管理,Docker Daemon依靠在缺省路徑下查找Unix Socket文件,自動發(fā)現(xiàn)可用的插件。
當客戶端與Daemon交互,使用插件創(chuàng)建數(shù)據(jù)卷時,Daemon會在后端找到插件對應的 socket 文件,建立連接并發(fā)起相應的API請求,最終結(jié)合Daemon自身的處理完成客戶端的請求。
7.convoy卷插件
convoy卷插件支持三種運行方式:devicemapper、NFS、EBS。下面的實驗以nfs的運行方式來演示
實驗目的:在server1和2底層用nfs來實現(xiàn)數(shù)據(jù)共享
step1 首先在server1和server2上搭建nfs文件系統(tǒng):
server1:
yum install -y nfs-utils systemctl start rpcbind mkdir /nfs #創(chuàng)建共享目錄 chmod 777 /nfs #修改共享目錄權限 vim /etc/exports #編輯共享目錄文件,否則將不會被共享出去 /nfs *(rw,no_root_squash) systemctl start nfs
注意:rpcbind服務必須是開啟的。這是因為:他是一個RPC服務,主要是在nfs共享時候負責通知客戶端,服務器的nfs端口號的。簡單理解rpc就是一個中介服務。
server2:
yum install -y nfs-utils systemctl start nfs-server.service showmount -e server1 #尋找server1的掛載目錄 mkdir /nfs mount server1:/nfs /nfs df
測試:
在server2中:
cd /nfs/ touch file
在server1中:
cd /nfs/ ls #查看到file
說明兩個節(jié)點的/nfs實現(xiàn)同步了
step2 配置convoy環(huán)境:
docker官方只提供了卷插件的api,開發(fā)者可以根據(jù)實際需求定制卷插件驅(qū)動。
在server1中:
tar zxf convoy.tar.gz cd convoy/ cp convoy* /usr/local/bin/ #將二進制文件加入到PATH路徑 mkdir /etc/docker/plugins #創(chuàng)建docker的插件目錄 convoy daemon --drivers vfs --driver-opts vfs.path=/nfs &> /dev/null & cd /nfs ls
注意:第一次運行上面的convoy daemon命令的時候,會在/nfs目錄下生成一個config文件夾,這個文件夾不要刪除,不然客戶端的convoy命令就會用不了
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec #將convoy守護進程開啟生成的.sock文件放入/etc/docker/plugins目錄下的convoy.spec文件中,docker就可以識別。(其中convoy.spec文件之前是不存在的) cat /etc/docker/plugins/convoy.spec
在server2中同樣配置convoy環(huán)境:
scp -r server1:convoy . cd convoy/ cp convoy* /usr/local/bin/ #將二進制文件加入到PATH路徑 mkdir /etc/docker/plugins #創(chuàng)建docker的插件目錄 echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec convoy daemon --drivers vfs --driver-opts vfs.path=/nfs &> /dev/null & cd /nfs ls
step3 創(chuàng)建卷:
docker volume ls convoy create vol1
step4 操作卷:
在server2中運行容器,指定卷為剛才新創(chuàng)建的vol1:
docker run -it --name vm1 -v vol1:/usr/share/nginx/html nginx docker ps docker inspect vm1 curl 172.17.0.2 #nginx默認發(fā)布頁
cd /nfs/ cd vol1/ echo hello convoy > index.html curl 172.17.0.2
在server1中數(shù)據(jù)也同步了:
cd /nfs/ cd vol1/ cat index.html
在ser1中也可以運行容器,也可以用到共享的數(shù)據(jù)卷
說明:docker引擎默認掃描 /etc/docker/plugins目錄中的convoy.spec—>訪問/run/convoy/convoy.sock文件—>發(fā)起響應的api請求—>把數(shù)據(jù)寫入vol1中—>底層通過nfs進行主機間的數(shù)據(jù)同步
如何刪除通過nfs創(chuàng)建的數(shù)據(jù)卷,讓之后創(chuàng)建的數(shù)據(jù)卷都是本地的呢?
刪除卷:
convoy delete vol1
實現(xiàn)本地驅(qū)動:
cd /etc/docker/plugins/ mv convoy.spec /mnt systemctl restart docker
創(chuàng)建卷:
docker volume create vol1 ls cd volumes/ ls #可以看到vol1,默認創(chuàng)建在這個目錄下 cd vol1/ ls cd _data/ ls #進入該目錄,是空的
使用卷:
docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx docker ps ls #看到nginx默認發(fā)布目錄被掛到這里了
補充幾條命令:
docker container prune #刪除停止的容器 docker volume prune #刪除沒有被使用的卷
推薦學習:《docker視頻教程》