Docker清理占用的磁盤(pán)空間

摘要:用了 Docker,好處挺多的,但是有一個(gè)不大不小的問(wèn)題,它會(huì)一不小心占用太多磁盤(pán),這就意味著我們必須及時(shí)清理。

好處:

  • 所有服務(wù)器的配置都非常簡(jiǎn)單,只安裝了 Docker,這樣新增服務(wù)器的時(shí)候要簡(jiǎn)單很多。
  • 可以非常方便地在服務(wù)器之間移動(dòng)各種服務(wù),下載 Docker 鏡像就可以運(yùn)行,不需要手動(dòng)配置運(yùn)行環(huán)境。
  • 開(kāi)發(fā)/測(cè)試環(huán)境與生產(chǎn)環(huán)境嚴(yán)格一致,不用擔(dān)心由于環(huán)境問(wèn)題導(dǎo)致部署失敗。

至少,上線這一年多來(lái),Docker 一直非常穩(wěn)定,沒(méi)有出什么問(wèn)題。但是,它有一個(gè)不大不小的問(wèn)題,會(huì)比較消耗磁盤(pán)空間。

如果 Docker 一不小心把磁盤(pán)空間全占滿(mǎn)了,你的服務(wù)也就算玩完了,因此所有 Docker 用戶(hù)都需要對(duì)此保持警惕。當(dāng)然,大家也不要緊張,這個(gè)問(wèn)題還是挺好解決的。

1. docker system 命令

誰(shuí)用光了磁盤(pán)?Docker System 命令詳解中,我們?cè)敿?xì)介紹了docker system命令,它可以用于管理磁盤(pán)空間。

docker system df命令,類(lèi)似于 Linux 上的df命令,用于查看 Docker 的磁盤(pán)使用情況:

docker system df

TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              147                 36                  7.204GB             3.887GB (53%)
Containers          37                  10                  104.8MB             102.6MB (97%)
Local Volumes       3                   3                   1.421GB             0B (0%)
Build Cache                                                 0B                  0B

可知,Docker 鏡像占用了7.2GB磁盤(pán),Docker 容器占用了104.8MB磁盤(pán),Docker 數(shù)據(jù)卷占用了1.4GB磁盤(pán)。

docker system prune命令可以用于清理磁盤(pán),刪除關(guān)閉的容器、無(wú)用的數(shù)據(jù)卷和網(wǎng)絡(luò),以及 dangling 鏡像(即無(wú) tag 的鏡像)。docker system prune -a命令清理得更加徹底,可以將沒(méi)有容器使用 Docker 鏡像都刪掉。注意,這兩個(gè)命令會(huì)把你暫時(shí)關(guān)閉的容器,以及暫時(shí)沒(méi)有用到的 Docker 鏡像都刪掉了...所以使用之前一定要想清楚吶。

執(zhí)行docker system prune -a命令之后,Docker 占用的磁盤(pán)空間減少了很多:

docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              10                  10                  2.271GB             630.7MB (27%)
Containers          10                  10                  2.211MB             0B (0%)
Local Volumes       3                   3                   1.421GB             0B (0%)
Build Cache                                                 0B                  0B

2. 手動(dòng)清理 Docker 鏡像/容器/數(shù)據(jù)卷

對(duì)于舊版的 Docker(版本 1.13 之前),是沒(méi)有 docker system 命令的,因此需要進(jìn)行手動(dòng)清理。這里給出幾個(gè)常用的命
刪除所有關(guān)閉的容器

docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm

刪除所有 dangling 鏡像(即無(wú) tag 的鏡像):

docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

刪除所有 dangling 數(shù)據(jù)卷(即無(wú)用的 volume):

docker volume rm $(docker volume ls -qf dangling=true)

Fundebug提供實(shí)時(shí)、專(zhuān)業(yè)的錯(cuò)誤監(jiān)控服務(wù),為您的線上代碼保駕護(hù)航,歡迎大家免費(fèi)使用!

3. 限制容器的日志大小

有一次,當(dāng)我使用 1 與 2 提到的方法清理磁盤(pán)之后,發(fā)現(xiàn)并沒(méi)有什么作用,于是,我進(jìn)行了一系列分析。

在 Ubuntu 上,Docker 的所有相關(guān)文件,包括鏡像、容器等都保存在/var/lib/docker/目錄中:

du -hs /var/lib/docker/
97G /var/lib/docker/

Docker 竟然使用了將近100GB磁盤(pán),這也是夠了。使用du命令繼續(xù)查看,可以定位到真正占用這么多磁盤(pán)的目錄:

92G /var/lib/docker/containers/a376aa694b22ee497f6fc9f7d15d943de91c853284f8f105ff5ad6c7ddae7a53

docker ps可知,nginx 容器的 ID 恰好為a376aa694b22,與上面的目錄/var/lib/docker/containers/a376aa694b22的前綴一致:

docker ps
CONTAINER ID        IMAGE                                       COMMAND                  CREATED             STATUS              PORTS               NAMES
a376aa694b22        192.168.59.224:5000/nginx:1.12.1            "nginx -g 'daemon off"   9 weeks ago         Up 10 minutes                           nginx

因此,nginx 容器竟然占用了92GB的磁盤(pán)。進(jìn)一步分析可知,真正占用磁盤(pán)空間的是 nginx 的日志文件。那么這就不難理解了。我們Fundebug每天的數(shù)據(jù)請(qǐng)求為百萬(wàn)級(jí)別,那么日志數(shù)據(jù)自然非常大。

使用truncate命令,可以將 nginx 容器的日志文件“清零”:

truncate -s 0 /var/lib/docker/containers/a376aa694b22ee497f6fc9f7d15d943de91c853284f8f105ff5ad6c7ddae7a53/*-json.log

當(dāng)然,這個(gè)命令只是臨時(shí)有作用,日志文件遲早又會(huì)漲回來(lái)。要從根本上解決問(wèn)題,需要限制 nginx 容器的日志文件大小。這個(gè)可以通過(guò)配置日志的max-size來(lái)實(shí)現(xiàn),下面是 nginx 容器的 docker-compose 配置文件:

nginx:
    image: nginx:1.12.1
    restart: always
    logging:
        driver: "json-file"
        options:
            max-size: "5g"

重啟 nginx 容器之后,其日志文件的大小就被限制在5GB,再也不用擔(dān)心了~

4. 重啟 Docker

有一次,當(dāng)我清理了鏡像、容器以及數(shù)據(jù)卷之后,發(fā)現(xiàn)磁盤(pán)空間并沒(méi)有減少。根據(jù)Docker disk usage提到過(guò)的建議,我重啟了 Docker,發(fā)現(xiàn)磁盤(pán)使用率從 83%降到了 19%。根據(jù)高手指點(diǎn),這應(yīng)該是與內(nèi)核 3.13 相關(guān)的 BUG,導(dǎo)致 Docker 無(wú)法清理一些無(wú)用目錄:

it's quite likely that for some reason when those container shutdown, docker couldn't remove the directory because the shm device was busy. This tends to happen often on 3.13 kernel. You may want to update it to the 4.4 version supported on trusty 14.04.5 LTS.

The reason it disappeared after a restart, is that daemon probably tried and succeeded to clean up left over data from stopped containers.

我查看了一下內(nèi)核版本,發(fā)現(xiàn)真的是 3.13:

uname -r
3.13.0-86-generic

如果你的內(nèi)核版本也是 3.13,而且清理磁盤(pán)沒(méi)能成功,不妨重啟一下 Docker。當(dāng)然,這個(gè)晚上操作比較靠譜。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容