早上4点左右,同事信息说服务器磁盘占用95%以上的警告,我们有台服务器是40G的,已经跑了两年了
第一反应是谁攻击了,让其下载大量文件导致,之前已经被别人攻击过,也可能是是日志量过大和项目发布次数过多,docker存在的一些无用镜像导致的,接下来就从这几方面开始排查.

磁盘清理

黑客攻击

登录阿里云后台

  • 磁盘情况
    image.png
    也可以使用命令查询
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 

image.png

基本排除攻击情况

日志量过大

项目日志过大

切换到项目路径

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层

image.png

server就是项目的路径,一共占去7.2G,删除无用的日志就可以了

docker日志过大

切换到docker目录,看下磁盘占用情况,可以看到占用7.1g,主要集中在overlay文件夹和containers文件夹

cd /var/lib/docker
sudo du -h --max-depth=1 | sort -h

image.png

查看containers目录哪个文件占用过大

cd containers
sudo du -d1 -h ./ | sort -h

image.png
这里的一长串的字母就是containerId的完整路径,可以使用docker ps -a来查看是哪个容器,
我们切至最大的文件夹

cd d392464452f8241be12a4164e28d76047131f777cb130862797c85736cd43d75
ll -h

image.png

可以看到磁盘空间都是**-json.log文件占用了
有的同学会说就是日志目录删除即可,删除其实不能真正的释放磁盘空间,该文件已经被Linux系统占用,已经加载进内存中,删除是无效的,除非删除之后重启服务器,这样操作有点高射炮打蚊子
我们使用echo >输出重定向来搞定这件事

echo aaa > **-json.log
ll -h

image.png
磁盘大小瞬间释放出来了,这种时间久了日志还是会大,需要我们定期清理,那有没有办法系统自动清理呢.当然有

控制容器日志大小

运行时控制
# 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以内存排序

image.png
可以看到redis内容占用和有个java项目占用过大,可以根据业务需要选择停止或优化服务
我们的redis是很多key没有加失效时间导致key逐渐过多,占用内存逐渐增大

继续查看overlay目录哪个文件占用过大

cd overlay
sudo du -h --max-depth=1 | sort -h

image.png
…此处省略一些…
image.png

这里我已经清理过了,最开始的时候,我们有两个镜像加起来超过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