清理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

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

清理Docker垃圾

上一篇:8.15 图论模拟赛垫底记


下一篇:pwn-100