elk显示每天0点会有一个502的尖峰,奇怪怎么会有502。
由于对rancher不熟,怀疑是不是rancher在做什么daemon process。
然后去查/var/log/message系统日志,查到了一些这样的日志:
Jan 3 00:00:01 rc02 systemd: Started Session 108334 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108334 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108335 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108335 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108336 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108336 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108338 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108338 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108339 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108339 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108337 of user root. Jan 3 00:00:01 rc02 systemd: Starting Session 108337 of user root. Jan 3 00:00:01 rc02 systemd: Started Session 108340 of user zabbix. Jan 3 00:00:01 rc02 systemd: Starting Session 108340 of user zabbix.这个时间点刚好跟502尖峰时刻吻合,而且又这么整齐划一。怀疑是这里的问题。
于是又查systemd: Started Session xxx of user root.
了解到这是centos 7的系统管理进程,还有这篇,而且网友说这是定时任务引起的,突然联想到我的在0点清理nginx日志的定时任务(当然后来知道上面的定时任务跟我的没关系,但也确实是我的定时任务引起的502)。
我的定时任务所执行的内容是每天0点将nginx的访问日志cp一份,然后把旧日志重定向(io redirection)清空“echo ''> old.log"。
问题就出现在这个清空行为上,因为日志量较大,一天12G,清空的操作会耗时几秒的时间。从现象上看有几个点值得深究一下:
1、清空操作(或者说重定向命令在写操作)是否会对文件加锁,如果会加锁的话,nginx写日志的操作就会被等待,超时导致502;对于这个问题,首先锁是不会加的,因为在linux系统中除了内核
2、nginx的11个阶段中,log阶段也会作为响应请求的一部分吗?毕竟作为请求处理阶段肯定是200没问题的,但作为结果看来,log阶段也被包含在响应阶段;
除了上面的问题,还有一个更高层的问题就是:如何对容器内的日志进行转储。如果映射到共享目录,通过logrotate进行转储可能会有问题(会有少量的502,这个不确定是logrotate引起的还是容器相关引起的);如果在容器内部进行转储的话,会导致容器的体积变大且不纯粹。
—— 如果映射到共享目录:
1、如果在物理机的共享目录中进行转储,那么nginx的log rotate有一个教程,就两句,先mv oldfile newfile,然后kill -USR1 nginx.pid进行重新加载nginx配置文件。但这里有个问题,容器相当于是一个系统,里面的进程的pid是1,那映射出来的pid也是1,而1在宿主机,也就是物理机上是init()进程,是系统初始化刚开机时候的引导进程,那肯定是不允许你kill的,所以只能kill nginx在物理机中的进程号了:
/var/logs/ngxp/vplay.log { rotate 1 copytruncate daily dateext missingok sharedscripts postrotate #[ -f /var/vol/hd/openresty/pid/vplay.pid ] && kill -USR1 `cat /var/vol/hd/openresty/pid/vplay.pid` ps aux|grep nginx|grep master|awk '{print $2}'|xargs kill -USR1 endscript }这个也有一个问题,那就是你会kill掉所有包含nginx字样的,服务器的。虽然也没关系反正都得切割日志,只是个小问题;
2、还有一种是通过docker exec命令进行容器重启或者容器内的nginx重启,连接在这儿,我没有试过。主要操作如下:
$ sudo vi /etc/logrotate.d/test /home/test/logs/*log { rotate 90 missingok ifempty sharedscripts compress postrotate docker exec -it nginx-test systemctl reload nginx > /dev/null 2>/dev/null || true endscript }—— 如果在容器内部进行转储:
这样的话,需要配置一下dockerfile,通过yum/apt-get安装一下logrotate。这个可以搜一下Dockerfile的RUN或者EXEC。