早上4点左右,同事信息说服务器磁盘占用95%以上的警告,我们有台服务器是40G的,已经跑了两年了
第一反应是谁攻击了,让其下载大量文件导致,之前已经被别人攻击过,也可能是是日志量过大和项目发布次数过多,docker存在的一些无用镜像导致的,接下来就从这几方面开始排查.
磁盘清理
黑客攻击
登录阿里云后台
- 磁盘情况
也可以使用命令查询
df -Th
df知识补充
参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。
语法:df [-ahikHTm] [目录或文件名]
-a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k :以 KBytes 的容量显示各文件系统;
-m :以 MBytes 的容量显示各文件系统;
-h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-H :以 M=1000K 取代 M=1024K 的进位方式;
-T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
-i :不用硬盘容量,而以 inode 的数量来显示
- 内存情况
#-h:以人类易读的单位展示
free -h
基本排除攻击情况
日志量过大
项目日志过大
切换到项目路径
sudo du -h --max-depth=1
du知识补充
du命令也是查看使用空间的,但是与 df 命令不同的是 Linux du 命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的,这里介绍 Linux du 命令。
语法:du [-ahskm] 文件或目录名称
选项与参数:
-a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
-h :以人们较易读的容量格式 (G/M) 显示;
-s :列出总量而已,而不列出每个各别的目录占用容量;
-S :不包括子目录下的总计,与 -s 有点差别。
-k :以 KBytes 列出容量显示;
-m :以 MBytes 列出容量显示;
--max-depth=n : 指定统计子目录的深度为第n层
server就是项目的路径,一共占去7.2G,删除无用的日志就可以了
docker日志过大
切换到docker目录,看下磁盘占用情况,可以看到占用7.1g,主要集中在overlay文件夹和containers文件夹
cd /var/lib/docker
sudo du -h --max-depth=1 | sort -h
查看containers目录哪个文件占用过大
cd containers
sudo du -d1 -h ./ | sort -h
这里的一长串的字母就是containerId的完整路径,可以使用docker ps -a
来查看是哪个容器,
我们切至最大的文件夹
cd d392464452f8241be12a4164e28d76047131f777cb130862797c85736cd43d75
ll -h
可以看到磁盘空间都是**-json.log文件占用了
有的同学会说就是日志目录删除即可,删除其实不能真正的释放磁盘空间,该文件已经被Linux系统占用,已经加载进内存中,删除是无效的,除非删除之后重启服务器,这样操作有点高射炮打蚊子
我们使用echo >
输出重定向来搞定这件事
echo aaa > **-json.log
ll -h
磁盘大小瞬间释放出来了,这种时间久了日志还是会大,需要我们定期清理,那有没有办法系统自动清理呢.当然有
控制容器日志大小
运行时控制
# max-size 最大数值 max-file 最大日志数
$ docker run -it --log-opt max-size=10m --log-opt max-file=3 redis
全局配置
# 创建目录
sudo mkdir -p /etc/docker
#添加配置
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://qiojqnqv.mirror.aliyuncs.com"],
"log-driver":"json-file",
"log-opts":{
"max-size" :"50m","max-file":"3"
}
}
EOF
# 重新加载
sudo systemctl daemon-reload
# 重启docker
sudo systemctl restart docker
参数说明
max-size=50m: 一个容器日志大小上限是50M,
max-file=3: 一个容器有三个日志,分别是id+.json、id+1.json、id+2.json。可以存在的最大日志文件数。如果超过最大值,则会删除最旧的文件。仅在max-size设置时有效。默认为5。
随后重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
重要!重要!重要!
已存在的容器不会生效,容器需要重新创建才可以
内存清理
关于内存,我们只需要找出哪个服务占用内存最高,后续处理根据自己业务处理
#使用top命令
top
#shift+m以内存排序
可以看到redis内容占用和有个java项目占用过大,可以根据业务需要选择停止或优化服务
我们的redis是很多key没有加失效时间导致key逐渐过多,占用内存逐渐增大
继续查看overlay目录哪个文件占用过大
cd overlay
sudo du -h --max-depth=1 | sort -h
…此处省略一些…
这里我已经清理过了,最开始的时候,我们有两个镜像加起来超过10g,这里只展示操作
补充知识
查看 docker 占用的资源,在进行资源清理之前我们有必要搞清楚docker都占用了哪些系统的资源。
#默认只列出正在运行的容器,-a选项会列出包括停止的所有容器
docker container ls
#列出镜像信息,-a 选项会列出 intermediate 镜像(就是其它镜像依赖的层)
docker image ls
#列出数据卷
docker volume ls
#列出 network
docker network ls
#显示系统级别的信息,比如容器和镜像的数量等
docker info
通过这些命令查看 docker 使用的资源情况后,相信你已经决定要清理 docker 占用的一些资源了!
清理
#删除那些已停止的容器,dangling镜像,未被容器引用的network和构建过程中的cache
docker system prune
安全起见,这个命令默认不会删除那些未被任何容器引用的数据卷,如果需要同时删除这些数据卷,你需要显式的指定 --volumes 参数。比如你可能想要执行下面的命令:
docker system prune --all --force --volumes
我们还可在不同在子命令下执行 prune,这样删除的就是某类资源:
#删除所有退出状态的容器
docker container prune
#删除未被使用的数据卷
docker volume prune
#删除 dangling 或所有未被使用的镜像
docker image prune