Docker 空間使用分析與清理

用戶在使用 Docker 部署業務一段時間後,可能會發現宿主節點的磁碟容量持續增長,甚至將磁碟空間耗盡進而引發宿主機異常,進而對業務造成影響。 本文先對 Docker 的空間分析與清理進行說明,然後對容器的磁碟容量限制與使用建議做簡要說明。

典型問題場景

用戶發現 Docker 宿主機的磁碟空間使用率非常高。通過 du 逐層分析,發現是 Volume 或 overlay2 等目錄佔用了過高空間。示例如下:

空間使用分析

遇到此類問題,可以參閱如下步驟進行空間分析,定位佔用過高空間的業務來源。

分析 Docker 空間分布

Docker 的內置 CLI 指令 docker system df ,可用於查詢鏡像(Images)、容器(Containers)和本地卷(Local Volumes)等空間使用大戶的空間佔用情況。 示例輸出如下:空間使用分析

查看空間佔用細節

可以進一步通過 -v 參數查看空間佔用細節,以確定具體是哪個鏡像、容器或本地卷佔用了過高空間。示例輸出如下:

[root@node3 docker]# docker system df -v# 鏡像的空間使用情況Images space usage:REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERSbusybox latest 6ad733544a63 5 days ago 1.129 MB 0 B 1.129 MB 1nginx latest b8efb18f159b 3 months ago 107.5 MB 107.5 MB 0 B 4ubuntu latest 14f60031763d 3 months ago 119.5 MB 0 B 119.5 MB 0alpine 3.3 606fed0878ec 4 months ago 4.809 MB 0 B 4.809 MB 0tutum/curl latest 01176385d84a 3 years ago 224.4 MB 0 B 224.4 MB 1# 容器的空間使用情況Containers space usage:CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED STATUS NAMESd1da451ceeab busybox "ping 127.0.0.1" 0 10.7 GB About an hour ago Up About an hour dstest956ae1d241e8 nginx:latest "nginx -g daemon ..." 0 26 B 3 months ago Up 3 months localTest_restserver_274973d237a06 nginx:latest "nginx -g daemon ..." 0 2 B 3 months ago Up 3 months # 本地卷的空間使用情況Local Volumes space usage:VOLUME NAME LINKS SIZE83ba8747f4172a3c02a15f85b71e1565affca59f01352b4a94e0d28e65c26d1c 0 830 Ba479c303b278f1442f66644f694a554aac630e72b7a27065a11ef85c4d87b648 0 22.16 MB79a25b6376e0d6587d8f4f24e08f9467981f04daad14bf3353a12d727d065503 1 18.83 MB

空間清理

自動清理

可以通過 Docker 內置的 CLI 指令 docker system prune 來進行自動空間清理。

Tips

不同狀態的鏡像

  • 已使用鏡像(used image): 指所有已被容器(包括已停止的)關聯的鏡像。即 docker ps -a 看到的所有容器使用的鏡像。
  • 未引用鏡像(unreferenced image):沒有被分配或使用在容器中的鏡像,但它有 Tag 信息。
  • 懸空鏡像(dangling image):未配置任何 Tag (也就無法被引用)的鏡像,所以懸空。這通常是由於鏡像 build 的時候沒有指定 -t 參數配置 Tag 導致的。比如:

REPOSITORY TAG IMAGE ID CREATED SIZE<none> <none> 6ad733544a63 5 days ago 1.13 MB # 懸空鏡像(dangling image)

掛起的卷(dangling Volume)

類似的,dangling=true 的 Volume 表示沒有被任何容器引用的卷。

docker system prune 自動清理說明

  • 該指令默認會清除所有如下資源:
    • 已停止的容器(container)
    • 未被任何容器所使用的卷(volume)
    • 未被任何容器所關聯的網路(network)
    • 所有懸空鏡像(image)。
  • 該指令默認只會清除懸空鏡像,未被使用的鏡像不會被刪除。
  • 添加 -a 或 --all 參數後,可以一併清除所有未使用的鏡像和懸空鏡像。
  • 可以添加 -f 或 --force 參數用以忽略相關告警確認信息。
  • 指令結尾處會顯示總計清理釋放的空間大小。

操作示例:

手工清理

網路清理

網路配置通常佔用的空間非常低,略過。

鏡像清理

如果通過 docker system df 分析,是鏡像佔用了過高空間。則可以根據業務情況,評估相關鏡像的使用情況。對於懸空和未使用的鏡像, 可以使用如下指令手工清理:

# 刪除所有懸空鏡像,但不會刪除未使用鏡像:docker rmi $(docker images -f "dangling=true" -q)# 刪除所有未使用鏡像和懸空鏡像。# 【說明】:輪詢到還在被使用的鏡像時,會有類似"image is being used by xxx container"的告警信息,所以相關鏡像不會被刪除,忽略即可。docker rmi $(docker images-q)

卷清理

如果通過 docker system df 分析,是卷佔用了過高空間。則可以根據業務情況,評估相關卷的使用情況。對於未被任何容器調用的卷(-v 結果信息中,"LINKS" 顯示為 0),可以使用如下指令手工清理:

容器清理

如果通過 docker system df 分析,是某個容器佔用了過高空間。則可以根據業務情況,評估相關容器的業務歸屬並進行處理。對於已停止或其它異常狀態的容器,可以結合 -f 或 --filter 篩選器,使用類似如下指令來手工清理:

更多關於 ps 指令支持的篩選器信息,可以參閱官方文檔。

在用空間資源分析

對於還在使用的空間資源,可以參閱如下說明做進一步排查分析。

鏡像空間分析

如果某個鏡像佔用了過高空間,則可以通過如下方式做進一步空間分析:

  1. 通過 docker system df 獲取佔用過高空間的鏡像信息。
  2. 基於相應鏡像創建測試容器。
  3. exec 進入容器後,結合 du 等 shell 指令做進一步空間分析,定位出佔用最高空間的目錄或文件。
  4. 結合業務情況做進一步處理,重新 build 鏡像。

示例:

容器空間分析

如果某個運行中的容器佔用了過高空間,則可以通過如下方式做進一步空間分析:

Tips

容器的只讀層與鏡像層的空間佔用情況

一個容器的佔用的總空間,包含其最頂層的讀寫層(writable layer)和底部的只讀鏡像層(base image layer,read-only)。更多相關說明,可以參閱官方文檔。

可以通過 docker ps 的 -s 參數來分別顯示二者的空間佔用情況,進而判斷相應容器的空間佔用主要是來自原始鏡像,還是運行中產生。

示例:

# 如下容器的原始鏡像佔用了 422MB 空間,實際運行過程中只佔用了 2B 空間:CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZEac39128ccbc0 registry.aliyuncs.com/acs-sample/wordpress:4.6 "/entrypoint.sh ap..." 3 months ago Up 11 days 0.0.0.0:32779->80/tcp Web_web_4 2 B (virtual 422 MB)

容器空間佔用的分析步驟:

  1. 通過 docker system df 獲取佔用過高空間的容器信息。
  2. 通過前述 -s 參數確認到底是底層鏡像,還是運行過程中產生的數據佔用了過高空間。
  3. exec 進入容器,結合 du 等 shell 指令做進一步空間分析,定位出佔用最高空間的目錄或文件。
  4. 結合業務情況做進一步處理。

引申:Docker 磁碟空間限制與使用建議

磁碟空間限制

使用 Device Mapper 存儲驅動限制容器磁碟空間

如果使用 Device Mapper 作為底層存儲驅動,則可以通過 Docker daemon 的如下參數來全局限制單個容器佔用空間的大小:

  • --storage-opt dm.basesize=20G 表示限制單個容器最多佔用 20G 空間,將應用於任何新建容器。

更多關於 Device Mapper 存儲驅動的說明,可以參閱官方文檔。

使用 btrfs 存儲驅動限制容器磁碟空間

btrfs 驅動主要使用 btrfs 所提供的 subvolume 功能來實現。一個容器會對應一個 subvolume。針對容器對應的 subvolume 啟用並配置 quota 即可限制其磁碟空間。示例配置:

btrfs 還有其它很好的特性,比如可以在線擴容(在線加入一塊新的塊設備,來擴充整個文件系統的大小)。更多關於 btrfs 存儲驅動的說明,可以參閱官方文檔。

外掛 LVM 卷

如果使用的是其它不支持對單個容器的磁碟容量進行限制的存儲驅動,則可以考慮如下通用方案:

  • 通過 LVM 方式創建一個指定容量的卷,然後掛載到宿主操作系統上特定目錄。最後通過 --volume 參數來讓容器來掛載使用相應目錄。

注意:該方案的前提條件是,容器中所有落盤操作要全部落到上述 "--volume" 參數指定的卷中,否則容器還會佔用默認 aufs 所在盤的空間,進而造成統計不準。

Docker 存儲使用建議

細化的存儲使用最佳實踐與採用的存儲驅動(storage driver)類型強相關,您可以參閱官方文檔做相關了解,本文不做進一步細化說明。

通用的存儲使用建議如下:

  • 容器內的業務日誌務必配置輪詢覆寫,或者使用日誌驅動將日誌輸出到外部存儲。避免日誌文件持續增長,佔用過高磁碟空間。
  • 結合外部監控對宿主機的磁碟空間使用情況進行監控和告警。
  • 可以參閱文檔 如何給容器服務的Docker增加數據盤來擴容默認 Docker 存儲空間。

原文

更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎


推薦閱讀:

網站從http轉到https需要多久?
看到網址前的小嘆號,隱私就處在危險的境地
從零部署一個https網站
WEB加速,協議先行
瀏覽器地址欄里的 https 加密圖標,分別是什麼含義?

TAG:Docker | HTTPS | 配置 |