1.thin-provision(精簡配置)與thick-provision(厚配置、厚置備)

1.1 thin-provision與thick-provision定義

    自動精簡配置(Thin Provisioning)是一種優化存儲資源利用的重要技術。有thin-provisioning就相對應的有thick-provisioning。傳統的硬盤、卷就屬於thick-provisioning的思路,一個硬盤、卷有多大,在一開始就把資源都分配出去了,無論是否有數據,資源已經佔用。

image.png 圖片來源:https://blog.51cto.com/jettcai/2149842

    自動精簡配置的核心思想是“按需分配”。它通過虛擬化技術,將一個集中的物理存儲池(Thin Pool)的空間,動態地分配給多個邏輯卷(LVs)或虛擬磁盤。其工作流程可以概括為以下幾個關鍵步驟:     創建存儲池:管理員首先將多塊物理磁盤組成一個大的存儲池(Thin Pool)。     分配邏輯空間:當為應用(如虛擬機、數據庫)創建邏輯卷時,系統會分配一個遠大於當前物理可用空間的虛擬容量(例如100GB),但此時並不佔用實際的物理空間。     動態分配物理空間:當應用開始寫入數據時,存儲系統才從存儲池中分配真正的物理塊來存放這些數據。例如,寫入5GB數據,則實際僅佔用存儲池中的5GB空間。     自動擴容與監控:當存儲池的物理空間使用率達到預警閾值(如90%)時,系統會發出警報,甚至能自動擴展存儲池的物理容量(通過添加新硬盤),確保應用不會因空間不足而中斷。

1.2 thin-provisioning使用限制與注意事項

    儘管自動精簡配置優勢明顯,但它並非萬能鑰匙,在使用時需要注意以下幾點:     空間用盡風險:最大的風險在於所有精簡卷共享的物理存儲池被耗盡。如果多個應用同時寫入大量數據,可能導致存儲池快速滿額,進而使所有依賴該池的應用不可用。因此,必須建立嚴格的監控和預警機制。     性能考慮:由於物理空間是動態分配的,寫入操作可能涉及額外的元數據更新和空間分配開銷,在極端高併發或碎片化嚴重的寫入場景下,性能可能略低於厚配置。對於要求數據物理連續性強或I/O延遲極其敏感的應用需謹慎評估。     特定文件系統的影響:某些文件系統(如NTFS)在刪除數據後,需要存儲控制器進行“回收”操作才能釋放空間,這會增加控制器的額外開銷。     數據刪除與回收:在精簡配置環境中,從客户端(如虛擬機)內部刪除文件,通常不會立即在底層物理存儲池中釋放出空間。

2.docker的存儲配置overlay與dm

2.1 什麼是overlay

    在計算機領域,Overlay​ 的核心思想是 “層疊”​ 或 “疊加”。存儲和網絡裏面都有overlay。     網絡領域:underlay是指真實的物理網絡/存儲基礎設施,overlay構建在底層之上的邏輯虛擬網絡/存儲層,例如vxlan、容器網絡(Calico, Flannel)。     存儲領域:在容器技術中,Overlay 思想最典型的體現是 OverlayFS​ 這類聯合文件系統。它的目標是高效地讓多個容器共享同一個基礎鏡像,同時擁有自己獨立的可寫空。OverlayFS 將兩個目錄(層)“疊加”成一個統一的視圖。下層的只讀目錄(lowerdir)通常是基礎鏡像,上層的可寫目錄(upperdir)屬於容器實例。最終,用户看到的是一個合併後的目錄(merged)。當容器需要修改一個來自基礎鏡像的文件時,OverlayFS 會執行“寫時複製”,先將文件複製到容器的可寫層,再進行修改。這樣,既節省了存儲空間,又保證了容器間的隔離性。

2.2 對於overlay2與thin-pool在docker中的應用

    將 Docker 存儲驅動配置為 overlay(或其升級版 overlay2),與使用 devicemapper相比,在性能、資源消耗和工作原理上會有顯著不同。overlay2是目前大多數場景下的推薦選擇。<br>     對比容器存儲驅動 overlay2和 devicemapper的主要差異:

特性維度 OverlayFS (主要指 overlay2) Devicemapper
工作原理​ 文件級寫時複製 (CoW) 塊級寫時複製 (CoW)
分層結構​ 通過聯合掛載實現多層疊加 使用快照(snapshot)和精簡池(thin pool)
性能特點​ 容器啓動快,內存使用高效(支持頁緩存共享 寫入性能可能更穩定,尤其是大文件
操作粒度​ 整個文件 數據塊(默認64KB)
修改流程​ 複製整個文件到可寫層,再修改 僅複製包含修改內容的數據塊到可寫層,再修改
存儲效率​ 鏡像層共享,節省空間 塊級操作,可能存在空間開銷
配置與維護​ 配置相對簡單,依賴內核支持 配置可能更復雜,需管理存儲池和快照
適用場景​ 通用場景、高密度容器部署(如PaaS) 對塊級存儲管理有特定要求的場景

當需要頻繁修改一個大型文件中的一小部分內容時,塊級操作的優勢最為明顯。例如,更新一個幾GB的數據庫文件中的幾條記錄,或者修改一個大型日誌文件的某些部分。在這種場景下,文件級操作需要複製整個GB級別的文件,而Devicemapper只需要複製被修改數據所在的幾個64KB的塊,這在I/O操作量和時間延遲上的優勢是巨大的。 Devicemapper的一個潛在缺點是,它不像一些文件級驅動那樣支持內存中的頁緩存共享。如果多個容器運行基於同一個鏡像的實例,每個容器都可能將所需的塊單獨加載到內存中,可能導致更高的內存使用量。

    深入解析 OverlayFS     OverlayFS 是一種聯合文件系統,它通過聯合掛載的方式,將多個目錄(稱為層)疊加起來,呈現為一個統一的視圖。在 Docker 中,這通常包括一個只讀的鏡像層(lowerdir)和一個可讀寫的容器層(upperdir),最終通過 merged​ 目錄展示給容器使用。     寫操作的特點:當容器首次修改一個存在於鏡像層中的文件時,OverlayFS 會執行 copy_up操作,將整個文件從鏡像層複製到容器層,然後進行修改。這意味着即使只修改大文件的一小部分,也會複製整個文件。不過,這個操作只發生一次。

    Devicemapper 的工作方式     Devicemapper 則在塊設備級別進行操作。它通常會在一個預先分配的存儲池(thin pool)中為鏡像和容器創建快照(snapshots)。每個容器都是其基礎鏡像的一個可寫快照。     塊級操作意味着 Devicemapper 在處理文件寫入時,是按數據塊(block)進行復制和修改的,這在頻繁修改大文件時可能有一定優勢。     但它的配置相對複雜,過去在某些配置下(如使用 loopback 模式)存在性能和穩定性問題。雖然基於 direct-lvm的配置能改善這些問題,但增加了管理複雜度。

2.3 docker中的devicemapper與內核中的device mapper

    為了快速澄清這個概念,我們可以先看下面這個表格,它清晰地展示了二者的關係:

特性 Linux Device Mapper (內核框架)​ Docker devicemapper (存儲驅動)​
角色與範圍​ 一個通用、強大的塊設備映射框架,提供構建各種存儲虛擬化的基礎能力。 一個具體應用,專門為滿足Docker鏡像分層與容器隔離需求而設計。
技術核心​ 依賴不同的Target Driver插件實現不同功能,例如:線性(linear)、條帶化(striped)、快照(snapshot)、精簡配置(thin-provisioning)等。 專門且固定地使用 Thin-Provisioning Snapshot(精簡配置快照)​ 這個Target Driver。
功能選擇​ 靈活可變。系統管理員可以根據需要,選擇並組合不同的插件來創建功能各異的虛擬設備。 固定不變。它的實現和所有能力(鏡像分層、寫時複製)都建立在Thin-Provisioning Snapshot之上。

    Device Mapper:一個“工具箱”     Linux Device Mapper更像一個多功能工具箱。它本身不直接完成特定任務,而是提供了一套機制,允許你通過不同的“工具”(即Target Driver插件)來操作和管理塊設備。這些“工具”功能各異,比如linear插件可以將多個物理設備線性地拼接成一個大的邏輯設備,mirror插件可以提供磁盤鏡像功能,而thin-provisioning插件則負責實現自動精簡配置和快照。     Docker devicemapper:專精於“Thin-Provisioning”這把“工具”     Docker在設計其存儲驅動時,需要實現鏡像分層(共享基礎層)和容器寫時複製(Copy-on-Write)這兩個核心特性。它發現Device Mapper工具箱裏的 thin-provisioning​ 這把“工具”完美契合這些需求。

Docker的 devicemapper存儲驅動,其實現本質上就是固定地使用了Device Mapper框架中的Thin-Provisioning(精簡配置)技術。在Docker的這個上下文中,devicemapper幾乎是 thin-provisioning的同義詞。雖然從技術上講,Device Mapper框架本身的能力遠不止於此,但Docker的 devicemapper存儲驅動是一個專門化的實現,它將其能力鎖定在了Thin-Provisioning上,以高效地解決容器存儲的特定問題。

3.docker中關於創建和配置thin-pool

    在配置文件中,你可以通過一些參數對 thin pool 進行精細控制。以下是一些關鍵選項:

參數 説明
dm.thinpooldev​ (direct-lvm 模式核心參數) 指定預創建好的 thin pool 邏輯設備路徑,例如 /dev/mapper/docker-thinpool。
dm.thinp_percent​ 設置數據卷可佔用卷組(VG)的空間百分比(如 95)。
dm.thinp_metapercent​ 設置元數據卷可佔用卷組(VG)的空間百分比(如 1)。
dm.thinp_autoextend_threshold​ 設置自動擴展觸發閾值(如空間使用率達 80%時擴展)。
dm.thinp_autoextend_percent​ 設置自動擴展一次增加容量的百分比(如擴展 20%)。
dm.basesize​ 設置容器和鏡像的基礎設備大小限制(默認 10G)。
dm.blkdiscard​ 啓用或禁用移除設備時丟棄塊,可能影響容器移除速度與空間回收。
dm.fs​ 指定基礎設備的文件系統類型,如 ext4或 xfs(默認常為 xfs)。

創建 LVM 物理卷和卷組並轉換為thin-pool池:

pvcreate /dev/sdb
vgcreate docker /dev/sdb
創建 Thin Pool 邏輯卷:
# 創建數據邏輯卷(佔用大部分空間)
lvcreate -l 95%VG -n thinpool docker
# 創建元數據邏輯卷(佔用少量空間)
lvcreate -l 1%VG -n thinpoolmeta docker
# 將兩者轉換為 thin pool
lvconvert -y --thinpool docker/thinpool --poolmetadata docker/thinpoolmeta

    修改 Docker 配置:編輯 /etc/docker/daemon.json文件,指定使用 devicemapper存儲驅動和 thin pool 設備:

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.thinpooldev=/dev/mapper/docker-thinpool",
  ]
}

    啓動 Docker 服務:

sudo systemctl daemon-reload
sudo systemctl start docker

4.thin-pool與lvm的關係

    LVM是一個靈活的存儲管理框架,LVM 的底層不僅限於 thin-provisioning 技術,也支持傳統卷組(VG),它更是一個存儲管理框架,而 thin-provisioning 是其之上一個高級的、可選的特性。     Thin Provisioning是LVM框架下通過先創建特定的Thin Pool資源池,然後在該池上創建邏輯卷而實現的一種高級功能。​ 傳統LVM是“厚置備”,而基於Thin Pool的LVM是“精簡置備”,後者通過按需分配的方式,實現了存儲的虛擬化,提供了更高的靈活性。

特性維度 在傳統卷組 (VG) 上創建 LV 在 Thin Pool 上創建 LV (精簡配置)
核心命令​ lvcreate -L 大小 -n LV名 VG名 lvcreate -V 虛擬大小 -T VG名/ThinPool名 -n LV名
空間分配​ 厚配置:創建時立即分配全部指定容量。 精簡配置:創建時分配虛擬容量,物理空間按需動態分配​ 。
關鍵參數​ -L:指定邏輯卷的實際物理大小。 -V:指定邏輯卷的虛擬大小(可遠超物理容量)。
資源池基礎​ 直接基於卷組 (VG) 的物理空間。 必須基於一個已創建的 Thin Pool​ 。
空間超用​ 不支持(LV總容量 ≤ VG物理容量)。 支持,是所有精簡卷虛擬容量之和可遠超Thin Pool物理容量 。
適用場景​ 空間需求固定、可預測,追求簡單穩定的場景。 空間需求不確定、需要靈活性、高存儲利用率的場景(如虛擬化、開發測試)。