volume的創(chuàng)建
為了能夠保存(持久化)數(shù)據(jù)以及共享容器間的數(shù)據(jù),Docker提出了Volume的概念.簡(jiǎn)單來(lái)說(shuō),Volume就是目錄或者文件,它可以繞過(guò)默認(rèn)的聯(lián)合文件系統(tǒng),而以正常的文件或者目錄的形式存在于宿主機(jī)上.
我們可以通過(guò)兩種方式來(lái)初始化Volume,這兩種方式有些細(xì)小而又重要的差別.我們可以在運(yùn)行時(shí)使用-v來(lái)聲明Volume:
[root@node1 volume]# docker run -it --name container-test -h CONTAINER -v /data busybox /bin/sh
/ #
/ # ls /data
上面的命令會(huì)將/data掛載到容器中,并繞過(guò)聯(lián)合文件系統(tǒng),我們可以在主機(jī)上直接操作該目錄.任何在該鏡像/data路徑的文件的文件都會(huì)被復(fù)制到Volume.我們可以使用docker inspect命令找到Volume在主機(jī)上的存儲(chǔ)位置:
$docker inspect container-test
"Mounts": [
{
"Name": "6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134",
"Source": "/var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true
}
],
這說(shuō)明Docker把在/var/lib/docker下的某個(gè)目錄掛載到了容器內(nèi)的/data目錄下.讓我們從主機(jī)添加文件都此文件夾下:
root@node1:~# touch /var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data/test-file
進(jìn)入容器
root@node1:~# docker exec -it container-test /bin/sh
root@CONTAINER:/# ls /data/
test-file
只要將主機(jī)的目錄掛載到容器的目錄上,那改變就會(huì)立即生效.我們可以在Dockerfile中通過(guò)使用VOLUME指令來(lái)達(dá)到相同的目的:
FROM ubunut VOLUME /data
但是還有另一件只有-v參數(shù)能夠做到而Dockerfile是做不到的事情就是在容器上掛載指定的主機(jī)目錄.例如:
(冒號(hào)前面是主機(jī)的目錄 : 冒號(hào)后面是docker容器的目錄)
root@node1:~# docker run -v /data/mysql:/data/mysql busybox
該命令將掛載主機(jī)的/data/mysql目錄到容器內(nèi)的/data目錄上.任何在/data/mysql目錄下的文件都會(huì)出現(xiàn)在容器內(nèi).這對(duì)于在主機(jī)和容器之間共享文件是非常有用的,例如掛載需要編譯的源代碼.為了保證可移植性,掛載主機(jī)目錄不需要從Dockerfile指定.當(dāng)使用-v參數(shù)時(shí),鏡像目錄下的任何文件都不會(huì)被復(fù)制到Volume中.
數(shù)據(jù)共享
如果要授權(quán)一個(gè)容器訪問(wèn)另一個(gè)容器的Volume,我們可以使用-volumes-from參數(shù)來(lái)執(zhí)行docker run
root@node1:~# docker run -it -h NEWCONTAINER --volumes-from container-test busybox /bin/bash
root@NEWCONTAINER:/# ls /data/
test-file
值得注意的是,就算你這個(gè)時(shí)候把container-test停止了,它仍然會(huì)起作用.只要有容器連接Volume,他就不會(huì)被刪除,如果這個(gè)時(shí)候你執(zhí)行:
root@node1:~# docker rm container-test
Error response from daemon: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [container-test]
數(shù)據(jù)容器
通常使用數(shù)據(jù)容器來(lái)持久化數(shù)據(jù)庫(kù)和數(shù)據(jù)文件明未。
$ docker run --name dbdata mysql echo "data only"
創(chuàng)建了一個(gè)名為dbdata的數(shù)據(jù)容器槽华,運(yùn)行完echo之后就停止了。數(shù)據(jù)容器是不需要運(yùn)行的趟妥,只要?jiǎng)?chuàng)建好了就可以了猫态。
$ docker run -d --volumes-from dbdata --name db1 mysql
啟動(dòng)一個(gè)數(shù)據(jù)庫(kù)服務(wù)容器,連接到dbdata數(shù)據(jù)容器上披摄。
注意:
數(shù)據(jù)容器不需運(yùn)行亲雪,純粹是在浪費(fèi)資源
不需為數(shù)據(jù)容器單獨(dú)使用一個(gè)小的鏡像,直接使用數(shù)據(jù)庫(kù)鏡像本身就可以了
刪除Volumes
這個(gè)功能太重要了,如果你已經(jīng)使用docker run來(lái)刪除你的容器,那可能會(huì)有很多孤立的Volume仍在占用著空間.
Voulume可以被刪除的條件:
1.該容器可以用docker rm -v來(lái)刪除且沒(méi)有其他容器連接到該Volume(以及主機(jī)目錄是也沒(méi)被指定為Volume).注意,-v是必不可少的.
2.docker run中使用rm參數(shù).
數(shù)據(jù)備份
如果要備份mysql數(shù)據(jù)庫(kù)疚膊,我們需要備份數(shù)據(jù)容器中的/var/lib/mysql文件夾义辕。
$ docker run --rm --volumes-from dbdata -v $(pwd):/backup ubuntu tar zcvf /backup/mysql.tar.gz /var/lib/mysql
此時(shí)就會(huì)在當(dāng)前目錄下生成一個(gè)mysql.tar.gz文件。