誰用佔用了這麼多磁碟空間?Docker System命令詳解
用了一段時間Docker後,會發現它佔用了不少硬碟空間。還好Docker 1.13引入瞭解決方法,它提供了簡單的命令來檢視/清理Docker使用的磁碟空間。
本文通過一個簡單的示例,可以證明Docker能夠很快地將磁碟佔滿。該示例通過play-with-docker.com執行。點選Add new instance即可建立新的例項,該例項安裝了最新版的Docker 17.03。這篇部落格主要討論磁碟空間,那麼不妨使用df命令檢視磁碟的初始狀態:
$ df -h Filesystem Size Used Available Use% Mounted on /dev/mapper/... 10.0G 443.3M 9.6G 4% / tmpfs 60.0G 0 60.0G 0% /dev tmpfs 60.0G 0 60.0G 0% /sys/fs/cgroup /dev/xvda1 49.1G 3.7G 43.3G 8% /etc/resolv.conf /dev/xvda1 49.1G 3.7G 43.3G 8% /etc/hostname /dev/xvda1 49.1G 3.7G 43.3G 8% /etc/hosts shm 64.0M 0 64.0M 0% /dev/shm /dev/mapper/... 10.0G 443.3M 9.6G 4% /graph/overlay2
可知,在新建立的play-with-docker.com例項,一共有10GB磁碟空間,其中接近500MB已被佔用。
接下來編寫Dockerfile來建立一個映象。這個映象基於Alpine映象;映象將寫入3個隨機的檔案,每個檔案1GB,檔案由dd命令生成;因為這個映象並沒有實際作用,因此CMD設為/bin/true。
FROM alpine RUN dd if=/dev/zero of=1g1.img bs=1G count=1 RUN dd if=/dev/zero of=1g2.img bs=1G count=1 RUN dd if=/dev/zero of=1g3.img bs=1G count=1 CMD /bin/true
執行docker build -t test .即可建立映象,執行完成後將生成一個3GB的映象。
$ docker image ls REPOSITORY TAG CREATED SIZE test latest 38 seconds ago 3.23GB alpine latest 5 weeks ago 3.99MB
不難理解,該映象佔用了相應大小的磁碟空間。
$ df -h Filesystem Size Used Available Use% Mounted on /dev/mapper/... 10.0G 3.4G 6.5G 34% /
若只寫入2個隨機檔案,則需要修改Dockerfile,刪掉一行。為了避免構建映象時使用快取,我在dd命令之前添加了一行echo命令。
FROM alpine RUN echo foo RUN dd if=/dev/zero of=1g1.img bs=1G count=1 RUN dd if=/dev/zero of=1g2.img bs=1G count=1 # RUN dd if=/dev/zero of=1g3.img bs=1G count=1 CMD /bin/true
本來以為這樣可以節省1GB磁碟空間,然而實際情況更加糟糕!
$ df -h Filesystem Size Used Available Use% Mounted on /dev/mapper/... 10.0G 5.4G 4.5G 54% /
舊的Docker映象一直存在,最終磁碟空間會很快被用完。Docker 1.13引入了docker system df命令,類似於Linux上的df命令,用於檢視Docker的磁碟使用情況。
$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 3 0 5.373GB 5.373GB (100%) Containers 0 0 0B 0B Local Volumes 0 0 0B 0B
可知,例項上一共有3個Docker映象: apline映象,包含3個1GB隨機檔案的映象以及包含2個1GB隨機檔案的映象。這些映象佔用了超過5GB磁碟空間。由於我們並沒有基於這些映象執行容器,所以它們都可以被刪除,所以可回收的(RECLAIMABLE)磁碟空間為100%。使用docker run test執行test映象再檢視:
$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 3 1 5.373GB 3.225GB (60%) Containers 1 0 0B 0B Local Volumes 0 0 0B 0B
現在情況就不同了,我運行了一個容器,它執行/bin/true之後就很快退出了。
這個容器綁定了test映象,test映象被標記為活躍(active)因而不能被刪除,這導致可回收的磁碟空間變少了。
現在來清理一下磁碟空間。
Docker提供了docker system prune,可以用於清理dangling映象(參考What are Docker : images?)和容器,以及失效的資料卷和網路。
$ docker system prune WARNING! This will remove: - all stopped containers - all volumes not used by at least one container - all networks not used by at least one container - all dangling images Are you sure you want to continue? [y/N] y Deleted Containers: 1cdf866157b4a97e151125af3c2a7f186a59b6f63807e2014ce1a00d68f44e1d Deleted Images: deleted: sha256:f59bb277... deleted: sha256:695b8e70... deleted: sha256:93b1cceb... deleted: sha256:c74d6bcd... deleted: sha256:df8b9bb1... deleted: sha256:dfe8340f... deleted: sha256:ce1ee654... Total reclaimed space: 3.221GB
根據警告資訊可知,這個命令會刪除所有關閉的容器以及dangling映象。示例中,含有3個1GB隨機檔案的映象的名稱被佔用了,名稱為:,為dangling映象,因此會被刪除。同時,所有的中間映象也會被刪除。這樣的話,一共3GB的磁碟空間被回收了!
更進一步,使用-a選項可以做深度清理。這時我們會看到更加嚴重的WARNING資訊:
$ docker system prune -a WARNING! This will remove: - all stopped containers - all volumes not used by at least one container - all networks not used by at least one container - all images without at least one container associated to them Are you sure you want to continue? [y/N] y Deleted Images: untagged: test:latest deleted: sha256:c515ebfa2... deleted: sha256:07302c011... deleted: sha256:37c0c6474... deleted: sha256:5cc2b6bc4... deleted: sha256:b283b9c35... deleted: sha256:8a8b9bd8b... untagged: alpine:latest untagged: [email protected]:58e1a1bb75db1... deleted: sha256:4a415e366... deleted: sha256:23b9c7b43... Total reclaimed space: 2.151GB
這個命令將清理整個系統,並且只會保留真正在使用的映象,容器,資料卷以及網路,因此需要格外謹慎。比如,我們不能在生產環境中執行prune -a命令,因為一些備用映象(用於備份,回滾等)有時候需要用到,如果這些映象被刪除了,則執行容器時需要重新下載。
此時,所有未繫結容器的映象將會被刪除。由於第一次prune命令刪除了所有容器,因此所有映象(它們沒有繫結任何容器)都會被刪除。
$ df -h Filesystem Size Used Available Use% Mounted on /dev/mapper/... 10.0G 442.5M 9.6G 4% /
現在,已使用的磁碟空間又變成了4%。本文的示例只是冰山一角,因為一旦我們運行了真正的容器,並且使用了Docker資料卷和Docker網路,則磁碟空間將會更快用完。感興趣的話,可以檢視部落格最後的視訊(不要忘了訂閱!)。在視訊中,我介紹一個簡單的WordPress應用,它由數個容器,資料卷以及網路構成。這個應用可以很快地消耗掉磁碟空間,我將介紹如何處理這個問題。