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