Docker日志配置和清理

在linux上,容器日志一般存放在/var/lib/docker/containers/{container_id}/

  • 设置Docker容器日志大小,docker-compose的max-size(限制在5GB) 例子:
1
2
3
4
5
6
7
8
nginx: 
image: nginx:1.12.1
restart: always
logging:
driver: “json-file”
options:
max-size: “5g”
max-file: 3

max-size=500m,意味着一个容器日志大小上限是500M,max-file=3,意味着一个容器有三个日志,分别是id+.json、id+1.json、id+2.json。

或者统一配置/etc/docker/daemon.json

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

  • 查所有容器日志大小docker_log_size.sh
1
2
3
4
5
6
7
#!/bin/sh
echo "======== docker containers logs file size ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
ls -lh $log
done
  • 日志清理脚本clean_docker_log.sh,内容如下:
1
2
3
4
5
6
7
8
9
#!/bin/sh 
echo "======== start clean docker containers logs ========"
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done
echo "======== end clean docker containers logs ========"
  • 配置cron
1
2
3
1. 编辑crontab: crontab -e
2. 添加(每天晚上2点清理): 0 0 2 * * ? /opt/docker-sh/clean_docker_log.sh
3. 保存

overlay2过大如何清理

  • 查看具体哪个占用大
1
du -h --max-depth=1 /var/lib/docker/overlay2/
  • 方法1:根据id查看是哪个镜像,pid, 数据位置
1
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep "<id>"
  • 方法2:删除所有不可用镜像/network/volume/container
1
2
3
4
5
6
7
# docker system prune --all --volumes
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all volumes not used by at least one container
- all images without at least one container associated to them
- all build cache

删除整个/var/lib/docker【适用于构建机器】

有的时候即使使用docker system prune --all --volumes -f删除无用数据,overlay2下磁盘依旧删不了多少东西。这时候通常会发现是du -ah --max-depth=1 /var/lib/docker/overlay2/**/diff下的空间占据太大,那么针对**仅用于构建场景的机器**,可以考虑删除整个docker文件夹【而不是删除overlay2下的文件夹,否则可能会出现启动问题】

  • 停止服务
1
2
3
4
5
6
systemctl stop docker
systemctl stop docker.socket

# 验证
systemctl status docker
systemctl status docker.socket
  • 删除
1
rm -rf /var/lib/docker
  • 重新启动
1
systemctl start docker
  • 验证
1
2
3
systemctl status docker
systemctl status docker -l
systemctl status docker.socket -l

镜像清理脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env bash
#删除过期镜像,保留最新${retain}个版本(需要确保版本号确实是越新的越大)
retain=1
cdate=$(date '+%Y-%m-%d_%H:%M:%S')
# 镜像中的关键字
keyword="docker.io"
# 先删除异常停止的docker容器
docker rm -f $(docker ps -a | grep Exited | awk '{print $1}')
# 先删除名称或标签为none的镜像
docker rmi -f $(docker images | grep '<none>' | awk '{print $3}')
for service in $(docker images | grep "${keyword}" | awk '{print $1}')
do
# 查看当前服务有多少镜像
count=$(docker images | grep -c "$service")
# 如果当前服务的镜像数大于保留数,则进行删除
if [[ $count -gt $retain ]];then
# 当modifyCount=count-retain则停止删除镜像
modifyCount=0
# tag的分割符"v",然后取后面的数字进行正序排序(screw-db:v100)
for i in $(docker images | grep "$service" | awk '{print $2}' | awk -F'v' '{print $2}' | sort -u)
do
# 当modifyCount=count-retain则停止删除镜像
if [ $modifyCount -eq $(( count - retain )) ]; then
break
fi
# 拼接版本: v100
version=$(docker images | grep "$service" | awk '{print $2}' | grep "$i")
docker rmi -f "$service":"${version}"
echo "docker rmi $service:${version} 执行时间:$cdate" >> ~/log_delete_images.log
# 自增加1
modifyCount=$((modifyCount + 1))
done
fi
done