容器存儲(chǔ)
docker為容器準(zhǔn)備了兩種存放數(shù)據(jù)的方法
1、docker storage driver 管理的鏡像層和容器層
2、data volume
storage driver
容器由最上面的容器層和若干數(shù)量的只讀鏡像層組成,容器的數(shù)據(jù)就存放在這些層中。
這樣分層結(jié)構(gòu)的最大特性是 copy-on-write
- 新數(shù)據(jù)會(huì)放在最上層的容器層中
- 修改原有鏡像層的數(shù)據(jù),會(huì)將鏡像層中的數(shù)據(jù)復(fù)制到容器層,修改后的數(shù)據(jù)就保存在容器層中,鏡像層的數(shù)據(jù)保持不變。
- 如果多個(gè)層中有命名相同的文件,用戶只能看到最上一層的那個(gè)文件
分層結(jié)構(gòu)使構(gòu)建鏡像和容器的創(chuàng)建共享、分發(fā)變得高效
storage driver 實(shí)現(xiàn)了多層數(shù)據(jù)的堆疊并為用戶提供了一個(gè)單一合并之后的視圖
docker 支持多種 storage driver
- AUFS
- Device Mapper
- Btrfs
- OverlayFS
- VFS
- ZFS
他們都支持分層的架構(gòu),同時(shí)有擁有不同的特性
1、沒(méi)有drvier可以適用所有場(chǎng)景
2、drvier本身在快速迭代
docker 安裝時(shí)會(huì)根據(jù)當(dāng)前系統(tǒng)的配置選擇默認(rèn)的driver
運(yùn)行# docker info 可以查看
Server Version: 17.12.1-ce
Storage Driver: overlay2
Backing Filesystem: extfs
對(duì)于某些容器,直接將數(shù)據(jù)放在storage driver 維護(hù)的層中,比如無(wú)狀態(tài)的應(yīng)用。無(wú)狀態(tài)意味著沒(méi)有需要持續(xù)化的數(shù)據(jù),隨時(shí)從鏡像中直接創(chuàng)建
data volume
Data Volume本質(zhì)上是 docker host文件系統(tǒng)內(nèi)的目錄或文件,能夠被直接mount到容器文件系統(tǒng)中
1、data volume是目錄或文件,而非沒(méi)有格式化的磁盤(pán)(塊設(shè)備
2、容器可以讀寫(xiě) volume 中的數(shù)據(jù)
3、volume的數(shù)據(jù)可以被永久保存,即使使用它的容器已經(jīng)被銷毀
如何選擇數(shù)據(jù)存儲(chǔ)方式
1、database 軟件 databases數(shù)據(jù)
2、web 應(yīng)用 web應(yīng)用產(chǎn)生的日志
3、Apache server 靜態(tài)HTML文件
無(wú)狀態(tài)的應(yīng)該作為鏡像的一部分,需要持續(xù)化的數(shù)據(jù)應(yīng)該與鏡像分開(kāi)存放
docker volume 提供了兩種方式
bind mount
將host文件系統(tǒng)上已存在的目錄或文件mount到容器
# docker run -d -p 8080:80 -v /data/html:/usr/local/apache2/htdocs httpd
-v 的格式為<host path>:<container path>
# docker run -d -p 9999:80 -v /data/html:/usr/local/apache2/htdocs:ro httpd
還可以指定讀寫(xiě)權(quán)限
bind mount的使用直觀高效易于理解 但是需要指定host文件系統(tǒng)的特定路徑,這樣就限制了容器的可移植性
docker managed volume
Managed volume 和 bind mount 最大的區(qū)別是不需要指定mount源 指明mount point就可以了
# docker run -d -p 8080:80 --name=httpd_8080 -v /usr/local/apache2/htdocs httpd
通過(guò)-v 告訴容器我們需要data volume(數(shù)據(jù)卷) 并將其掛載到容器指定位置
docker 數(shù)據(jù)卷的位置 /var/lib/docker/volumes/
# docker inspect 命令結(jié)果的mounts區(qū)域里顯示了mount的詳細(xì)信息
# docker volume ls 數(shù)據(jù)卷列表
# docker volume inspect 數(shù)據(jù)卷詳情 命令的對(duì)象為數(shù)據(jù)卷
如果volume 掛載到容器中有已經(jīng)有數(shù)據(jù)的目錄,原有的數(shù)據(jù)會(huì)被復(fù)制到volume中
但此時(shí)容器中掛載的數(shù)據(jù)已經(jīng)不是storage driver管理的層數(shù)據(jù)了
數(shù)據(jù)共享
容器與host數(shù)據(jù)共享
bind mount 直接將要共享的目錄直接mount到容器
managed volume 就需要在容器創(chuàng)建后生成了mount路徑 再進(jìn)行數(shù)據(jù)復(fù)制
容器與容器之間數(shù)據(jù)共享
1、將數(shù)據(jù)放在bind mount 目錄中,然后將其mount到多個(gè)容器中
2、volume container
volume container是用來(lái)為其他容器提供volume的容器。他提供的卷可以是bind mount 也可以是managed volume的
# docker create --name=data_vc -v /data/:/usr/local/apache2/htdocs -v /root/data busybox
創(chuàng)建一個(gè)volume container 不需要運(yùn)行 ;
# docker volume ls
查看卷列表
# docker run -d -p 8888:80 --name=httpd0 --volumes-from data_vc httpd
# docker run -d -p 9999:80 --name=httpd1 --volumes-from data_vc httpd
創(chuàng)建httpd容器并指定使用data_vc容器為volume container (以data_vc為模版)
# 檢查httpd容器是否關(guān)聯(lián),并再次查看卷列表,沒(méi)有新增的volume
# docker inspect httpd
檢查容器的mounts區(qū)域配置。發(fā)現(xiàn)httpd容器的配置與data_vc一致
與 bind mount 相比,不必為每一個(gè)容器指定 host path,所有 path 都在 volume container 中定義好了,容器只需與 volume container 關(guān)聯(lián),實(shí)現(xiàn)了容器與 host 的解耦。使用 volume container 的容器其 mount point 是一致的,有利于配置的規(guī)范和標(biāo)準(zhǔn)化,但也帶來(lái)一定的局限,使用時(shí)需要綜合考慮
data-packed volume container
Volume container 中數(shù)據(jù)還是在host中
data-packed volume container 其原理就是將數(shù)據(jù)打包到鏡像中,通過(guò)docker managed volume 共享
# vim dockerfile
FROM busybox
ADD htdocs /usr/local/apache2/htdocs 復(fù)制到鏡像層
VOLUME /usr/local/apache2/htdocs 將數(shù)據(jù)同步到host
# docker build -t datapacked .
構(gòu)建鏡像
# docker create --name vc_data datapacked
創(chuàng)建模版容器
# docker run -d -p 1111:80 --volumes-from vc_data httpd
啟動(dòng)容器并指定volume
volume生命周期管理
volume的創(chuàng)建、共享和使用
備份、恢復(fù)、遷移、銷毀volume
備份##########
因?yàn)関olume實(shí)際上是host文件系統(tǒng)中的目錄和文件,備份volume實(shí)際上就是對(duì)文件系統(tǒng)的備份
恢復(fù)
遷移
假如使用更高版本的Registry,這就涉及數(shù)據(jù)遷移的問(wèn)題
1、 docker stop 停止當(dāng)前容器
2、啟動(dòng)新版本容器并mount原有volume
docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:latest
銷毀
可以刪除不再需要的volume,但是無(wú)法找回了
docker不會(huì)銷毀bind mount ,刪除數(shù)據(jù)的工作只能由host負(fù)責(zé)。
對(duì)于docker managed volume ,在執(zhí)行 # docker rm 刪除容器時(shí)可以帶上-v參數(shù) ,docker 會(huì)將容器使用到的volume一并刪除
但前提是沒(méi)有其他容器mount該volume,目的是保護(hù)數(shù)據(jù)
如果刪除容器時(shí)沒(méi)有帶有 -v 選項(xiàng) docker的volume就會(huì)遺留下來(lái)。
可以通過(guò) docker volume ls 查看全部的volume
# docker volume rm xxx xxx
批量刪除
# docker volume rm $(docker volume ls -q)