前言、Docker中的數(shù)據(jù)管理
Docker鏡像是由多個只讀層疊加而成翘紊,啟動容器時蔽氨,Docker會加載只讀層并會在鏡像棧頂部添加一個讀寫層,如果運(yùn)行中的容器修改了現(xiàn)有的一個文件帆疟,那么該文件就會從只讀層復(fù)制一份到讀寫層中鹉究,該文件的只讀版本仍然存在,只是已經(jīng)被讀寫層中該文件的副本所隱藏踪宠,這就是docker的寫時復(fù)制機(jī)制自赔。關(guān)閉重啟容器,其數(shù)據(jù)不受影響柳琢,但是刪除容器時绍妨,其改變的讀寫層數(shù)據(jù)就會丟失。
容器在運(yùn)行項(xiàng)目時會產(chǎn)生數(shù)據(jù)染厅,比如運(yùn)行的mysql容器痘绎,那么一定會有數(shù)據(jù)的產(chǎn)生,那么問題來了肖粮,數(shù)據(jù)是保存在容器內(nèi)部還是保存在外部孤页?如果將數(shù)據(jù)保存在內(nèi)部,那么也就意味著我們改變了原有鏡像涩馆,這種做法是不可取的行施,因?yàn)樵诤笃诘溺R像升級將變得不可能了。除非我們在改變鏡像后commit提交打成一個新的鏡像魂那。顯然蛾号,數(shù)據(jù)是應(yīng)該保存在容器的外部,也就是說保存在主機(jī)上涯雅。那么問題又來了鲜结,數(shù)據(jù)保存在主機(jī)上,那么容器該如何讀取主機(jī)中的數(shù)據(jù)呢?
為了能夠持久化數(shù)據(jù)以及共享容器間的數(shù)據(jù)精刷,Docker提出了Volume的概念拗胜。簡單來說,Volume就是目錄或者文件怒允,它可以繞過默認(rèn)的聯(lián)合文件系統(tǒng)埂软,而以正常的文件或者目錄的形式存在于宿主機(jī)上。
容器中管理數(shù)據(jù)主要有兩種方式:
- 數(shù)據(jù)卷(Data volumes):容器內(nèi)數(shù)據(jù)直接映射到本地主機(jī)環(huán)境
- 數(shù)據(jù)卷容器(Data Volume Containers):使用特定容器維護(hù)數(shù)據(jù)卷纫事,數(shù)據(jù)卷容器掛載數(shù)據(jù)卷勘畔,其他容器通過掛載數(shù)據(jù)卷容器實(shí)現(xiàn)數(shù)據(jù)傳遞共享
一、數(shù)據(jù)卷的概念
數(shù)據(jù)卷就是由docker掛載到容器中的目錄或者文件丽惶,但是不屬于UnionFS炫七。數(shù)據(jù)卷的生命周期完全獨(dú)立于容器,docker不會在容器被刪除時而刪除其掛載的數(shù)據(jù)卷蚊夫,因此可以實(shí)現(xiàn)持久化或共享數(shù)據(jù)诉字。
特點(diǎn):
- 數(shù)據(jù)卷可以在不同容器之間共享或重用數(shù)據(jù)
- 數(shù)據(jù)卷中的更改直接生效
- 數(shù)據(jù)卷中的更改不會包含在鏡像的更新之中
1-1、創(chuàng)建容器時添加數(shù)據(jù)卷
數(shù)據(jù)卷是一個可供容器使用的特殊目錄知纷,它將主機(jī)操作系統(tǒng)目錄直接映射進(jìn)容器,類似于linux中的mount操作陵霉。在create或者run容器時琅轧,可以通過-v參數(shù)指定主機(jī)的目錄,掛載到容器中的某一個目錄上踊挠,這樣乍桂,容器就在這個目錄讀寫數(shù)據(jù)了。從而實(shí)現(xiàn)了容器和數(shù)據(jù)的分離效床。例如:
docker run --name 容器名 -v /宿主機(jī)絕對路徑:/容器內(nèi)路徑 鏡像名
docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
二睹酌、Docker實(shí)戰(zhàn)案例五:Docker安裝MySQL實(shí)現(xiàn)宿主機(jī)和容器之間的數(shù)據(jù)共享
2-1、查找鏡像
docker search mysql
2-2剩檀、拉取鏡像
docker pull mysql
默認(rèn)拉取tag為latest的mysql官方鏡像
latest: Pulling from library/mysql
683abbb4ea60: Pull complete
0550d17aeefa: Pull complete
7e26605ddd77: Pull complete
9882737bd15f: Pull complete
999c06ab75f6: Pull complete
c71d695f9937: Pull complete
c38f847c1491: Pull complete
5e0cb05a8fc3: Pull complete
c89e3e373fca: Pull complete
fa39a2c9922d: Pull complete
b293d9c897c4: Pull complete
3dc061869740: Pull complete
Digest: sha256:43ed4f8c9d1695e97a39cdfe9475af9096e3723cfb79d820d8da00d61a277a85
Status: Downloaded newer image for mysql:latest
2-3憋沿、創(chuàng)建容器
新建本地映射到docker鏡像的mysql文件目錄,/mysql/conf沪猴、/mysql/logs辐啄、/mysql/data。
使用如下命令將提前創(chuàng)建好的/mysql/conf运嗜、/mysql/logs壶辜、/mysql/data掛載到容器中MySQL對應(yīng)的目錄中:
docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
2-4、查看并驗(yàn)證
查看MySQL容器是否正常運(yùn)行:
進(jìn)入容器內(nèi)部并進(jìn)入MySQL:
三担租、數(shù)據(jù)卷容器
如果用戶需要在多個容器之間共享一些持續(xù)更新的數(shù)據(jù)砸民,最簡單的方式是使用數(shù)據(jù)卷容器。數(shù)據(jù)卷容器也是一個容器,但是它的目的是專門用來提供數(shù)據(jù)卷供其他容器掛載岭参。如果要授權(quán)一個容器訪問另一個容器的Volume便贵,我們可以使用--volumes-from參數(shù)來實(shí)現(xiàn)∪咻可以使用數(shù)據(jù)卷容器對其中的數(shù)據(jù)卷進(jìn)行備份承璃、恢復(fù)、以實(shí)現(xiàn)數(shù)據(jù)的遷移蚌本。
首先創(chuàng)建一個數(shù)據(jù)卷容器dbdata,并在其中創(chuàng)建一個數(shù)據(jù)卷掛載到/dbdata盔粹。
//創(chuàng)建一個數(shù)據(jù)卷容器
[root@xxx ~]# docker run -it -v /dbdata --name dbdata ubuntu
//查看目錄
root@d4bb57243d45:/# ls
bin boot dbdata dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
然后,可以在其他容器中使用--volumes-from來掛載dbdata容器中的數(shù)據(jù)卷程癌,例如創(chuàng)建db1和db2兩個容器舷嗡,并從dbdata容器掛載數(shù)據(jù)卷:
// 創(chuàng)建2個容器掛載dbdata容器中的數(shù)據(jù)卷
[root@xxx ~]# docker run -it --volumes-from dbdata --name db1 ubuntu
[root@xxx ~]# docker run -it --volumes-from dbdata --name db2 ubuntu
此時,容器db1和容器db2都掛載同一個數(shù)據(jù)卷到相同的dbdata目錄嵌莉。三個容器任何一方在該目錄下的寫入进萄,其他容器都可以看到。例如锐峭,在dbdata容器中創(chuàng)建一個test文件,在db1容器中可能查看到它:
//在dbdata容器的數(shù)據(jù)卷中創(chuàng)建文件a
root@9e90f695bcb8:/dbdata# touch a
root@9e90f695bcb8:/dbdata# ll
total 4
drwxr-xr-x. 2 root root 14 Apr 14 10:02 ./
drwxr-xr-x. 22 root root 4096 Apr 14 10:01 ../
-rw-r--r--. 1 root root 0 Apr 14 10:02 a
//在db1容器中查看數(shù)據(jù)卷目錄dbdata中鼠,也發(fā)現(xiàn)了文件a
root@ab4426a23cb4:/dbdata# ll
total 4
drwxr-xr-x. 2 root root 6 Apr 14 10:01 ./
drwxr-xr-x. 22 root root 4096 Apr 14 10:02 ../
root@ab4426a23cb4:/dbdata# ls
a
//db2結(jié)果和db1一樣
root@b4bea0f56613:/# cd dbdata/
root@b4bea0f56613:/dbdata# ll
total 4
drwxr-xr-x. 2 root root 14 Apr 14 10:02 ./
drwxr-xr-x. 22 root root 4096 Apr 14 10:03 ../
-rw-r--r--. 1 root root 0 Apr 14 10:02 a
可以多次使用--volumes-from參數(shù)來從多個容器掛載多個數(shù)據(jù)卷。還可以從其他已經(jīng)掛載了容器卷的容器來掛載數(shù)據(jù)卷沿癞。
使用--volumes-from參數(shù)所掛載數(shù)據(jù)卷的容器自身并不需要保持在運(yùn)行狀態(tài)援雇。如果刪除了掛載容器(包括dbdata、db1和bd2)椎扬,數(shù)據(jù)卷并不會被自動刪除惫搏。如果要刪除一個數(shù)據(jù)卷,必須在刪除最后一個還掛載著它的容器時顯示使用docker rm -v命令來指定同時刪除關(guān)聯(lián)的數(shù)據(jù)卷蚕涤。