清澈如初|一个小需求,自动重启k8s集群中日志不刷新的POD


清澈如初|一个小需求,自动重启k8s集群中日志不刷新的PODk8s
需求日常工作中 , 所有项目都不是完美的 , 笔者就经常遇到这种情况 , pod状态是running , 但是程序却没有响应 。 发生这种情况的原因有很多种 , 有可能是因为k8s健康检查的原因 , 比如使用ps检查进程;或者是程序内部死循环 , 但是不退出;再或者网络闪断 , 程序无法重连等等 。
无论什么原因 , 都会有解决办法 , 但是优化需要时间 , 在未完全解决之前 , 问题不能不解决 , 于是想到了一个临时方案 , 因为笔者公司项目日志是直接打印在stdout的 , 发生了程序无响应的情况 , 比较简单的一个办法是判断日志输出的时间 。 基于此 , 可以简单写一个小脚本 , 发现日志长时间不输出的时候 , 重启pod 。
思路使用kubectl logs命令查看最后一条日志输出的时间戳 , 与服务器时间对比 , 差值大于阈值 , 则重启相应POD 。 当然 , 这只是一个简单的思路 , 并不适用于大部分场景 , 但是适合笔者公司 , 因为核心项目请求量很大 , 但凡是超过1分钟日志不刷新 , 基本可以断定100%出现问题了 。
此思路其实也是抛砖引玉 , 希望能给大家一些灵感 , 如果有什么更好的办法 , 也可以与笔者沟通交流 。
简单实现shell比较简单 , 直接与服务器交互也比较友好 , 就是用shell来写吧 。
#!/bin/sh# 获取当前UTC时间utc_now=`date -u`# 将时间转换为timestamptimestamp_now=`date -d "$utc_now" +%s`function restart_pod() {for i in `kubectl get pod -n iot|grep PODNAME|awk '{print $1}'`;dofor time in `kubectl logs--tail=1 --timestamps $i -n iot | awk '{print $1}'`;dotimestamp_pod=`date -d "$time" +%s`delay=$(($timestamp_now-$timestamp_pod))echo $i:$delayif [ "$delay" -ge "30" ];thenecho "Pod $i 30S内没有最新日志产生 , 重启pod!"echo $ikubectl delete pod $i -n iot --force --grace-period=0curlwxFunc "Pod $i 30S内没有最新日志产生 , 重启pod!(生产环境)"fidonedone}function curlwxFunc() {JSON='{"msgtype": "text","text": {"content": "'$1'"}}'curl '' \-H 'Content-Type:application/json' \-d "${JSON}"}restart_pod脚本很简单 , 先查询pod , 然后看pod最后一条日志时间 , 与服务器时间对比 , 延迟超过30s就重启pod , 并且调用企业微信接口发一条通知 。
后记【清澈如初|一个小需求,自动重启k8s集群中日志不刷新的POD】此方法也是治标不治本 , 治标还需要从源头解决 , 不过需要时间 , 再没有解决之前 , 先用这个小脚本抗一抗吧 。 也欢迎大家拍砖 。