本文由Markdown语法编辑器编辑完成.
1.前言
之前曾经撰写过一篇文章,是关于如何清理linux系统的SSD空间的.https://blog.csdn.net/inter_peng/article/details/123963010?spm=1001.2014.3001.5502
写这篇文章的时候,我的系统盘就经常被占满.虽然可以通过上述文章中的办法,暂时清理出一些空间.但是隔几天,就又满了.
最后我失去了耐心.当系统提示系统盘空间不到1%的空间时,我一般就直接运行:
sudo rm -rf /var/lib/docker/volumes
运行这条指令,会将我服务器中所有docker容器生成的volumes文件删除.一般运行完毕后,会释放100G左右的空间.
但是运行这条指令的后果是,我的电脑上无法运行任何的docker服务,这对于我的工作会造成一定的困扰.
虽然可以通过一些别的方式解决,但总是不太方便.
直到上周,因为要开发一个需求,必须经常的修改代码和调试.迫不得已,我必须找到这个困扰了我一年的问题.
2. 解决方案
2.1 我的尝试
首先,第一步还是运行docker-compose up -d.
这时,docker-compose.yml中配置的service会正常启动,所有的容器都显示up状态.
然而,好景不长,不到10s钟,就会有一个或两个服务,被中止运行.之后,相互依赖的一些服务,也都会出现宕机的情况.
于是,我又运行docker-compose down -v, 算是彻底地关闭所有运行的服务和删除服务创建的volumes. 然后再次up -d, 结果还是和上一次一样.服务先是正常启动,然后就又会被中止.
查看服务被中止的日志,似乎是被系统给杀掉了.类似ook.
一般服务进程被系统ookiller, 是因为系统内存不足时,系统为了维持自身的运转,而随机杀掉占用内存较高的进程,以释放空间.
但是,很明显,我的被杀掉的进程占用的内存很小,而且我的系统资源也够用.
那么思来想去,唯一的一种可能就是,我的进程是被系统里面写好的,类似定时任务的机制,给杀掉的.且这个定时任务,是每隔一段时间自动执行的,因此即使我后来手动重启了服务,还是会被这个interval类型的定时任务给杀掉.
最后,我回忆了一下,终于想到了问题的根源.是我在大概一年前,为了测试一个定时任务时,在系统的crontab中,增加了一个定时脚本.
2.2 问题根源
大概一年前,同事撰写了一个定时杀掉和重启docker服务的脚本,命名为start_docker.sh.
#!/bin/bash
/bin/date
cd /path/to/docker/
/usr/local/bin/docker-compose down
/usr/local/bin/docker-compose up -d
sleep 10
docker_service_count=`/usr/local/bin/docker-compose config --services |wc -l`
for i in `/usr/local/bin/docker-compose config |grep ' scale: ' |awk '{print $2}'`
do
docker_service_count=`expr $docker_service_count + $i - 1`
done
while [ `/usr/local/bin/docker-compose ps |grep Up|wc -l` -ne $docker_service_count ]
do
echo "There is something not Up totally, try again at : "`/bin/date`
echo "docker-compose ps :"`/usr/local/bin/docker-compose ps |grep Up|wc -l`
echo "docker-compose service count :"$docker_service_count
/usr/local/bin/docker-compose down
/usr/local/bin/docker-compose up -d
sleep 10
done
这个脚本的大概作用就是,监测位于/path/to/docker/目录下的docker-compose.yml中的服务,在运行完docker-compose up -d后,是否所有的服务都正常启动了(即是否所有服务的状态都是Up).
如果发现有服务的状态不正常,就再运行docker-compose down, 关闭服务后,再尝试up -d.
如此反复,直至所有服务都正常启动为止.
然后运行:
sudo chmod +x start_docker.sh
sudo mv start_docker.sh /etc/init.d/
将以上的start_docker.sh, 转化为可执行文件.并将它移动到系统的 /etc/init.t目录下.
执行 crontab -e ,在crontab定时任务中,添加如下行:
0 19 * * * /etc/init.d/start_docker.sh >> /tmp/start_docker.log 2>&1
然后在系统的定时任务中,设置每天的19点,运行该可执行程序,并记录脚本运行的日志.
虽然这里只设置了每天运行一次.
但是这个脚本一旦开始执行,如果它发现有服务未正常启动,就会每隔10s,down up一次.
而随着不断的down和up容器,会产生很多很多的volumes.
就是这些不断增长的volumes, 将我系统的SSD占满了.
而且,自己的系统,每隔10s运行一次down和up的操作,也会影响到其他进程的运行流畅度.
2.3 解决方案
问题定位到后,就很好解决了.
不管是将/etc/init.d目录下的start_docker.sh删除,还是在crontab -e, 将设置的定时任务停掉,都可以解决.
执行完上述步骤后,我的容器终于可以稳定的运行了.
虽然下午花了2~3个小时的时间才解决,但是对于我来说,还是很值的.
最重要的,也是提高了我自己解决系统问题的自信.
以前遇到类似的问题,我总是觉得自己不是特别擅长操作系统方面的知识,所以会逃避问题.
但是,当某一天真得逼得自己没办法时,通过不断的思考和寻找线索,问题还是能解决的.
3. 启发
通过这次的问题解决,我的思考是:做事情一定要有始有终.
我之前是因为测试一个问题时,增加了那个定时脚本.但是之后却一直留在了自己的系统中,没有及时把它停掉,导致困扰了我一年.如果当时做完测试,及时把定时任务关闭,就不会有这个问题了.