使用DeviceMapper存儲驅(qū)動(dòng)
Device Mapper是一個(gè)基于內(nèi)核的框架嘴纺,支持Linux上的許多高級卷管理技術(shù)。Docker的 devicemapper 存儲驅(qū)動(dòng)利用此框架的精簡配置和快照功能進(jìn)行及你想和容器的管理冬竟。本文將Device Mapper存儲驅(qū)動(dòng)稱為 devicemapper, 并將內(nèi)核框架稱為 Device Mapper.
對于支持它的系統(tǒng)哼御,devicemapper已經(jīng)被包含在Linux內(nèi)核中改艇。但是,還需要一些特殊配置才能用于Docker研儒。比如豫缨,在RHEL或者CentOS的常規(guī)安裝中,docker默認(rèn)設(shè)置為overlay,而且不是一個(gè)被支持的配置端朵。
devicemapper驅(qū)動(dòng)使用專用于Docker的塊設(shè)備好芭,并在塊級別而不是文件級別運(yùn)行。這些設(shè)備可以通過在你的Docker宿主機(jī)添加屋里存儲設(shè)備來擴(kuò)展逸月,而且在操作系統(tǒng)級別比使用文件系統(tǒng)表現(xiàn)更好栓撞。
一、前言
- devicemapper 存儲驅(qū)動(dòng)是Docker EE以及RHEL碗硬、CentOS和Oracle Linux支持的商業(yè)版Docker引擎(CS-Engine))唯一支持的存儲驅(qū)動(dòng)瓤湘。參考Product compatibility matrix。
- devicemapper 還支持CentOs恩尾、Fedora弛说、Ubuntu和Debian上跑的Docker CE。
- 在你本地系統(tǒng)上改變存儲驅(qū)動(dòng)翰意,將導(dǎo)致你已經(jīng)創(chuàng)建的容器無法訪問木人。使用docker save來保存容器,并將你的鏡像推到Docker Hub或者私有倉庫冀偶,不然就要重新制做這些容器和鏡像了醒第。
二、為Docker配置 devicemapper存儲驅(qū)動(dòng)
在下面步驟之前进鸠,一定要先閱讀前言
2.1 測試環(huán)境下配置loop-lvm
這種配置只能用于線下測試環(huán)境稠曼,回環(huán)設(shè)備效率低下并且更耗費(fèi)資源,并且要求你在磁盤創(chuàng)建合適大小的文件客年。他們還能引入競爭條件霞幅。因設(shè)置簡單漠吻,經(jīng)常用于測試環(huán)境。生產(chǎn)環(huán)境的配置參考下節(jié)dirct-lvm
- stop Docker
$ sudo systemctl stop docker
- 編輯/etc/docker/daemon.json 司恳。確保文件為空途乃,并添加下面內(nèi)容:
{
"storage-driver": "devicemapper"
}
- start docker
$ sudo systemctl start docker
- 核查docker daemon使用了devicemapper存儲驅(qū)動(dòng)耍共。使用docker info命令并查看Storage Driver。
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.03.2-ce
Storage Driver: devicemapper
Pool Name: docker-253:1-264951-pool
Pool Blocksize: 65.54 kB
Base Device Size: 21.47 GB
Backing Filesystem: xfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 22.53 GB
Data Space Total: 107.4 GB
Data Space Available: 8.399 GB
Metadata Space Used: 37.46 MB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.11 GB
Thin Pool Minimum Free Space: 10.74 GB
Udev Sync Supported: true
Deferred Removal Enabled: false
Deferred Deletion Enabled: false
Deferred Deleted Device Count: 0
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Library Version: 1.02.135-RHEL7 (2016-11-16)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-514.26.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.26 GiB
Name: inf-wpc03.iwm.name
ID: F67X:HSDI:FN2N:M3LM:TQYF:BRCQ:UQRT:RM2M:7AS6:Q4ZY:A4EP:TV47
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://2q6zc99h.mirror.aliyuncs.com
Live Restore Enabled: false
WARNING: devicemapper: usage of loopback devices is strongly discouraged for production use.
Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
宿主機(jī)使用loop-lvm模式铅鲤,并不能用于生產(chǎn)環(huán)境的系統(tǒng)中划提。事實(shí)上Data loop file和一個(gè)Metadata loop file都在 /var/lib/docker/devicemapper文件夾下枫弟。他們是回環(huán)安裝的稀疏文件邢享。生產(chǎn)環(huán)境中還是要使用下節(jié)中的dirct-lvm。
2.2 在生產(chǎn)環(huán)境配置dirct-lvm
生產(chǎn)環(huán)境的主機(jī)使用devicemapper存儲驅(qū)動(dòng)時(shí)淡诗,必須采用dirct-lvm模式骇塘。這種模式使用塊設(shè)備創(chuàng)建精簡池。它比回環(huán)設(shè)備更快韩容,更高效的使用系統(tǒng)資源款违,而且塊設(shè)備還可按需增長。但是配置比loop-lvm復(fù)雜許多群凶。
如果你對前言中的條件沒有意見插爹,按照下面步驟配置即可在dirct-lvm模式下使用devicemapper。
??警告:更改存儲驅(qū)動(dòng)將使你在本地的容器破壞掉请梢。使用docker save來保存容器赠尾,并把鏡像推到Docker Hub或者你的私有倉庫,以便恢復(fù)毅弧。
2.2.1 允許Docker配置dirct-lvm模式
在Docker 17.06或更高版本中气嫁,Docker能為你管理塊設(shè)備,簡化direct-lvm模式的配置够坐。這僅適用于新版Docker配置中。你只能使用一個(gè)塊設(shè)備,如果想使用多個(gè)椅寺,可以按照2.2.2節(jié)的步驟配置湃密。已經(jīng)增加了下面的新配置項(xiàng):
選項(xiàng) | 描述 | 必選? | 默認(rèn)值 | 舉例 |
---|---|---|---|---|
dm.directlvm_device | 為direct-lvm配置的塊設(shè)備路徑 | 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è)置合適的配置項(xiàng)甲棍,重啟Docker才能生效。下面是使用了全部配置項(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"
]
}
查尋每一種存儲驅(qū)動(dòng)的所有參數(shù):
重啟docker生效脉课,Docker調(diào)用命令為你配置這些救军。
??警告:在docker為你準(zhǔn)備好塊設(shè)備之后改變這些值是不被支持的财异,并且會導(dǎo)致一些錯(cuò)誤。
你仍然需要執(zhí)行定期維護(hù)任務(wù)(3.1節(jié))唱遭。
2.2.2 手動(dòng)配置dirct-lvm模式
以下過程將創(chuàng)建配置為精簡池的邏輯卷戳寸,以用作存儲池的備份。它假定您有一個(gè)備用塊設(shè)備/dev/xvdf拷泽,并且有足夠的空間來完成任務(wù)疫鹊。你環(huán)境的設(shè)備標(biāo)識符和卷大小可能不同,在下面步驟中需要你需要替換成你自己的變量司致。下面步驟需要確保docker已經(jīng)停止了拆吆。
- 確定要使用的塊設(shè)備。該設(shè)備將位于/dev/(如/dev/xvdf)下脂矫,并且需要足夠的可用空間來存儲主機(jī)將運(yùn)行的工作負(fù)載的映像和容器層枣耀。固態(tài)硬盤是最理想的選擇。
- stop docker
$ sudo systemctl stop docker
- 安裝下面套裝
- RHEL / CentOS: device-mapper-persistent-data, lvm2, and all dependencies
- Ubuntu / Debian: thin-provisioning-tools, lvm2, and all dependencies
- 根據(jù)第一步在你的塊設(shè)備上創(chuàng)建物理卷庭再。使用pvcreate命令
?? 警告:這一步的操作是毀滅性的捞奕,請百分之百確保你選的是正確的設(shè)備。
$ sudo pvcreate /dev/xvdf
Physical volume "/dev/xvdf" successfully created.
- 在上面設(shè)備創(chuàng)建 docker 卷組拄轻。
$ sudo vgcreate docker /dev/xvdf
Volume group "docker" successfully created
- 使用lvcreate命令創(chuàng)建兩個(gè)名為thinpool和thinpoolmeta的邏輯卷颅围。最后一個(gè)參數(shù)指定可用空間的大小,以便在空間不足時(shí)自動(dòng)擴(kuò)展數(shù)據(jù)或元數(shù)據(jù)恨搓,作為臨時(shí)性措施院促。下面是推薦值:
$ sudo lvcreate --wipesignatures y -n thinpool docker -l 95%VG
Logical volume "thinpool" created.
$ sudo lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
Logical volume "thinpoolmeta" created.
- 使用lvconvert命令將卷轉(zhuǎn)換為精簡池和精簡池元數(shù)據(jù)的存儲位置。
$ sudo lvconvert -y \
--zero n \
-c 512K \
--thinpool docker/thinpool \
--poolmetadata docker/thinpoolmeta
WARNING: Converting logical volume docker/thinpool and docker/thinpoolmeta to
thin pool's data and metadata volumes with metadata wiping.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Converted docker/thinpool to thin pool.
- 通過lvm配置文件配置精簡池的自動(dòng)擴(kuò)展斧抱。
$ sudo vi /etc/lvm/profile/docker-thinpool.profile
- 指定 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)磁盤使用率達(dá)到80%時(shí)夺姑,下面的示例將增加20%的容量墩邀。
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=20
}
保存文件。
- 使用lvchange命令盏浙,激活lvm配置文件
$ sudo lvchange --metadataprofile docker-thinpool docker/thinpool
Logical volume docker/thinpool changed.
- 啟用對主機(jī)上邏輯卷的監(jiān)控眉睹。沒有這一步,即使已經(jīng)存在LVM配置文件废膘,自動(dòng)擴(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
- 如果你之前在這臺機(jī)器上跑過docker,或者/var/lib/docker/存在丐黄,將這個(gè)文件移除以便Docker能使用新LVM來存儲鏡像和容器的內(nèi)容斋配。
$ mkdir /var/lib/docker.bk
$ mv /var/lib/docker/* /var/lib/docker.bk
- 編輯/etc/docker/daemon.json,配置devicemapper需要的配置項(xiàng)。文件內(nèi)容之前為空的話艰争,須如下:
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/docker-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
]
}
- start docker
#systemd:
$ sudo systemctl start docker
#service:
$ sudo service docker start
- 使用docker info 確認(rèn)新的配置
$ docker info
Containers: 53
Running: 50
Paused: 0
Stopped: 3
Images: 206
Server Version: 17.03.2-ce
Storage Driver: devicemapper
Pool Name: docker-thinpool
Pool Blocksize: 524.3 kB
Base Device Size: 21.47 GB
Backing Filesystem: xfs
Data file:
Metadata file:
Data Space Used: 38.18 GB
Data Space Total: 247 GB
Data Space Available: 208.8 GB
Metadata Space Used: 18.11 MB
Metadata Space Total: 5.365 GB
Metadata Space Available: 5.346 GB
Thin Pool Minimum Free Space: 24.7 GB
Udev Sync Supported: true
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.146-RHEL7 (2018-01-22)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-514.26.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.26 GiB
Name: inf-wpc05.iwm.name
ID: 5QUS:EUJY:URZR:ZUYB:K2Q2:DYBA:BDKK:NDN7:W2K5:LLNS:XIUI:VZJW
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://2q6zc99h.mirror.aliyuncs.com
Live Restore Enabled: false
如果你的docker配置正確坏瞄,那么Data file和Metadata file是空的,而且pool ame是 docker-thinpool
- 確認(rèn)完配置正確之后甩卓,你可以移除掉/var/lib/backer.bk
$ rm -rf /var/lib/docker.bk
三鸠匀、管理devicemapper
3.1 管理精簡池
不要僅僅依賴于LVM的自動(dòng)擴(kuò)展。卷組可以自動(dòng)擴(kuò)展逾柿,但是卷仍能寫滿缀棍。你可以使用lvs 或者 lvs -a來管理卷的空余空間。注意使用OS級別的監(jiān)控工具机错,比如Nagios爬范。
你可以使用journalctl 來查看LVM的日志。
$ journalctl -fu dm-event.service
如果你在精簡池中再三遇到錯(cuò)誤弱匪,可以在/etc/docker/daemon.json中 dm.min_free_space 設(shè)置一個(gè)值(一個(gè)百分比)青瀑。實(shí)例中,將它設(shè)置為 10 確绷》ǎ空余空間接近10%時(shí)狱窘,操作錯(cuò)誤會發(fā)出告警杜顺。參考 storage driver options in the Engine daemon reference财搁。
3.2 為running狀態(tài)的設(shè)備擴(kuò)容
你可以為running狀態(tài)的精簡池設(shè)備擴(kuò)容,這對于數(shù)據(jù)邏輯卷或者卷組滿了非常有用躬络。但是操作方法取決于你用了 loop-lvm 還是 direct-lvm 精簡池尖奔。
3.2.1 更改一個(gè)loop-lvm精簡池容量
這個(gè)是測試環(huán)境下的應(yīng)用,略過穷当。 點(diǎn)擊查看原文提茁。
3.2.2 更改一個(gè)dirct-lvm精簡池容量
為了擴(kuò)展一個(gè)dirct-lvm精簡池,首先需要將一個(gè)新的塊設(shè)備添加到Docker宿主機(jī)馁菜,并記下內(nèi)核給它分的名字茴扁。這個(gè)例子中新塊設(shè)備是 /dev/xvdg。
- 收集卷組信息
使用pvdisplay命令來尋找你的精簡池中正用著的物理塊設(shè)備和卷組名字汪疮。
$ sudo pvdisplay |grep 'VG Name'
PV Name /dev/xvdf
VG Name docker
下面的步驟中請注意使用你自己設(shè)備上的卷組名替換例子中的命令峭火。
- 使用vgextend 命令加上步中獲得的 VG Name 和你的新塊設(shè)備名,來擴(kuò)展卷組智嚷。
$ sudo vgextend docker /dev/xvdg
Physical volume "/dev/xvdg" successfully created.
Volume group "docker" successfully extended
- 擴(kuò)展 docker/thinpool 邏輯卷卖丸。這個(gè)命令需要立刻使用100%的卷空間,并不自動(dòng)擴(kuò)展盏道。使用 docker/thinpool_tmeta 來擴(kuò)展元數(shù)據(jù)精簡池(metadata thinpool)稍浆。
$ sudo lvextend -l+100%FREE -n docker/thinpool
Size of logical volume docker/thinpool_tdata changed from 95.00 GiB (24319 extents) to 198.00 GiB (50688 extents).
Logical volume docker/thinpool_tdata successfully resized.
- 使用 docker info 確認(rèn)新的精簡池使用 Data Space Available 。如果你擴(kuò)展了 docker/thinpool_tmeta 邏輯卷,請查看 Metadata Space Available衅枫。
Storage Driver: devicemapper
Pool Name: docker-thinpool
Pool Blocksize: 524.3 kB
Base Device Size: 10.74 GB
Backing Filesystem: xfs
Data file:
Metadata file:
Data Space Used: 212.3 MB
Data Space Total: 212.6 GB
Data Space Available: 212.4 GB
Metadata Space Used: 286.7 kB
Metadata Space Total: 1.07 GB
Metadata Space Available: 1.069 GB
<output truncated>
3.3 重啟后激活devicemapper
如果你重啟了主機(jī)嫁艇,發(fā)現(xiàn) docker 沒啟動(dòng),查看錯(cuò)誤發(fā)現(xiàn)"Non existing device" 弦撩。你需要使用下面命令重新激活邏輯卷裳仆。
sudo lvchange -ay docker/thinpool
四、devicemapper存儲驅(qū)動(dòng)是怎么工作的
??警告:不要直接操作/var/lib/docker/的目錄和文件孤钦。這些文件和目錄是被Docker控制的歧斟。
在操作系統(tǒng)視角,使用 lsblk 命令來查看設(shè)備和其他pools:
$ 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)
當(dāng)你使用 devicemapper ,Docker在這個(gè)精簡池(thinpool)存儲鏡像和鏡像層(layer)內(nèi)容偏形,并通過將他們掛在到 /var/lib/docker/devicemapper/ 的子目錄來對容器開放静袖。