?
? ????? PHP ??? ???? ??? ?? ??
Device Mapper是基于內(nèi)核的框架,支持Linux上的許多高級(jí)卷管理技術(shù)。Docker的devicemapper
存儲(chǔ)驅(qū)動(dòng)程序利用此框架的精簡(jiǎn)配置和快照功能進(jìn)行鏡像和容器管理。本文將Device Mapper存儲(chǔ)驅(qū)動(dòng)程序稱(chēng)為devicemapper
,并將內(nèi)核框架稱(chēng)為Device Mapper
。
對(duì)于支持它的系統(tǒng),devicemapper
支持包含在Linux內(nèi)核中。但是,需要特定配置才能將其用于Docker。例如,在RHEL或CentOS的股票安裝中,Docker將默認(rèn)為overlay
,這不是受支持的配置。
devicemapper
驅(qū)動(dòng)程序使用專(zhuān)用于Docker的塊設(shè)備,并在塊級(jí)而不是文件級(jí)運(yùn)行。這些設(shè)備可以通過(guò)將物理存儲(chǔ)添加到Docker主機(jī)來(lái)擴(kuò)展,并且它們比在操作系統(tǒng)級(jí)別使用文件系統(tǒng)更好。
如果您在RHEL,CentOS或Oracle Linux上使用Docker EE,則必須使用devicemapper
存儲(chǔ)驅(qū)動(dòng)程序。
devicemapper
存儲(chǔ)驅(qū)動(dòng)程序是RHEL,CentOS和Oracle Linux上唯一支持Docker EE和商業(yè)支持Docker Engine(CS-Engine)的存儲(chǔ)驅(qū)動(dòng)程序。請(qǐng)參閱產(chǎn)品兼容性表格。
devicemapper
在CentOS,F(xiàn)edora,Ubuntu或Debian上運(yùn)行的Docker CE也受支持。
更改存儲(chǔ)驅(qū)動(dòng)程序?qū)⑹鼓褎?chuàng)建的任何容器在本地系統(tǒng)上都不可訪問(wèn)。使用docker save
保存的容器,并推動(dòng)現(xiàn)有圖像多克爾集線器或私人倉(cāng)庫(kù),讓你不必后重新創(chuàng)建它們。
devicemapper
存儲(chǔ)驅(qū)動(dòng)程序配置Docker在遵循這些程序之前,您必須先滿足所有先決條件。
loop-lvm
測(cè)試模式此配置僅適用于測(cè)試。環(huán)回設(shè)備速度慢且資源密集,并且需要您以特定大小在磁盤(pán)上創(chuàng)建文件。他們還可以引入競(jìng)爭(zhēng)條件。他們應(yīng)該進(jìn)行測(cè)試,因?yàn)榘惭b更容易。
對(duì)于生產(chǎn)系統(tǒng),請(qǐng)參閱為生產(chǎn)配置direct-lvm模式。
停止Docker。$ sudo systemctl stop docker
2. 編輯/etc/docker/daemon.json
。如果它還不存在,請(qǐng)創(chuàng)建。假設(shè)文件為空,請(qǐng)?zhí)砑右韵聝?nèi)容。{ "storage-driver": "devicemapper" }查看每個(gè)存儲(chǔ)驅(qū)動(dòng)程序的所有存儲(chǔ)選項(xiàng):
- [Stable](../../../reference/commandline/dockerd/index#storage-driver-options)- [Edge](https://docs.docker.com/edge/engine/reference/commandline/dockerd/#storage-driver-options)
如果daemon.json
文件包含格式錯(cuò)誤的JSON,Docker將無(wú)法啟動(dòng)。
啟動(dòng)Docker。$ sudo systemctl start docker
驗(yàn)證守護(hù)進(jìn)程正在使用devicemapper
存儲(chǔ)驅(qū)動(dòng)程序。使用docker info
命令并尋找Storage Driver
。$ docker info 容器:0 正在運(yùn)行:0 已暫停:0 已停止:0 圖像:0 服務(wù)器版本:17.03.1-ce存儲(chǔ)驅(qū)動(dòng)程序:devicemapper 池名稱(chēng):docker-202:1-8413957-pool 池大?。?5.54 kB 基本設(shè)備大小:10.74 GB 備份文件系統(tǒng):xfs 數(shù)據(jù)文件:/ dev/loop0 元數(shù)據(jù)文件:/dev/loop1 使用的數(shù)據(jù)空間:11.8 MB 數(shù)據(jù)空間總數(shù):107.4 GB 數(shù)據(jù)空間可用:7.44 GB 使用的元數(shù)據(jù)空間:581.6 kB 元數(shù)據(jù)空間總數(shù):2.147 GB 可用元數(shù)據(jù)空間:2.147 GB 精簡(jiǎn)池最小可用空間:10.74 GB Udev同步支持:true 延遲刪除已啟用:false 延遲刪除已啟用:false 延期刪除設(shè)備計(jì)數(shù):0 數(shù)據(jù)循環(huán)文件:/var/lib/docker/devicemapper/devicemapper/data 元數(shù)據(jù)循環(huán)文件:/var/lib/docker/devicemapper/devicemapper/metadata 庫(kù)版本:1.02.135-RHEL7 (2016-11-16) <output truncated>
該主機(jī)在運(yùn)行的loop-lvm
節(jié)點(diǎn),這是不支持在生產(chǎn)系統(tǒng)上。這是由以下事實(shí)表明的:Data loop file
a和a Metadata loop file
在文件下/var/lib/docker/devicemapper/devicemapper
。這些是回送加載的稀疏文件。對(duì)于生產(chǎn)系統(tǒng),請(qǐng)參閱為生產(chǎn)配置direct-lvm模式。
使用devicemapper
存儲(chǔ)驅(qū)動(dòng)程序的生產(chǎn)主機(jī)必須使用direct-lvm
模式。該模式使用塊設(shè)備來(lái)創(chuàng)建精簡(jiǎn)池。這比使用回送設(shè)備更快,更高效地使用系統(tǒng)資源,并且塊設(shè)備可以根據(jù)需要增長(zhǎng)。但是,loop-lvm
模式需要更多的設(shè)置。
在滿足先決條件之后,請(qǐng)按照以下步驟將Docker配置為devicemapper
以direct-lvm
模式使用存儲(chǔ)驅(qū)動(dòng)程序。
警告:更改存儲(chǔ)驅(qū)動(dòng)程序?qū)⑹鼓褎?chuàng)建的任何容器在本地系統(tǒng)上都無(wú)法訪問(wèn)。使用
docker save
保存的容器,并推動(dòng)現(xiàn)有圖像多克爾集線器或私人倉(cāng)庫(kù),這樣就不需要以后重新創(chuàng)建。
在Docker 17.06及更高版本中,Docker可以為您管理塊設(shè)備,簡(jiǎn)化direct-lvm
模式配置。這僅適用于新的Docker設(shè)置。您只能使用一個(gè)塊設(shè)備。如果您需要使用多個(gè)塊設(shè)備,請(qǐng)手動(dòng)配置direct-lvm模式。添加了以下新的配置選項(xiàng):
Option | Description | Required? | Default | Example |
---|---|---|---|---|
dm.directlvm_device | The path to the block device to configure for direct-lvm. | Yes | dm.directlvm_device="/dev/xvdf" | |
dm.thinp_percent | The percentage of space to use for storage from the passed in block device. | No | 95 | dm.thinp_percent=95 |
dm.thinp_metapercent | The percentage of space to for metadata storage from the passed=in block device. | No | 1 | dm.thinp_metapercent=1 |
dm.thinp_autoextend_threshold | The threshold for when lvm should automatically extend the thin pool as a percentage of the total storage space. | No | 80 | dm.thinp_autoextend_threshold=80 |
dm.thinp_autoextend_percent | The percentage to increase the thin pool by when an autoextend is triggered. | No | 20 | dm.thinp_autoextend_percent=20 |
dm.directlvm_device_force | Whether to format the block device even if a filesystem already exists on it. If set to false and a filesystem is present, an error is logged and the filesystem is left intact. | No | false | dm.directlvm_device_force=true |
編輯daemon.json
文件并設(shè)置適當(dāng)?shù)倪x項(xiàng),然后重新啟動(dòng)Docker以使更改生效。以下daemon.json
設(shè)置了上表中的所有選項(xiàng)。
{ "storage-driver": "devicemapper", "storage-opts": [ "dm.directlvm_device=/dev/xdf", "dm.thinp_percent=95", "dm.thinp_metapercent=1", "dm.thinp_autoextend_threshold=80", "dm.thinp_autoextend_percent=20", "dm.directlvm_device_force=false" ]}
查看每個(gè)存儲(chǔ)驅(qū)動(dòng)程序的所有存儲(chǔ)選項(xiàng):
Stable
Edge
重新啟動(dòng)Docker以使更改生效。Docker會(huì)調(diào)用這些命令為您配置塊設(shè)備。
警告:在Docker為您準(zhǔn)備好塊設(shè)備后更改這些值不受支持,并且會(huì)導(dǎo)致錯(cuò)誤。
您仍然需要執(zhí)行定期維護(hù)任務(wù)。
以下過(guò)程將創(chuàng)建配置為精簡(jiǎn)池的邏輯卷,以用作存儲(chǔ)池的備份。它假定您有一個(gè)備用塊設(shè)備,/dev/xvdf
并有足夠的空間來(lái)完成任務(wù)。設(shè)備標(biāo)識(shí)符和音量大小在您的環(huán)境中可能不同,您應(yīng)該在整個(gè)過(guò)程中替換您自己的值。該過(guò)程還假定Docker守護(hù)進(jìn)程處于該stopped
狀態(tài)。
確定要使用的塊設(shè)備。該設(shè)備將位于/dev/
(如/dev/xvdf
)下,并且需要足夠的可用空間來(lái)存儲(chǔ)主機(jī)將運(yùn)行的工作負(fù)載的映像和容器層。理想情況下,這將是一個(gè)固態(tài)硬盤(pán)。
2. 停止Docker。$ sudo systemctl stop docker
3. 安裝下列軟件包:
- **RHEL / CentOS**: `device-mapper-persistent-data`, `lvm2`, and all dependencies
- **Ubuntu / Debian**: `thin-provisioning-tools`, `lvm2`, and all dependencies
4. 使用該pvcreate
命令在步驟1中創(chuàng)建塊設(shè)備上的物理卷。替換您的設(shè)備名稱(chēng)/dev/xvdf
。 警告:接下來(lái)的幾個(gè)步驟是破壞性的,所以請(qǐng)確保您指定了正確的設(shè)備!
$ sudo pvcreate/dev/xvdf 物理卷“/dev/xvdf”已成功創(chuàng)建。
5. docker
使用該vgcreate
命令在同一設(shè)備上創(chuàng)建一個(gè)卷組。$ sudo vgcreate docker/dev/xvdf成功創(chuàng)建卷組“docker”
6. 創(chuàng)建兩個(gè)命名的邏輯卷thinpool
并thinpoolmeta
使用該lvcreate
命令。最后一個(gè)參數(shù)指定可用空間的大小,以便在空間不足時(shí)自動(dòng)擴(kuò)展數(shù)據(jù)或元數(shù)據(jù),作為臨時(shí)性缺口。這些是推薦值。$ sudo lvcreate --wipesignatures y -n thinpool docker -l 95%VG 創(chuàng)建邏輯卷“thinpool”。$ sudo lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG 創(chuàng)建邏輯卷“thinpoolmeta”。
6. 使用該lvconvert
命令將卷轉(zhuǎn)換為精簡(jiǎn)池和精簡(jiǎn)池元數(shù)據(jù)的存儲(chǔ)位置。$ sudo lvconvert -y \ --zero n \ -c 512K \ --thinpool docker/thinpool \ --poolmetadata
警告:使用元數(shù)據(jù)擦除將邏輯卷docker/thinpool和docker/thinpoolmeta轉(zhuǎn)換為精簡(jiǎn)池的數(shù)據(jù)和元數(shù)據(jù)卷。這將破壞邏輯卷的內(nèi)容(文件系統(tǒng)等)將docker/thinpool轉(zhuǎn)換為精簡(jiǎn)池。
7. 通過(guò)lvm
配置文件配置精簡(jiǎn)池的自動(dòng)擴(kuò)展。$ sudo vi /etc/lvm/profile/docker-thinpool.profile
8. 指定thin_pool_autoextend_threshold
和thin_pool_autoextend_percent
值。 thin_pool_autoextend_threshold
是lvm
嘗試自動(dòng)擴(kuò)展可用空間之前所用空間的百分比(100 =disabled,不推薦)。 thin_pool_autoextend_percent
是自動(dòng)擴(kuò)展時(shí)添加到設(shè)備的空間量(0 = disabled)。當(dāng)磁盤(pán)使用率達(dá)到80%時(shí),下面的示例將增加20%的容量。激活{ thin_pool_autoextend_threshold=80 thin_pool_autoextend_percent=20 } 保存文件。
9. 使用該lvchange
命令應(yīng)用LVM配置文件。$ sudo lvchange --metadataprofile docker-thinpool docker/thinpool邏輯卷docker/thinpool已更改。
10. 啟用對(duì)主機(jī)上邏輯卷的監(jiān)視。沒(méi)有這一步,即使存在LVM配置文件,自動(dòng)擴(kuò)展也不會(huì)發(fā)生。$ sudo lvs -o+seg_monitor LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Monitor thinpool docker twi-a-t--- 95.00g 0.00 0.01 monitored
11. 如果您以前曾經(jīng)在此主機(jī)上運(yùn)行過(guò)Docker,或者/var/lib/docker/
存在,請(qǐng)將其移出,以便Docker可以使用新的LVM池來(lái)存儲(chǔ)映像和容器的內(nèi)容。$ mkdir /var/lib/docker.bk $ mv /var/lib/docker/* /var/lib/docker.bk 如果以下任何步驟失敗并且您需要恢復(fù),您可以刪除/var/lib/docker
并替換為/var/lib/docker.bk
。
12. 編輯/etc/docker/daemon.json
并配置devicemapper
存儲(chǔ)驅(qū)動(dòng)程序所需的選項(xiàng)。如果該文件先前為空,則應(yīng)該包含以下內(nèi)容: 注意:dm.use_deferred_deletion=true
使用默認(rèn)內(nèi)核版本3.18時(shí),RHEL,CentOS或Ubuntu 14.04尚不支持延遲刪除選項(xiàng)。
{ "storage-driver": "devicemapper", "storage-opts": "dm.thinpooldev=/dev/mapper/docker-thinpool", "dm.use_deferred_removal=true", "dm.use_deferred_deletion=true" }
啟動(dòng)Docker。 systemd:$ sudo systemctl start docker 服務(wù):$ sudo service docker start
2. 驗(yàn)證Docker是否正在使用新配置docker info
。$ docker info容器:0運(yùn)行:0暫停:0已停止:0映像:0服務(wù)器版本:17.03.1-ce存儲(chǔ)驅(qū)動(dòng)程序:devicemapper池名稱(chēng):docker-thinpool池大小:524.3 kB基本設(shè)備大?。?0.74 GB備份文件系統(tǒng): xfs數(shù)據(jù)文件:元數(shù)據(jù)文件:使用的數(shù)據(jù)空間:19.92 MB數(shù)據(jù)空間總數(shù):102 GB數(shù)據(jù)空間可用:102 GB使用的元數(shù)據(jù)空間:147.5 kB元數(shù)據(jù)空間總計(jì):1.07 GB元數(shù)據(jù)空間:1.069 GB精簡(jiǎn)池最小可用空間:10.2 GB Udev的同步支持:真遞延去除啟用:真遞延刪除啟用:真實(shí)延遲刪除設(shè)備數(shù)量:0庫(kù)版本:1.02.135-RHEL7(2016年11月16日)<output truncated>如果Docker配置正確時(shí),Data file
和Metadata file
將是空白的,并且池名將會(huì)是docker-thinpool
。
3. 驗(yàn)證配置正確后,可以刪除/var/lib/docker.bk
包含以前配置的目錄。$ rm -rf /var/lib/docker.bk
不要單獨(dú)依靠LVM自動(dòng)擴(kuò)展。卷組可以自動(dòng)擴(kuò)展,但是卷仍能寫(xiě)滿。您可以使用lvs
或監(jiān)視卷上的可用空間lvs -a
。考慮在操作系統(tǒng)級(jí)別使用監(jiān)控工具,例如Nagios。
要查看LVM日志,您可以使用journalctl
:
$ journalctl -fu dm-event.service
如果您遇到精簡(jiǎn)池問(wèn)題,可以將存儲(chǔ)選項(xiàng)設(shè)置dm.min_free_space
為一個(gè)值(表示百分比)/etc/docker.daemon.json
。例如,將其設(shè)置為10
在可用空間達(dá)到或接近10%時(shí)確保操作失敗并發(fā)出警告。請(qǐng)參閱Engine守護(hù)程序參考中的存儲(chǔ)驅(qū)動(dòng)程序選項(xiàng)。
您可以增加正在運(yùn)行的精簡(jiǎn)池設(shè)備上的池的容量。如果數(shù)據(jù)的邏輯卷已滿并且卷組處于滿負(fù)荷狀態(tài),這很有用。具體過(guò)程取決于您是使用loop-lvm精簡(jiǎn)池還是直接使用lvm精簡(jiǎn)池。
調(diào)整loop-lvm
精簡(jiǎn)池的最簡(jiǎn)單方法是使用device_tool實(shí)用程序,但可以使用操作系統(tǒng)實(shí)用程序。
在Docker Github存儲(chǔ)庫(kù)device_tool.go
的contrib/
目錄中提供了一個(gè)社區(qū)貢獻(xiàn)的腳本。您可以使用此工具調(diào)整loop-lvm
精簡(jiǎn)池的大小,避免上述漫長(zhǎng)的過(guò)程。此工具無(wú)法保證正常工作,但您只能loop-lvm
在非生產(chǎn)系統(tǒng)上使用。
如果您不想使用device_tool
,則可以手動(dòng)調(diào)整精簡(jiǎn)池的大?。ǎse-operating-system-utilities)。
要使用該工具,請(qǐng)克隆Github存儲(chǔ)庫(kù),更改為contrib/docker-device-tool
,并按照其中的說(shuō)明README.md
編譯該工具。
2. 使用該工具。以下示例將精簡(jiǎn)池的大小調(diào)整為200GB。$ ./device_tool resize 200GB
如果您不想使用設(shè)備工具實(shí)用程序,則可以loop-lvm
使用以下步驟手動(dòng)調(diào)整精簡(jiǎn)池的大小。
在loop-lvm
模式中,回送設(shè)備用于存儲(chǔ)數(shù)據(jù),另一個(gè)用于存儲(chǔ)元數(shù)據(jù)。loop-lvm
模式僅支持測(cè)試,因?yàn)樗哂酗@著的性能和穩(wěn)定性缺陷。
如果您使用的loop-lvm
模式,輸出docker info
會(huì)顯示文件路徑Data loop file
和Metadata loop file
:
$ docker info |grep 'loop file' Data loop file: /var/lib/docker/devicemapper/devicemapper/data Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
按照以下步驟增加精簡(jiǎn)池的大小。在此示例中,精簡(jiǎn)池為100 GB,并增加到200 GB。
列出設(shè)備的大小。$ sudo ls -lh /var/lib/docker/devicemapper/devicemapper/ total 1175492 -rw------- 1 root root 100G Mar 30 05:22 data -rw------- 1 root root 2.0G Mar 31 11:17 metadata
2. data
使用該truncate
命令將文件的大小增大到200 G,該命令用于增加或減小文件的大小。請(qǐng)注意,減小尺寸是一種破壞性操作。$ sudo truncate -s 200G /var/lib/docker/devicemapper/devicemapper/data
3. 驗(yàn)證文件大小已更改。$ sudo ls -lh /var/lib/docker/devicemapper/devicemapper/ total 1.2G -rw------- 1 root root 200G Apr 14 08:47 data -rw------- 1 root root 2.0G Apr 19 13:27 metadat
4. 環(huán)回文件已在磁盤(pán)上更改,但未在內(nèi)存中更改。列出內(nèi)存中環(huán)回設(shè)備的大小,以GB為單位。重新加載,然后再次列出大小。重新加載后,大小為200 GB。$ echo $ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 100 $ sudo losetup -c /dev/loop0 $ echo $ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 200
5. 重新加載devicemapper精簡(jiǎn)池。a. 先獲取泳池名稱(chēng)。池名稱(chēng)是第一個(gè)由其分隔的字段:
。這個(gè)命令提取它。$ sudo dmsetup status | grep'thin-pool'| awk -F':'{'print $ 1'} docker-8:1-123141-pool b.轉(zhuǎn)儲(chǔ)精簡(jiǎn)池的設(shè)備映射表。$ sudo dmsetup table docker-8:1-123141-pool 0 209715200-pool 7:1 7:0 128 32768 1 skip_block_zeroing c. 使用輸出的第二個(gè)字段計(jì)算精簡(jiǎn)池的總部分。該數(shù)字以512-k扇區(qū)表示。一個(gè)100G文件有209715200個(gè)512-k扇區(qū)。如果你把這個(gè)數(shù)字加倍到200G,你會(huì)得到419430400個(gè)512k扇區(qū)。d. 使用以下三個(gè)重新加載具有新扇區(qū)號(hào)的精簡(jiǎn)池dmsetup
命令。$ sudo dmsetup suspend docker-8:1-123141-pool $ sudo dmsetup reload docker-8:1-123141-pool --table'0 419430400 thin-pool7:1 7:0 128 32768 1 skip_block_zeroing'$ sudo dmsetup resume docker-8:1-123141-pool
要擴(kuò)展direct-lvm
精簡(jiǎn)池,您需要首先將新的塊設(shè)備附加到Docker主機(jī),并記下內(nèi)核分配給它的名稱(chēng)。在這個(gè)例子中,新的塊設(shè)備是/dev/xvdg
。
按照此步驟擴(kuò)展direct-lvm
精簡(jiǎn)池,替換您的塊設(shè)備和其他參數(shù)以適合您的情況。
收集有關(guān)您的卷組的信息。使用此pvdisplay
命令查找您的精簡(jiǎn)池當(dāng)前正在使用的物理塊設(shè)備以及卷組的名稱(chēng)。$ sudo pvdisplay |grep 'VG Name' PV Name /dev/xvdf VG Name docker
在以下步驟中,根據(jù)需要替換塊設(shè)備或卷組名稱(chēng)。
使用上一步中的vgextend
命令VG Name
和新塊設(shè)備的名稱(chēng)擴(kuò)展卷組。$ sudo vgextend docker /dev/xvdg Physical volume "/dev/xvdg" 已成功創(chuàng)建。卷組“docker”已成功擴(kuò)展
2. 擴(kuò)展docker/thinpool
邏輯卷。該命令立即使用100%的體積,而不會(huì)自動(dòng)擴(kuò)展。要擴(kuò)展元數(shù)據(jù)精簡(jiǎn)池,請(qǐng)使用docker/thinpool_tmeta
。docker/thinpool_tmeta
. $ sudo lvextend -l+100%FREE -n docker/thinpool 邏輯卷docker/thinpool_tdata的大小從95.00 GiB(24319個(gè)擴(kuò)展盤(pán)區(qū))變?yōu)?98.00個(gè)GiB(50688個(gè)盤(pán)區(qū))。邏輯卷docker/thinpool_tdata已成功調(diào)整大小。
3. 使用Data Space Available
輸出中的字段驗(yàn)證新的精簡(jiǎn)池大小docker info
。如果您擴(kuò)展了docker/thinpool_tmeta
邏輯卷,請(qǐng)查找Metadata Space Available
。存儲(chǔ)驅(qū)動(dòng)程序:devicemapper池名稱(chēng):docker-thinpool池塊大?。?24.3 kB基本設(shè)備大?。?0.74 GB備份文件系統(tǒng):xfs數(shù)據(jù)文件:元數(shù)據(jù)文件:使用的數(shù)據(jù)空間:212.3 MB數(shù)據(jù)空間總計(jì):212.6 GB數(shù)據(jù)空間可用:212.4 GB元數(shù)據(jù)已用空間:286.7 kB元數(shù)據(jù)空間總計(jì):1.07 GB元數(shù)據(jù)空間可用:1.069 GB <output truncated>
devicemapper
存儲(chǔ)驅(qū)動(dòng)是怎么工作的警告:不要直接操作其中的任何文件或目錄
/var/lib/docker/
。這些文件和目錄由Docker管理。
lsblk
從操作系統(tǒng)的角度來(lái)看,使用該命令可以查看設(shè)備及其池:
$ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 8G 0 disk └─xvda1 202:1 0 8G 0 part /xvdf 202:80 0 100G 0 disk ├─docker-thinpool_tmeta 253:0 0 1020M 0 lvm │ └─docker-thinpool 253:2 0 95G 0 lvm └─docker-thinpool_tdata 253:1 0 95G 0 lvm └─docker-thinpool 253:2 0 95G 0 lvm
使用mount
命令查看Docker正在使用的安裝點(diǎn):
$ mount |grep devicemapper/dev/xvda1 on /var/lib/docker/devicemapper type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
在使用時(shí)devicemapper
,Docker會(huì)將圖像和圖層內(nèi)容存儲(chǔ)在精簡(jiǎn)池中,并通過(guò)將它們安裝在容器的子目錄下將它們公開(kāi)在容器中/var/lib/docker/devicemapper/
。
/var/lib/docker/devicemapper/metadata/
目錄包含有關(guān)Devicemapper配置本身的元數(shù)據(jù)以及有關(guān)存在的每個(gè)圖像和容器層的元數(shù)據(jù)。devicemapper
存儲(chǔ)驅(qū)動(dòng)程序使用快照,這個(gè)元數(shù)據(jù)包含有關(guān)這些快照的信息。這些文件是JSON格式。
/var/lib/devicemapper/mnt/
目錄包含存在的每個(gè)圖像和容器圖層的裝入點(diǎn)。圖像層掛載點(diǎn)為空,但容器的掛載點(diǎn)顯示容器的文件系統(tǒng),因?yàn)樗@示在容器內(nèi)。
devicemapper
存儲(chǔ)驅(qū)動(dòng)程序使用專(zhuān)用的塊設(shè)備,而不是格式化的文件系統(tǒng),并在copy-on-write(CoW)操作上以獲得最大性能的塊級(jí)的文件進(jìn)行操作。
devicemapper
另一個(gè)功能是使用快照(有時(shí)也稱(chēng)為精簡(jiǎn)設(shè)備或虛擬設(shè)備),它將每層中引入的差異存儲(chǔ)為非常小的輕量級(jí)精簡(jiǎn)池??煺仗峁┝嗽S多好處:
容器之間共享的圖層只能存儲(chǔ)在磁盤(pán)上一次,除非它們是可寫(xiě)的。例如,如果您有10張全部基于的不同圖像alpine
,則alpine
圖像及其所有父圖像只會(huì)在磁盤(pán)上存儲(chǔ)一次。
快照是copy-on-write(CoW)策略的實(shí)現(xiàn)。這意味著給定的文件或目錄只有在容器被修改或刪除時(shí)才會(huì)被復(fù)制到容器的可寫(xiě)層。
由于devicemapper
在塊級(jí)別運(yùn)行,因此可以同時(shí)修改可寫(xiě)層中的多個(gè)塊。
快照可以使用標(biāo)準(zhǔn)的操作系統(tǒng)級(jí)備份工具進(jìn)行備份。只需復(fù)制一份/var/lib/docker/devicemapper/
。
當(dāng)您使用devicemapper
存儲(chǔ)驅(qū)動(dòng)程序啟動(dòng)Docker時(shí),所有與映像和容器圖層相關(guān)的對(duì)象都將存儲(chǔ)在/var/lib/docker/devicemapper/
其中,并由一個(gè)或多個(gè)塊級(jí)設(shè)備(環(huán)回設(shè)備(僅測(cè)試)或物理磁盤(pán))支持。
所述基部設(shè)備是最低級(jí)的對(duì)象。這是精簡(jiǎn)池本身。你可以使用它來(lái)檢查它docker info
。它包含一個(gè)文件系統(tǒng)。這個(gè)基礎(chǔ)設(shè)備是每個(gè)圖像和容器層的起點(diǎn)。基礎(chǔ)設(shè)備是Device Mapper的實(shí)現(xiàn)細(xì)節(jié),而不是Docker層。
有關(guān)基礎(chǔ)設(shè)備和每個(gè)圖像或容器圖層的元數(shù)據(jù)/var/lib/docker/devicemapper/metadata/
以JSON格式存儲(chǔ)。這些圖層是寫(xiě)入時(shí)復(fù)制快照,這意味著它們是空的,直到它們與父圖層分離。
每個(gè)容器的可寫(xiě)入層都安裝在一個(gè)安裝點(diǎn)中/var/lib/docker/devicemapper/mnt/
。每個(gè)只讀圖像層和每個(gè)停止的容器都存在一個(gè)空目錄。
每個(gè)圖像圖層都是其下面圖層的快照。每幅圖像的最底層是存儲(chǔ)在池中的基礎(chǔ)設(shè)備的快照。運(yùn)行容器時(shí),它是容器所基于的映像的快照。以下示例顯示了一個(gè)具有兩個(gè)運(yùn)行容器的Docker主機(jī)。第一個(gè)是ubuntu
容器,第二個(gè)是busybox
容器。
devicemapper
讀取和寫(xiě)入的工作方式與devicemapper
,讀取發(fā)生在塊級(jí)別。下圖顯示了讀取0x44f
示例容器中的單個(gè)塊()的高級(jí)過(guò)程。
應(yīng)用程序0x44f
在容器中發(fā)出塊請(qǐng)求。由于容器是圖像的精簡(jiǎn)快照,它沒(méi)有該塊,但它具有一個(gè)指向最接近的父圖像上存在的塊的指針,并從那里讀取該塊。該塊現(xiàn)在存在于容器的內(nèi)存中。
編寫(xiě)新文件:使用devicemapper
驅(qū)動(dòng)程序,將新數(shù)據(jù)寫(xiě)入容器是通過(guò)按需分配操作完成的。新文件的每個(gè)塊都分配在容器的可寫(xiě)層中,并且塊寫(xiě)入那里。
更新現(xiàn)有文件:文件的相關(guān)塊從最近的圖層中讀取。當(dāng)容器寫(xiě)入文件時(shí),只有修改后的塊被寫(xiě)入容器的可寫(xiě)層。
刪除文件或目錄:當(dāng)您刪除容器可寫(xiě)層中的文件或目錄時(shí),或者圖像層刪除其父層中存在的文件時(shí),devicemapper
存儲(chǔ)驅(qū)動(dòng)程序?qū)⒔厝?duì)該文件或目錄的進(jìn)一步讀取嘗試,并作出響應(yīng)文件或目錄不存在。
編寫(xiě)然后刪除文件:如果容器寫(xiě)入文件并稍后刪除文件,則所有這些操作都發(fā)生在容器的可寫(xiě)層中。在這種情況下,如果你正在使用direct-lvm
,塊被釋放。如果您使用loop-lvm
,塊可能不會(huì)被釋放。這是不用于loop-lvm
生產(chǎn)的另一個(gè)原因。
allocate-on demand
性能影響:devicemapper
存儲(chǔ)驅(qū)動(dòng)程序使用allocate-on-demand
操作將精簡(jiǎn)池中的新塊分配到容器的可寫(xiě)層。每個(gè)塊都是64KB,所以這是用于寫(xiě)入的最小空間量。
寫(xiě)時(shí)復(fù)制性能影響:容器首次修改特定塊時(shí),該塊將寫(xiě)入容器的可寫(xiě)層。因?yàn)檫@些寫(xiě)操作發(fā)生在塊的級(jí)別而不是文件,所以性能影響最小化。但是,編寫(xiě)大量數(shù)據(jù)塊仍然會(huì)對(duì)性能產(chǎn)生負(fù)面影響,并且devicemapper
在此場(chǎng)景中,存儲(chǔ)驅(qū)動(dòng)程序?qū)嶋H上可能比其他存儲(chǔ)驅(qū)動(dòng)程序的性能更差。對(duì)于寫(xiě)入繁重的工作負(fù)載,應(yīng)使用完全繞過(guò)存儲(chǔ)驅(qū)動(dòng)程序的數(shù)據(jù)卷。
在使用devicemapper
存儲(chǔ)驅(qū)動(dòng)程序時(shí)要記住這些事項(xiàng)以最大限度地提高性能。
使用 direct-lvm
:loop-lvm
模式不是高性能的,不應(yīng)該在生產(chǎn)中使用。
使用快速存儲(chǔ):固態(tài)硬盤(pán)(SSD)比旋轉(zhuǎn)磁盤(pán)提供更快的讀取和寫(xiě)入速度。
內(nèi)存使用情況:devicemapper
使用比其他一些存儲(chǔ)驅(qū)動(dòng)程序更多的內(nèi)存。每個(gè)啟動(dòng)的容器都會(huì)將其文件的一個(gè)或多個(gè)副本加載到內(nèi)存中,具體取決于同時(shí)修改同一文件的塊數(shù)。由于內(nèi)存壓力,devicemapper
存儲(chǔ)驅(qū)動(dòng)程序可能不是高密度用例中某些工作負(fù)載的正確選擇。
將卷用于寫(xiě)入繁重的工作負(fù)載:卷為寫(xiě)入繁重的工作負(fù)載提供最佳和最可預(yù)測(cè)的性能。這是因?yàn)樗鼈兝@過(guò)了存儲(chǔ)驅(qū)動(dòng)程序,并且不會(huì)產(chǎn)生精簡(jiǎn)配置和寫(xiě)入時(shí)復(fù)制引入的任何潛在開(kāi)銷(xiāo)。卷還有其他好處,例如允許您在容器之間共享數(shù)據(jù),并且即使在沒(méi)有正在運(yùn)行的容器正在使用它們時(shí)也會(huì)持久存在。
了解圖像,容器和存儲(chǔ)驅(qū)動(dòng)程序
選擇存儲(chǔ)驅(qū)動(dòng)程序
AUFS存儲(chǔ)驅(qū)動(dòng)程序在實(shí)踐中
Btrfs存儲(chǔ)驅(qū)動(dòng)程序在實(shí)踐中
守護(hù)進(jìn)程引用