譯者按: Docker鏡像,容器,數據卷以及網絡都會佔用主機的磁盤空間,這樣的話,磁盤很容易就會被用完。這篇博客介紹了一個簡單的解決方案 - Docker System命令。javascript
原文: What’s eating my disk? Docker System Commands explainedjava
譯者: Fundebugdocker
爲了保證可讀性,本文采用意譯而非直譯。小程序
用了一段時間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](http://labs.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的鏡像。app
$ docker image ls REPOSITORY TAG CREATED SIZE test latest 38 seconds ago 3.23GB alpine latest 5 weeks ago 3.99MB
不難理解,該鏡像佔用了相應大小的磁盤空間。ide
$ 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 <none>:<none> 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: alpine@sha256: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應用,它由數個容器,數據卷以及網絡構成。這個應用能夠很快地消耗掉磁盤空間,我將介紹如何處理這個問題。
視頻: What's eating my disk?!Clean up your Docker System
Fundebug專一於JavaScript、微信小程序、微信小遊戲、支付寶小程序、React Native、Node.js和Java實時BUG監控。
自從2016年雙十一正式上線,Fundebug累計處理了6億+錯誤事件,獲得了Google、360、金山軟件等衆多知名用戶的承認。歡迎免費試用!
轉載時請註明做者Fundebug以及本文地址:
https://blog.fundebug.com/2017/04/19/docker-system-explain/