docker清理实践

[TOC]

准备测试数据

  • 创建 悬空的镜像(即REPOSITORY和TAG均为的镜像
docker pull busybox:musl
docker tag busybox:musl busybox:stable
mkdir -p /tmp/busybox
cd /tmp/busybox
echo 'FROM busybox:stable' > /tmp/busybox/Dockerfile
echo 'RUN touch /tmp/test' >> /tmp/busybox/Dockerfile
docker build -t busybox:test /tmp/busybox
docker pull busybox:stable
docker build -t busybox:test /tmp/busybox

docker images -f "dangling=true"
  • 创建 正常的容器 并写入1G文件
docker run -d --rm --name busybox busybox:test /bin/sh -c "/bin/sleep 3600"
docker exec -it busybox /bin/sh -c 'dd if=/dev/zero of=./test.zip count=1024 bs=1M'

docker system df | grep Containers
  • 创建 已停止 的容器(即docker ps -a中STATUS为Exited的容器
docker run -d --name busybox2 busybox:test /bin/sh -c "/bin/sleep 1"

docker ps -a | grep Exited
  • 创建 已暂停 的容器(即docker ps -a中STATUS为Paused的容器
docker run -d --rm --name busybox3 busybox:test /bin/sh -c "/bin/sleep 3600"
docker pause busybox3

docker ps -a | grep Paused
  • 创建 孤儿卷(即未被使用的卷)
docker volume create volume-test1

docker volume ls -f dangling=true

确认过程

docker info 确认 docker root 路径

  • docker info 查看 docker root 路径
docker info | grep Root

docker system df 分析资源使用

  • docker system df:查看所有镜像/容器/数据卷等资源使用的统计信息
docker system df

docker system df 列出了 docker 使用磁盘的 4 种类型:

类型 描述 备注
Images 所有镜像占用的空间 包括拉取的镜像、本地构建的镜像
Containers 运行中的容器所占用的空间 没运行就不占空间
Local Volumes 本地数据卷的空间
Build Cache 镜像构建过程产生的缓存数据
  • docker system df -v:查看所有镜像/容器/数据卷等资源使用的详细信息
docker system df -v

注:docker system df -v 看到的容器大小,有可能比实际的小很多。比如 df -v 看到某容器大小43G,但该容器对应的 overlay2/xxx/diff 和 merge 加一起却有82G

docker inspect 分析 overlay2 使用

  • 查看指定容器(比如 busybox)的 overlay2 目录
docker inspect busybox | grep overlay2

docker volume 查看 volume 使用

  • 查看volume
docker volume ls

查看容器日志的大小

  • 查看docker所有容器日志(*-json.log)
find /var/lib/docker/containers/ -name *-json.log
  • 查看超过100MB的文件
find /var/lib/docker -type f -size +100M -print0 | xargs -0 du -h | sort -nr

查看 /var/lib/docker/overlay2

  • 查询 overlay2 占用磁盘空间较多(比如达到G或T以上)的目录
du -sh /var/lib/docker/overlay2/* | grep [GT] | sort -nr
  • 找到使用较多的 overlay2 子目录,结合 docker inspect 反向定位到哪个容器在用

docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep xxx
  • 进入容器(比如 busybox),找到占用磁盘较多的目录,清理就完了。
docker exec -it busybox /bin/sh -c 'du -sh /*'

手动清理

清理容器日志

  • 重置较大的容器日志(*-json.log)
find /var/lib/docker/containers/ -name *-json.log
# bash -c "echo > /var/lib/docker/containers/xxx-json.log"
  • 删除较大(超过100MB)的容器日志
find /var/lib/docker -type f -size +100M -print0 | xargs -0 du -h | sort -nr
# rm -f xxx

停止 container

  • 停止 已暂停 的容器(注:请确认已暂停的容器不在使用,否则后面会误删)
# docker stop $(docker ps -a | grep "Paused" | awk '{print $1 }')
  • 停止 特定|所有 的容器
# docker stop $(docker ps -a | egrep "(mysql|zabbix)" | awk '{print $1}')

# docker stop $(docker ps -a -q)

删除 container

  • 删除 已停止 的容器
docker rm $(docker ps -a | grep "Exited" | awk '{print $1 }')
  • 删除 特定|所有 的容器
# docker rm $(docker ps -a | egrep "(mysql|zabbix)" | awk '{print $1}')

# docker rm $(docker ps -a -q)

删除 images

  • 删除 悬空 的镜像(即REPOSITORY和TAG均为的镜像)

    注1:若REPOSITORY正常、TAG为,只是说明该镜像没有正常打标签,不可轻易删除。

    注2:如果正在运行的容器使用了悬空镜像,那么删除此镜像就会报错:Error response from daemon: conflict: unable to delete 77bb919cd617 (cannot be forced) - image is being used by running container 48c2f4b4f4af。若确认依赖的容器已不在使用,停掉此容器再次删除悬空镜像就不会报错了。

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

docker rmi $(docker images -qf dangling=true)
  • 删除 特定 的容器
docker rmi -f $(docker images | egrep "(mysql|zabbix|mariadb)" | awk '{print $3}')

删除 volume

  • 删除 孤儿卷(即无用的volume)
docker volume rm $(docker volume ls -qf dangling=true)
  • 清理volume
docker volume prune

删除 network

  • 删除网络,网络一般不占用磁盘空间,可以不用删除
# docker network rm $(docker network ls -q)

推荐 docker system prune

  • docker system prune:会删除已停止的容器、无用的网络、悬空镜像、悬空镜像的构建缓存

    注1:不会删除已暂停的容器、没有关联容器的镜像

docker images -qf dangling=true  #.悬空的镜像
docker ps -a | grep Exited  #.已关闭的容器

docker system prune
  • docker system prune -a:清理的更加彻底,会删除没有容器使用的镜像
docker system prune -a

最佳实践

使用参数限制容器大小

  • 比如,在创建容器的时候使用参数 –storage-opt size=100G 来设定容器的硬盘大小为100G
docker pull nginx:latest

docker run -itd --name nginx1 -p 8001:80 nginx:latest /bin/bash
docker exec -it nginx1 /bin/bash -c 'df -Th | grep overlay'

docker run -itd --name nginx2 -p 8002:80 --memory=2G --storage-opt size=100G nginx:latest /bin/bash
docker exec -it nginx2 /bin/bash -c 'df -Th | grep overlay'

修改默认的docker路径

  • 修改docker默认存放镜像/容器/数据卷的路径,比如:/data/docker
mkdir -p /data/docker
systemctl stop docker
rsync -avz /var/lib/docker/ /data/docker
mv /var/lib/docker /var/lib/docker.bak
echo '{"data-root":"/data/docker"}' > /etc/docker/daemon.json
systemctl restart docker 
docker info | grep Root
  #.执行 docker info 若返回 Docker Root Dir: /data/docker 则表示docker根目录修改成功

创建自动清理任务

  • 容器日志随时间推移会继续积累,可以创建一个定期清理的任务,脚本参考如下:clean_docker_log.sh
#!/bin/bash

logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
    cat /dev/null > $log
done
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2022-09-09 10:10:44

results matching ""

    No results matching ""