清理Docker垃圾


一、Docker容器鏡像刪除

$ docker stop $(docker ps -a -q)
# 停止所有的container
$ docker rm $(docker ps -a -q)
# 刪除所有停止的容器

$ docker images
# 查看當前有哪些image

$ docker rmi <image id>
# 刪除images,通過image的id來指定刪除誰
$ docker rmi $(docker images | grep "^<none>" | awk "{print $3}")
# 想要刪除untagged images,也就是那些id為的image的話可以用
$ docker rmi $(docker images -q)
# 要刪除全部image

清理所有已停止的docker小腳本

# 所有的
all_list=`docker ps -a -q`
# 運行中的
alive_list=`docker ps -q`

for i in $all_list;do
   echo $i   
   result=$(echo $alive_list | grep "$i")

   if [[ "$result" != "" ]]
   then
      echo "運行中...."
   else
     echo "已停止,開始刪除....清除時間:$(date +%Y%m%d%H%M%S)"
     docker rm -v $i
   fi
done

二、Docker磁盤空間清理

2.1 使用docker system命令清除

docker system df命令,類似於Linux上的df命令,用於查看Docker的磁盤使用情況:

$ 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磁盤,Docker容器占用了104.8MB磁盤,Docker數據卷占用了1.4GB磁盤。

  • docker system prune命令可以用於清理磁盤,刪除關閉的容器、無用的數據卷和網絡,以及dangling鏡像(即無tag的鏡像)。
  • docker system prune -a命令清理得更加徹底,可以將沒有容器使用Docker鏡像都刪掉。注意,這兩個命令會把你暫時關閉的容器,以及暫時沒有用到的Docker鏡像都刪掉了…所以使用之前一定要想清楚額。

執行docker system prune -a命令之后,Docker占用的磁盤空間減少了很多:

$ 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.2 手動清理Docker鏡像/容器/數據卷

對於舊版的Docker(版本1.13之前),是沒有docker system命令的,因此需要進行手動清理。這里給出幾個常用的命令:

# 刪除所有關閉的容器
$ docker ps -a | grep Exit | cut -d ’ ’ -f 1 | xargs docker rm

# 刪除所有dangling鏡像(即無tag的鏡像):
$ docker rmi (docker images | grep "^<none>" | awk "{print(docker images | grep "^<none>" | awk "{print3}”) 

# 刪除所有dangling數據卷(即無用的volume):
$ docker volume rm $(docker volume ls -qf dangling=true)

2.3 限制容器的日志大小

有一次,當我使用1與2提到的方法清理磁盤之后,發現並沒有什么作用,於是,我進行了一系列分析。

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

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

Docker竟然使用了將近100GB磁盤。使用du命令繼續查看,可以定位到真正占用這么多磁盤的目錄:

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的磁盤。進一步分析可知,真正占用磁盤空間的是nginx的日志文件。那么這就不難理解了。我們Fundebug每天的數據請求為百萬級別,那么日志數據自然非常大。

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

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

當然,這個命令只是臨時有作用,日志文件遲早又會漲回來。要從根本上解決問題,需要限制nginx容器的日志文件大小。這個可以通過配置日志的max-size來實現,下面是nginx容器的docker-compose配置文件:

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

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

2.4 重啟Docker

還有一次,當我清理了鏡像、容器以及數據卷之后,發現磁盤空間並沒有減少。根據Docker disk usage提到過的建議,我重啟了Docker,發現磁盤使用率從83%降到了19%。根據高手指點,這應該是與內核3.13相關的BUG,導致Docker無法清理一些無用目錄:

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.

三、Docker目錄/var/lib/docker/containers文件太大

Docker在不重建容器的情況下,日志文件默認會一直追加,時間一長會逐漸占滿服務器的硬盤的空間,內存消耗也會一直增加,本篇來了解一些控制日志文件的方法。

3.1 查出占用磁盤較大的文件

Docker 的日志文件存在 /var/lib/docker/containers 目錄中,通過下面的命令可以將日志文件夾根據升序的方式羅列出來。

$ sudo du -d1 -h /var/lib/docker/containers | sort -h
40K     /var/lib/docker/containers/7bbec35275e8f63784107d486c9c40cb62902afd6815c569b36947f0b0ed6405
40K     /var/lib/docker/containers/7df78d67728173c13b4a238518b79d4b4a384d38026102a61aef290e53f2f1a6
40K     /var/lib/docker/containers/8d59b4f970a1b5cb20fc281d73f5c643bd0514b25cac3e0fae13bcec99c45e05
40K     /var/lib/docker/containers/965375d69bca2e43a4f7d3306508cc1db40fa0b783b1d7fe4b6fa7e333926b8c
40K     /var/lib/docker/containers/e04e90f0d466ab5b969fd72894b23444d495a84591b1e93d5bef03da30b1fc2d
40K     /var/lib/docker/containers/f31069b69d329fcac0939bbb6310afa66535ff4573591414fbfabecdb0eeeb79
44K     /var/lib/docker/containers/1995f5cf52e09b3d6d2ec6760e3e29c51b645d1629a7f65415abb984a370bea4
44K     /var/lib/docker/containers/44fdc73c0e48797faffdfd4abe17ccdc3e617542d68f6f5a073bbfc343fdc0dd
44K     /var/lib/docker/containers/c3cb05fd745cfa1d527717ef63d7f9cc0dd81530d4f432538ce4fb89c0b1655f
164K    /var/lib/docker/containers/c742626988ae6237b0fc591b0604313b5ca29ebec4d91173cab3ef838d2a8967
448K    /var/lib/docker/containers/8d4ea3635d5cf9cb09b3f3652df29727288ef01adfc9963291ef53a7ed1f8a91
536K    /var/lib/docker/containers/16b599deca2f0e80024e1a342aec281c5578909c564a4a1127c92985396b91e4
1.4M    /var/lib/docker/containers/426d63b3423eaded89f4ecf1b35493f79f654903d8655af321b24307cc763e8e
5.5M    /var/lib/docker/containers/5206c2f48bd01de60a5c6576e7607ffcc6be3def17ee5dbc2be393311c2638c2
9.3M    /var/lib/docker/containers

3.2 清理單個文件

感覺哪個容器的日志太大就清理哪個

$ sudo sh -c "cat /dev/null > ${log_file}"
  • ${log_file} 就是日志文件

可以通過find命令查找全部日志

$ sudo find /var/lib/docker/containers -name *.log
/var/lib/docker/containers/a823b8ee2df7c89dcfcbc125ac835b167a4f3c4d0fc1a6ec08d359e5aefa23f0/a823b8ee2df7c89dcfcbc125ac835b167a4f3c4d0fc1a6ec08d359e5aefa23f0-json.log
/var/lib/docker/containers/99435d5cc9016af41a7f8b2761f93b4374d9774b77b1f463b429e63de7addb2a/99435d5cc9016af41a7f8b2761f93b4374d9774b77b1f463b429e63de7addb2a-json.log
/var/lib/docker/containers/8206ee47b251e97204437f6a5528b94faa2eabb385f93386f32d89efedfdb8ed/8206ee47b251e97204437f6a5528b94faa2eabb385f93386f32d89efedfdb8ed-json.log
/var/lib/docker/containers/7b3fd134954c459695092e4b79e840e7d864f6dd19b468af92ea3f83663b12b2/7b3fd134954c459695092e4b79e840e7d864f6dd19b468af92ea3f83663b12b2-json.log
/var/lib/docker/containers/dd88e4755c5bcacdbd540d21f0392c8d04a5317123a1b99ba2926ae59a72b7d0/dd88e4755c5bcacdbd540d21f0392c8d04a5317123a1b99ba2926ae59a72b7d0-json.log
/var/lib/docker/containers/7a854e0a7ca1e5029a1ac4aa689d48103d7240bded3c17f414a63368b4534da1/7a854e0a7ca1e5029a1ac4aa689d48103d7240bded3c17f414a63368b4534da1-json.log
/var/lib/docker/containers/965375d69bca2e43a4f7d3306508cc1db40fa0b783b1d7fe4b6fa7e333926b8c/965375d69bca2e43a4f7d3306508cc1db40fa0b783b1d7fe4b6fa7e333926b8c-json.log
/var/lib/docker/containers/54ef85ae58acd8fdfd028efa4e393512f4741ec3c5b0c3d690698c89c29256ac/54ef85ae58acd8fdfd028efa4e393512f4741ec3c5b0c3d690698c89c29256ac-json.log
/var/lib/docker/containers/af5b8850de8ff7d6ac3f747d263553211df3d514f5e896e624aee9a477e2db69/af5b8850de8ff7d6ac3f747d263553211df3d514f5e896e624aee9a477e2db69-json.log
/var/lib/docker/containers/16b599deca2f0e80024e1a342aec281c5578909c564a4a1127c92985396b91e4/16b599deca2f0e80024e1a342aec281c5578909c564a4a1127c92985396b91e4-json.log
/var/lib/docker/containers/ff3261b882c99365b702863ee0bda2527c21d50fee82f08583f22eec54c4534f/ff3261b882c99365b702863ee0bda2527c21d50fee82f08583f22eec54c4534f-json.log
/var/lib/docker/containers/426d63b3423eaded89f4ecf1b35493f79f654903d8655af321b24307cc763e8e/426d63b3423eaded89f4ecf1b35493f79f654903d8655af321b24307cc763e8e-json.log
/var/lib/docker/containers/90a9707a0edb5f38acff7e4bd225b4bea0e2f5aa12e56ed436af0ef6a88d1e28/90a9707a0edb5f38acff7e4bd225b4bea0e2f5aa12e56ed436af0ef6a88d1e28-json.log
/var/lib/docker/containers/c00c03b592b00931d7885aa4e9081f749ce844a9bdc2995e9d6bb46ed1277666/c00c03b592b00931d7885aa4e9081f749ce844a9bdc2995e9d6bb46ed1277666-json.log
/var/lib/docker/containers/ac6bc5a3db5be1f5c5a400d3b4d34427e55373aa50498594451bc48d73784248/ac6bc5a3db5be1f5c5a400d3b4d34427e55373aa50498594451bc48d73784248-json.log
/var/lib/docker/containers/e0136d5b180b7f85175e6a9db027a29bbcbc99ce077b96fda35987951dd5bae7/e0136d5b180b7f85175e6a9db027a29bbcbc99ce077b96fda35987951dd5bae7-json.log
/var/lib/docker/containers/8d4ea3635d5cf9cb09b3f3652df29727288ef01adfc9963291ef53a7ed1f8a91/8d4ea3635d5cf9cb09b3f3652df29727288ef01adfc9963291ef53a7ed1f8a91-json.log
...

或者查看具體容器名稱的日志位置

$ docker inspect --format='{{.LogPath}}' redis
/var/lib/docker/containers/c742626988ae6237b0fc591b0604313b5ca29ebec4d91173cab3ef838d2a8967/c742626988ae6237b0fc591b0604313b5ca29ebec4d91173cab3ef838d2a8967-json.log

3.3 控制容器日志大小

以上只是臨時解決的方式,最好是創建容器時就控制日志的大小.

3.4 運行時控制

啟動容器時,我們可以通過參數來控制日志的文件個數和單個文件的大小

# max-size 最大數值
# max-file 最大日志數
$ docker run -it --log-opt max-size=10m --log-opt max-file=3 redis

一兩個容器還好,但是如果有很多容器需要管理,這樣就很不方便了,最好還是可以統一管理。

3.5 全局配置

創建或修改文件 /etc/docker/daemon.json,並增加以下配置

{
    "log-driver":"json-file",
    "log-opts":{
        "max-size" :"50m","max-file":"1"
    }
}

隨后重啟 Docker 服務

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

不過已存在的容器不會生效,需要重建才可以!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM