站点图标 星露谷值班站长

Golang开发-运维巡检-Kubernetes Pod异常重启上报

在我们使用 kubernetes 的过程总经常会出现 pod 异常重启的情况。

pod 重启一般情况下分为 2 类,1 类是因为程序自身问题异常退出,另一种则是因为资源限制导致系统 OOMKilled 杀死。

在开发运维巡检系统的过程中就在考虑把 pod 异常重启的信息上报到系统里面存储展示,方便后期追溯和问题排查。

因为自己开发工作量比较大,所以就选择了 Github 上的开源项目进行二次开发。

这里选择的项目是 golang 开发的 https://github.com/airwallex/k8s-pod-restart-info-collector

k8s-pod-restart-info-collector 项目默认是上报重启信息到 slack,slack 在国外使用的比较多,国内使用钉钉和飞书的比较多,所以这里对程序进行了二次开发。

二次开发

经过修改后,程序会监听 k8s pod 重启然后把重启信息上报到我们的运维巡检系统,巡检系统负责把数据写入 es 并发送报警到钉钉群组。当然你也可以直接把重启信息发送到钉钉群组,这里我因为要去匹配环境 label 信息达到报警屏蔽的目的。

  1. 扩展环境变量支持
Environment="IGNORE_RESTART_COUNT=300000"
Environment="CLUSTER_NAME= 开发 K8S 集群"
  1. 扩展上报信息

因为需要写入 es,所以字段 key 展示加入了更多的信息展示。

核心修改 controller.go

# k8s node 主机获取
pod.Spec.NodeName
# 命名空间获取
pod.Namespace
# 获取总重启次数
func getPodRestartCount(pod *v1.Pod) int {
	var restarts int = 0
	for i := range pod.Status.ContainerStatuses {container := pod.Status.ContainerStatuses[i]
		restarts += int(container.RestartCount)
	}
	return restarts
}
# 默认上报信息修改, 可以汉化为中文或加入自己的定制环境变量
msg := SlackMessage{Title:  fmt.Sprintf("*Pod 重启!*\n*cluster: `%s`, pod: `%s`, namespace: `%s`*", c.alert.ClusterName, pod.Name, pod.Namespace),
    Text:   podStatus + podEvents + nodeEvents + containerLogs,
    Footer: fmt.Sprintf("%s, %s, %s", c.alert.ClusterName, pod.Name, pod.Namespace),
}
# 对于 deploymentName 的获取判断
# 默认是没有上报 deploymentName 的,我们可以通过下面的方式去获取
var deploymentName string
// deployment 判断
if _, ok := pod.Labels["app"]; ok {deploymentName = pod.Labels["app"]
}
# 这种方法获取的前提是你 yaml 部署模板里面要携带你的服务名称,具体看自身业务定制 

kibana 出图展示

对于问题排查我们可以查看重启时上报的日志信息

使用 systemd 去管理程序启动,通过环境变量去控制环境信息显示

[Unit]
Description=k8s-pod-restart
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=5
User=root
Environment="IGNORE_RESTART_COUNT=300000"
Environment="CLUSTER_NAME= 开发 K8S 集群"
WorkingDirectory=/usr/local/k8s-pod-restart
ExecStart=/usr/local/k8s-pod-restart/k8s-pod-restart
Environment="RUN_ENV=dev"

[Install]
WantedBy=multi-user.target

k8s pod 重启信息钉钉机器人通知

退出移动版