文末送书啦!| Device Mapper,那些你不知道的Docker核心技术
戳藍字“CSDN云計算”關注我們哦!
接觸Docker 比較早的同學應該知道,Docker 在最開始只能在Ubuntu和Debian等少數的Linux 發行版上運行,并且在這些發行版上默認使用的存儲驅動為AUFS。由于Linux 并未將AUFS的支持納入自己的內核主線(據說是因為AUFS的代碼寫的太爛了,進入內核的事情一直被linus拒絕),因此一段時間后隨著Docker 越發的流行,對于非Ubuntu系列的發行版,比如CentOS,就不能直接使用AUFS 作為Docker 的存儲驅動了。在這種情況下,Device Mapper就被作為一種重要的Docker存儲驅動被提了出來。
Device Mapper 概述
?
Device Mapper 作為linux 中非常重要的一項技術其實早在linux 2.6 這個內核版本的時候就已經被引入到linux之中。簡單說來Device?Mapper就是一個基于linux內核的框架,是linux內核用來將塊設備映射到虛擬設備的一種框架,Device Mapper對linux 上的高級卷管理技術做了進一步的增強,支持許多的高級卷管理技術。Docker 的devicemapper?存儲驅動程序就是基于DeviceMapper 這種框架的自動精簡配置(Thin Provisioning)和精簡配置快照(Thin Provisioning Snapshot)這兩個功能來對Docker 的鏡像和容器進行管理的。
?
Device Mapper 存儲驅動將我們的每一個Docker 容器鏡像都存放在它自身的虛擬設備之上,這些虛擬設備具備自動精簡配置、寫時拷貝和快照等功能。由于Device Mapper 技術工作在塊層面而非文件系統層面,因此Docker 引擎的devicemapper 存儲驅動使用塊設備來進行數據的存儲(包括元數據),而非使用文件系統。
?
不同于AUFS、ext2、ext3、ext4、XFS、NFS等常見的文件系統,Device Mapper 其實并不是一個文件系統。借助Device Mapper 我們可以很方便的根據自己的實際需要制定實現存儲資源的管理策略。當前linux 中常見的邏輯卷管理技術有多種,并非只有Device Mapper,其他常用的比如EVMS(enterprise volume management system)、LVM2(linux volume manager 2 version)以及dmraid(device mapper reid tools)等,和Device Mapper 一樣這幾個工具也是基于邏輯設備映射到物理設備這樣一種機制來實現的。
?????
需要注意的是Device Mapper?工作的級別為塊(block)級別,而不是文件級別,這一點是和文件系統的一個很大的不同點。Device Mapper 從linux 2.6.9這個內核版本開始后就被編譯進了linux 的內核之中,因此所有新于linux 2.6.9這個內核的發行版中都會內置Device Mapper 這個存儲驅動。雖然從linux2.6.9開始Device Mapper已經被內置到了linux的內核之中,但默認情況下是不能在linux上進行直接的使用的(比如CentOS 發行版的linux中默認使用的存儲驅動是overlay),一般需要進行一些配置之后才能在Docker之中進行使用。?
?
Device Mapper 為實現存儲資源管理的塊設備驅動專門設計開發了一個定制的內核架構,該內核架構采用高度模塊化的設計模式。Device?Mapper 包含三個主要的概念,這三個概念對應三個名詞,分別是:Mapped Device(也稱映射設備)、Mapping Table(也稱映射表)以及Target Device(也稱目標設備)。映射設備就是我們上文中已經提過的對外提供的邏輯設備,映射設備在向下尋找時必須找到支撐的目標設備;映射表用于存儲映射設備和目標設備的映射關系;目標設備比較靈活,可以是物理設備也可以是映射設備。其中映射表在內核空間中創建后再傳遞到內核空間。
?
簡單說來Mapped Device 可以理解為linux的內核對外提供的一種邏輯設備,是一種邏輯上的抽象。Mapped Device 借助Mapping Table 的映射關系和Target Device 建立映射。其中,Mapped Device 對應的邏輯設備都會對應一個物理設備,Target Device 所表示的是Mapped Device 所映射的物理空間段。
?
需要注意的是Mapping Table 中的地址和offset 以linux磁盤的扇區(512字節)作為基本單位,所以當我們看到128時,實際代表其實是128 * 512字節。Device Mapper 存儲驅動中的Mapping Table?里有邏輯的起始地址、地址范圍、所在物理設備的地址偏移量以及Target 類型等數據。Mapped Device 支持映射一個或者多個物理設備到Target Device,同時也支持嵌套形式的映射(類似linux文件系統中目錄里面還可以再有目錄或者文件),比如將一個Device Mapper 映射到其他的Device Mapper,理論上可以無限嵌套下去。
?
Device Mapper 借助linux 內核中眾多的模塊化的Target 驅動插件對I/O請求進行過濾或者進行重定向。有些同學可能會問為什么要在內核中提供這么多的內核插件,這樣設計的依據是什么? 最開始我也有同樣的疑惑,后來專門花時間確認了下,最終查到這樣的設計其實依據的是linux內核中策略和機制分離的原則。目前已經提供的插件包括鏡像、快照、加密、多路徑以及軟raid等。
?
上文中我們講過,Device Mapper 其實就是一個框架(區別于常見的文件系統),我們可以根據自己的業務的實際需要在這個框架上添加自己需要的各種各樣的策略,這一點上有些類似面向對象中的策略模式。比較知名的插件比如Docker中DeviceMapper 里面最重要的模塊--精簡配置快照模塊(thin provisioning snapshot)。
?
簡單說來,Device Mapper 就是對外提供一個虛擬設備供用戶進行使用,這塊設備可以通過映射表找到相應的地址,這個地址可以指向一個設備,也可指向到一個虛擬設備。
Docker 中默認使用的存儲驅動可以借助命令docker info 直接進行查看,以CentOS 發行版為例:
?
[root@localhost ~]# docker info
Containers: 13
?Running: 0
?Paused: 0
?Stopped: 13
Images: 13
Server Version: 1.10.3
Storage Driver: devicemapper
?Pool Name: docker-8:3-404820673-pool
?Pool Blocksize: 65.54 kB
?Base Device Size: 10.74 GB
?Backing Filesystem: xfs
?Data file: /dev/loop0
?Metadata file: /dev/loop1
?Data Space Used: 13.49 GB
?Data Space Total: 107.4 GB
?Data Space Available: 81.52 GB
?Metadata Space Used: 12.5 MB
?Metadata Space Total: 2.147 GB
?Metadata Space Available: 2.135 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
?WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
?Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
?Library Version: 1.02.107-RHEL7 (2016-06-09)
Execution Driver: native-0.2
Logging Driver: journald
Plugins:
?Volume: local
?Network: null host bridge
Kernel Version: 3.10.0-327.36.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 2
CPUs: 4
Total Memory: 1.781 GiB
Name: localhost.localdomain
ID: V7HM:XRBY:P6ZU:SGWK:J52L:VYOY:UK6L:TR45:YJRC:SZBS:DQRF:CFP5
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Registries: docker.io (secure)
[root@localhost ~]#
?
通過上面的命令輸出我們可以看出,Docker host 使用的默認存儲驅動為devicemapper。另外從結果中Data loop file: /var/lib/docker/devicemapper/devicemapper/data和Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata 這兩個文件可以看出Data loop file 和Metadata loop file 是存在的,且這兩個文件都是loopback映射的稀疏文件,具體可以判斷使用了loop-lvm模式。
?
Device Mapper 核心技術
?
1.?空間劃分
?
Device Mapper 的空間主要分為兩部分:用戶空間、內核空間。
?
(1)?用戶空間
在Device Mapper中用戶空間這部分主要負責完成的是配置具體的策略和控制邏輯,這樣描述可能比較籠統,舉個例子,比如我們的邏輯設備需要和哪些物理設備建立映射,以及這種映射的具體建立方式等。
Device Mapper 用戶空間和內核空間中包含device mapper 庫和工具dmsrtup,會對Device Mapper 中用戶空間中的device mapper 設備的創建和刪除等操作進行二次封裝。
?
(2)?內核空間
?
Device Mapper中內核空間主要做的工作就是提供機制,這些機制的作用就是完成上面說的用戶空間策略所需要的一些機制,比如過濾和重定向I/O請求。Device Mapper 內核空間中通過不同的驅動插件來將I/O請求轉發到目的設備上面。
?
2.?自動精簡配置
?
自動精簡配置是隸屬于虛擬化中的一種技術,類似公有云中的資源超售,邏輯上可以提供很多的資源,似乎可以無限無限分配資源,但實際上用多少分配多少,目的就是為了提高資源的使用率。結合超售的概念再通過下面的一張圖我們就可以清楚Device Mapper 中自動精簡配置到底是怎么一回事。
?
3.?精簡配置快照
說了那么多,Docker 到底是怎么使用自動精簡配置來實現Docker 容器鏡像的分層的呢??答案是Docker 借助了自動精簡配置中的快照技術,下面我們會具體看下自動精簡配置中是如何實現快照這個功能的。
?
# 新建數據文件demo-data.img,在此直接以dd快速新建一下
[root@localhost ~]# dd if=/dev/zero of=demo-data.img bs=1M count=1 seek=10M
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.00111645 s, 939 MB/s
?
# 新建元數據文件demo-meta.data.img
[root@localhost ~]# dd if=/dev/zero of=demo-meta.data.img bs=1M count=1 seek=1G
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.00169702 s, 618 MB/s
?
創建完成后為兩個文件各自創建一個環回設備。
?
# 為demo-data.img 文件新建環回設備
[root@localhost ~]# losetup /dev/loop0 demo-data.img
?
# 為demo-meta.data.img文件新建環回設備
[root@localhost ~]# losetup /dev/loop1 demo-meta.data.img
?
# 查看設備
[root@localhost ~]# losetup -a
/dev/loop0: [2051]:134991410 (/var/lib/docker/devicemapper/devicemapper/data)
/dev/loop1: [2051]:134991411 (/var/lib/docker/devicemapper/devicemapper/metadata)
?
# 新建一個自動精簡配置的池,起始sector 0,最小可分配sectro數128
[root@localhost ~]# dmsetup create demo-thin-pool --table "0 20971522 thin-pool /dev/loop1 /dev/loop0 128 65536 1 skip_block_zeroing"
?
# 正常的話可以看到新建的DeviceMapper設備
[root@localhost ~]# ls /dev/mapper/
control ?docker-8:3-404820673-pool ?demo-thin-pool
?
#?格式化之前需要先新建一個自動精簡配置的卷
[root@localhost ~]# dmsetup message /dev/mapper/demo-thin-pool 0 "create_thin 0"
?
注:上面命令引號部分中,create_thin 為關鍵字,0為我們為這個卷分配額設備id。
?
# 為上面新建的卷創建一個可以掛載的設備
[root@localhost ~]# dmsetup create demo-thin-volume-1 --table "0 2097152 thin /dev/mapper/demo-thin-pool 0"
?
后面需要掛載我們新加的設備,但是在掛載之前我們需要先對新加的設備進行格式化。
?
# 格式化卷,格式化的文件系統在此我們以ext4為例
[root@localhost ~]# mkfs.ext4 /dev/mapper/demo-thin-volume-1
?
格式化完成之后,后面就可以進行掛載操作了。
?
# 新建掛載點目錄,在此我們以dm為例
[root@localhost ~]# mkdir /mnt/dm
?
# 將上面我們格式化好的卷掛載到掛載點dm
[root@localhost ~]# mount /dev/mapper/demo-thin-volume-1 /mnt/dm
?
下面我們在我們的device mapper設備中添加一個文件,并寫入一些測試的數據。
?
# 新建測試文件
[root@localhost ~]# echo "demo thin-vloume" > /mnt/dm/demo
[root@localhost ~]# cat /mnt/dm/demo
demo thin-vloume
?
新建的DeviceMapper設備掛載完成之后,下面我們開始處理快照的事情。
?
# 向demo-thin-pool 發送創建快照的消息
[root@localhost ~]# dmsetup message /dev/mapper/demo-thin-pool 0 "create_snap 1 0"
?
# 創建設備,名稱此處以demosnap為例
[root@localhost ~]# dmsetup create demosnap --table "0 2097152 thin /dev/mapper/demo-thin-pool 1"
?
# 為demosnap 創建掛載點目錄
[root@localhost ~]# mkdir /mnt/demosnap
?
# 掛載demosnap 到新建的掛載點目錄
[root@localhost ~]# mount /dev/mapper/demosnap /mnt/demosnap
?
# 查看快照里是否有我們前面新建的文件demo
[root@localhost ~]# ls /mnt/demosnap
demo
?
# 查看文件內容是否和之前的一致
[root@localhost ~]# cat /mnt/demosnap/demo
demo thin-vloume
從結果可以看出鏡像中可以看到我們前面新建的文件,且我們這里新建的鏡像中的文件以及文件中的數據和源數據是一樣的,下面我們看下鏡像到底有沒有分層。要驗證這個問題,我們只需要修改下快照的數據,然后看下源數據是否會被同樣的修改掉即可。
?
# 修改快照中的文件demo中的數據
[root@localhost ~]# echo "demo thin-volume snap" > /mnt/demosnap/demo
?
# 快照中添加一個新的文件
[root@localhost ~]# echo "demo thin-volume snap2" > /mnt/demosnap/demo2
?
# 查看當前快照數據
[root@localhost ~]# ls /mnt/demosnap/
demo ?demo2
?
# 查看/mnt/dm下數據是否發生變化
[root@localhost ~]# ls /mnt/dm/
demo
?
從結果看快照中新增的文件demo2并未出現,我們再看下demo文件的數據是否被修改掉。
?
[root@localhost ~]# cat /mnt/dm/demo
demo thin-vloume
從結果看demo文件中的數據并未因為鏡像中的修改而被修改,可見確實是進行了分層。
?
在此我們只建了一個快照,因此鏡像的分層現象看著并不是很明顯,我們可以再在剛剛新建的鏡像上再添加一個鏡像,這樣就可以比較明確的看到分層鏡像了。
?
# 創建新鏡像demosnap2
[root@localhost ~]# dmsetup message /dev/mapper/demo-thin-pool 0 "create_snap 2 1"
[root@localhost ~]# dmsetup create demosnap2 --table "0 2097152 thin /dev/mapper/demo-thin-pool 2"
?
# 新建新鏡像的掛載點目錄
[root@localhost ~]# mkdir /mnt/demosnap2
?
# 掛載新鏡像到新的掛載點上
[root@localhost ~]# mount /dev/mapper/demosnap2 ?/mnt/demosnap2
?
# 查看新鏡像的數據
[root@localhost ~]# ls /mnt/demosnap2
demo2
?
可以參考上文中對第一個鏡像的操作來操作下第二個鏡像,看下現象是否是一樣。
?
以上就是對DeviceMapper 核心原理的一個解釋和基本的操作演示,下文中我們會看下DeviceMapper 在Docker 中具體是如何使用的。
Docker 中的Device?Mapper核心技術
?
Docker 中的devicemapper 存儲驅動有三個核心概念,分別是:寫時復制(copy on write)、自動精簡配置(thin provisioning)以及快照(snapshot)。其中自動精簡配置和快照技術上文中在講Device Mapper 核心原理時我們已經說過,這里我們先簡單介紹下寫時復制技術。
?
1.?寫時復制原理
?
寫時復制技術是Docker 容器中非常核心的一個功能,Docker 容器運行后,當我們需要去修改一個不在最頂層分支中的文件時,這個時候最頂層的分支需要先將需要修改的文件從其所在的層拷貝到最頂層的分支,然后再對拷貝上上來的文件進行修改,文件修改完成后位于底層分支的文件內容并未發生改變,這種方式就是寫時復制技術,也稱COW。
?
當我們在最上層的分支中去刪除從底層分支拷貝上來的文件時,此時文件文件并沒有被實際刪除,只是在最頂層的分支中對被刪文件進行了重命名和隱藏的操作,因此被執行刪除操作的文件實際并沒有被刪除,只是不可見了。
?
如下圖所示,我們看到的文件file1 其實是鏡像層中branch0分支中的文件:
?
當我們需要修改文件file1時,Device Mapper 中的寫時復制技術會將文件file1直接拷貝到最上層的top branch,然后再進行修改,即我們修改的其實是從底層拷貝的文件:
?
當我們需要刪除文件file1時,由于文件file1是鏡像層的文件,此時會在容器最上層中創建一個.wh開頭的隱藏文件,從而將文件file1隱藏掉,所以文件file1并未被刪除掉,這樣也就保證了鏡像層數據的完整性和復用性。
?
有些同學可能會問,每次修改底層的文件時都需要先從底層將文件復制上來,是否會影響容器的性能?答案是會影響,所以一般建議對于容器中需要經常修改的文件不要放到底層的鏡像層中,可以在容器運行起來后再將需要頻繁修改的文件添加到容器中。
?
2.?Docker DeviceMapper 實踐
?
devicemapper 是紅帽系列linux發行版上的默認存儲驅動,它有兩種配置模式:loop-lvm以及direct-lvm。
?
我們知道使用Device Mapper 作為Docker 的存儲驅動時,默認情況下使用的配置模式一般是loop-lvm,loop-lvm 使用操作系統層面離散的文件來構建精簡池。Loop-lvm 模式會借助服務器中空閑的文件來構建存儲池,這些存儲池主要提供給Docker 容器鏡像和Docker 容器快照進行使用。Loop-lvm 在使用上非常簡單,無需額外的配置,開箱即可使用,不過一般不太建議在生產環境中使用lvm模式,Docker 官方明文說明不推薦使用該模式:
?
WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
?
direct-lvm 是Docker 官方推薦的生產環境中可以使用的模式,該模式使用塊設備來構建精簡池來存放鏡像和Docker容器的數據。
?
早期使用direct-lvm 模式時一般需要技術人員自己手動配置lvm,所有的配置項都需要自己逐個手動的添加,整個過程相對比較繁瑣,好在從Docker 17.06開始Docker 已經支持了自動化配置direct-lvm(需要注意單個塊設備的限制)。
?
(1)?direct-lvm 模式自動配置
需要注意的是direct-lvm目前還只能支持1個塊設備,如果需要使用多個塊設備,這個時候direct-lvm 自動配置就不適合了,需要進行手動配置。
direct-lvm 模式自動配置的示例配置文件位置為:/usr/lib/docker-storage-setup/docker-storage-setup,可以在此查看一些常見配置的詳細說明,另外也可通過docker storage setup 的linux man 手冊來查看具體的使用文檔和配置項說明,在此筆者整理了一下幾個常用的關鍵選項:
?
參數名稱 | 參數說明 | 是否必填 | 默認值 | 參數示例值 |
directlvm_device | 將要配置的direct-lvm的塊設備的路徑 | yes | directlvm_device=“/dev/your-device” | |
directlvm_device_force | 指定需要創建的data thin pool 的大小 | no | 95 | thinp_percent=95 |
thinp_autoextend_percen | 指定需要創建的metadata thin pool的大小 | no | 1 | thinp_metapercent=1 |
thinp_autoextend_threshold | 指定自動擴容的百分比,其中100代表disable,百分比最小為50 | no | 80 | thinp_autoextend_threshold=80 |
t thinp_metapercent | 指定每次擴容的大小,即實際值,上面的為百分比。需要注意的是也是100代表disable | no | 20 | thinp_autoextend_percent=20 |
thinp_percent | 當需要使用的塊設備中已經有文件系統時,是否需要對該 設備執行格式化 | no | false | directlvm_device_force=true |
?
參數的具體配置路徑為:/etc/docker/daemon.json,上面表格中參數對應的示例配置如下:
?
[root@localhost ~]# cat /etc/docker/daemon.json
{
??"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"
??]
}
?
以上便是對Docker device mapper 中direct-lvm 模式自動配置的一個簡單的描述,下面我們一起看下direct-lvm 模式的手動配置。
?
(2)?direct-lvm 手動配置
?
a.?停止Docker daemon
?
????進行手動配置前我們需要確保服務器上的Docker Daemon 是停止的。
?
????# 停止Docker 的守護進程
[root@localhost ~]# systemctl stop docker
?
# 查看Docker 守護進程狀態
[root@localhost ~]# systemctl status docker
● docker.service - Docker Application Container Engine
???Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
???Active: inactive (dead) since Thu 2019-06-27 20:11:59 PDT; 6s ago
?????Docs: http://docs.docker.com
??Process: 1505 ExecStart=/usr/bin/docker-current daemon --exec-opt native.cgroupdriver=systemd $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_NETWORK_OPTIONS $ADD_REGISTRY $BLOCK_REGISTRY $INSECURE_REGISTRY (code=exited, status=0/SUCCESS)
?Main PID: 1505 (code=exited, status=0/SUCCESS)
?
Jun 25 18:38:24 localhost.localdomain docker-current[1505]: .............time="2019-06-25T18:38:24.934695010-07:00" level=error m...nted"
Jun 25 18:38:24 localhost.localdomain docker-current[1505]: time="2019-06-25T18:38:24.936034267-07:00" level=error msg="Error unm...nted"
Jun 25 18:38:25 localhost.localdomain docker-current[1505]: time="2019-06-25T18:38:25.003155308-07:00" level=info msg="Loading co...one."
Jun 25 18:38:25 localhost.localdomain docker-current[1505]: time="2019-06-25T18:38:25.003207642-07:00" level=info msg="Daemon has...tion"
Jun 25 18:38:25 localhost.localdomain docker-current[1505]: time="2019-06-25T18:38:25.003244444-07:00" level=info msg="Docker dae....10.3
Jun 25 18:38:25 localhost.localdomain systemd[1]: Started Docker Application Container Engine.
Jun 25 18:38:25 localhost.localdomain docker-current[1505]: time="2019-06-25T18:38:25.009717428-07:00" level=info msg="API listen...sock"
Jun 27 20:11:59 localhost.localdomain systemd[1]: Stopping Docker Application Container Engine...
Jun 27 20:11:59 localhost.localdomain docker-current[1505]: time="2019-06-27T20:11:59.755131077-07:00" level=info msg="Processing...ted'"
Jun 27 20:11:59 localhost.localdomain systemd[1]: Stopped Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
?
b.?部署lVM2
?
???????LVM2 不是單個軟件,是一個包含管理linux上邏輯卷的用戶空間工具集。
?
???????# 安裝device mapper persistent data
???????[root@localhost ~]# yum install -y device-mapper-persistent-data
?
???????# 安裝lvm2
???????[root@localhost ~]# yum install -y lvm2
?
c.?卷管理
?
上面的工具集安裝完成后接下來就是對卷的管理操作,過程和我們日常使用lvm基本一致。
?
# 新建物理卷
[root@localhost ~]# pvcreate /dev/sdb
??Physical volume "/dev/sdb" successfully created.
?
# 新建一個名為docker 卷組
[root@localhost ~]# vgcreate docker /dev/sdb
??Volume group "docker" successfully created
?
# 新建存儲池,此處存儲池名稱以thinpool 為例
[root@localhost ~]# ?lvcreate --wipesignatures y -n thinpool docker -l 95%VG
??Logical volume "thinpool" created.
參數95%代表設置存儲池的大小為卷組的尺寸的90%,的10%的空間可以用于后續的數據的自動擴展和元數據的存儲。
?
# 新建元數據存儲池,在此我們只分配1%的空間
[root@localhost ~]# lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
??Logical volume "thinpoolmeta" created.
?
以上我們就準備好了存儲池和元數據的存儲池,接下來我們將存儲池轉換為thinpool格式。
?
# 存儲池格式轉換為thinpool 格式
[root@localhost ~]# lvconvert -y --zero n -c 512K --thinpool docker/thinpool --poolmetadata docker/thinpoolmeta
??Thin pool volume with chunk size 512.00 KiB can address at most 126.50 TiB of data.
??WARNING: Converting 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 and docker/thinpoolmeta to thin pool.
?
# 配置存儲池的自動擴展
[root@localhost ~]# vim /etc/lvm/profile/docker-thinpool.profile
?
設置參數thin_pool_autoextend_threshold、thin_pool_autoextend_percent,這兩個參數的含義在direct-lvm 模式自動配置中已經描述過,在此我們不再贅述。
?
示例配置:
?
[root@localhost ~]# cat /etc/lvm/profile/docker-thinpool.profile
activation{
??thin_pool_autoextend_threshold = 80
??thin_pool_autoextend_percent = 20
}
?
# 新lvm 配置生效
[root@localhost ~]# lvchange --metadataprofile docker-thinpool docker/thinpool
??Logical volume docker/thinpool changed.
?
# 通過卷信息查看邏輯卷是否受監控
[root@localhost ~]# lvs -o+seg_monitor
??LV ??????VG ????Attr ??????LSize ??Pool Origin Data% ?Meta% ?Move Log Cpy%Sync Convert Monitor ?
??thinpool docker twi-a-t--- <19.00g ????????????0.00 ??0.03 ????????????????????????????monitored
?
# 備份Docker 的數據
[root@localhost ~]# mkdir /var/lib/docker.bk
[root@localhost ~]# mv /var/lib/docker/* /var/lib/docker.bk
?
修改配置文件/etc/docker/daemon.json,打開參數dm.use_deferred_removal、dm.use_deferred_deletion,防止意外產生的掛載點泄露問題。
[root@localhost ~]# cat /etc/docker/daemon.json
{
????"storage-driver": "devicemapper",
????"storage-opts": [
????"dm.thinpooldev=/dev/mapper/docker-thinpool",
????"dm.use_deferred_removal=true",
????"dm.use_deferred_deletion=true"
????]
}
?
# 查看服務器上的devicemapper 結構,查看上面創建的設備文件和存儲池是否就緒
[root@localhost ~]# lsblk
NAME ???????????????????MAJ:MIN RM ?SIZE RO TYPE MOUNTPOINT
sda ??????????????????????8:0 ???0 ?100G ?0 disk
├─sda1 ???????????????????8:1 ???0 ?300M ?0 part /boot
├─sda2 ???????????????????8:2 ???0 ???2G ?0 part [SWAP]
└─sda3 ???????????????????8:3 ???0 97.7G ?0 part /
sdb ??????????????????????8:16 ??0 ??20G ?0 disk
├─docker-thinpool_tmeta 253:1 ???0 ?204M ?0 lvm ?
│ └─docker-thinpool ????253:3 ???0 ??19G ?0 lvm ?
└─docker-thinpool_tdata 253:2 ???0 ??19G ?0 lvm ?
??└─docker-thinpool ????253:3 ???0 ??19G ?0 lvm ?
sr0 ?????????????????????11:0 ???1 1024M ?0 rom ?
?
從查詢結果可以看出docker-thinpool 存儲池在data 和 metadata兩個設備之上。一般建議的存儲池的命名規則為:Docker-主設備號:二級設備號-inode號-pool。
?
需要注意的是,生產環境中一般不建議過于依賴lvm的自動擴展,雖然大部分情況下卷組可以自動進行擴展,但是有時候卷組可能會被塞滿。所以在生產環境中需要根據自己的實際需要降低對自動擴展的依賴,同時建議添加對卷空間使用量的監控。
?
福利來了!!!
評論區留下你對容器的理解與看法,
我們將抽取點贊數最高的三位讀者,
送出以下精美圖書一份
活動時間截止7月11日18:00
內容簡介:本書將以企業落地實踐為切入點,分享作為終端用戶的企業在關鍵業務環境中落地使用 Docker 及 Kubernetes 技術的經驗和心得。內容既有扎實的技術實現方法,又有各行業容器技術企業級落地實踐的深度解讀。
內容簡介:?本書給開發者、架構師、運維工程師提供了富有實踐價值的技術資料。閱讀本書,將學習到如何使用以容器為中心的方法,幫助團隊交付高質量軟件,而這都是基于紅帽的云化PaaS 平臺OpenShift 來自動服務的。本書詳細介紹了如何配置容器應用、如何使用OpenShift的開發運維工具管理Kubernetes 集群。
內容簡介:?本書提供幾十個基于場景的演示,介紹使用OpenDaylight可以解決的基礎案例,包括討論虛擬用戶邊緣、動態互連、網絡虛擬化、虛擬核心和聚合、意圖和策略聯網、自定義OpenDaylight容器、認證和授權。經典場景的介紹,能幫助讀者快速學習和掌握OpenDaylight相關知識。
福利
掃描添加小編微信,備注“姓名+公司職位”,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
推薦閱讀:
OpenStack入門科普,看這一篇就夠啦!
優秀工程師必備的一項技能,你解鎖了嗎?
被竇唯夸獎“音樂好”的刺猬樂隊成員竟然是程序員
喬納森離開蘋果;李彥宏被潑水;Windows 公開 Linux 內核源代碼 | 開發者周刊
以太坊暗網? 這群北大才子做到了...
智能文本信息抽取算法的進階與應用
人工智能六十年技術簡史
總結
以上是生活随笔為你收集整理的文末送书啦!| Device Mapper,那些你不知道的Docker核心技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软发布 Azure 物联网安全中心;阿
- 下一篇: 林芝地区驾车到昌吉回族自治州车师古道走哪