代码实现:
package main
import (
"bytes"
"encoding/json"
"fmt"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
"net/http"
"pod_informer/sink"
"time"
)
type DingTalkMessage struct {
MsgType string `json:"msgtype"`
Markdown struct {
Title string `json:"title,omitempty"`
Text string `json:"text"`
} `json:"markdown"`
PicURL string `json:"picUrl,omitempty"` // 图片链接字段,用于非模板消息中的图片
}
func SendDingTalkNotification(message, picURL string, webhookURL string) error {
dingTalkMsg := DingTalkMessage{
MsgType: "markdown",
Markdown: struct {
Title string `json:"title,omitempty"`
Text string `json:"text"`
}{
Title: " Kubernetes Event Alert", //可选的标题
Text: fmt.Sprintf("![]( %s )\n%s", picURL, message),
},
}
msgBytes, err := json.Marshal(dingTalkMsg)
if err != nil {
return fmt.Errorf("failed to marshal message: %w", err)
}
resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(msgBytes))
if err != nil {
return fmt.Errorf("failed to send POST request: %w", err)
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("non-200 response from DingTalk: %d", resp.StatusCode)
}
return nil
}
func EventHandler(obj interface{}) {
event, ok := obj.(*v1.Event)
if !ok {
fmt.Println("Received a non-Event object")
return
}
alertTime := time.Now().Format("2006-01-02 15:04:05")
eventTime := event.EventTime
namespace := event.ObjectMeta.Namespace
eventName := event.InvolvedObject.Name
eventType := event.Type
message := fmt.Sprintf("【告警中】\n\n工作空间: %s\n\n事件类型: %s\n\n事件时间: %s\n\n告警时间: %s\n\n应用名称: %s\n\n应用状态: %s\n\n应用信息: %s",
namespace, eventType, eventTime, alertTime, eventName, event.Reason, event.Message)
//图片替换为实际的值,获取环境变量
//webhookURL := os.Getenv("WEBHOOKURL")
imageurl := "https://5b0988e595225.cdn.sohucs.com/images/20200304/d1211d8ffdbb430eb0d445565aa134ba.gif"
// 钉钉机器人的Webhook URL替换为实际值
webhookURL := "webhook URL替换为实际值"
if err := sink.SendDingTalkNotification(message, imageurl, webhookURL); err != nil {
fmt.Printf("Failed to send DingTalk notification: %v\n", err)
}
}
func main() {
// 初始化Kubernetes客户端
kubeConfig, err := clientcmd.BuildConfigFromFlags("", ".kube/config")
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
panic(err)
}
// 创建informer工厂
informerFactory := informers.NewSharedInformerFactory(clientset, 0)
// 监听所有命名空间的Event
eventInformer := informerFactory.Core().V1().Events().Informer()
// 注册EventHandler
eventInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: EventHandler,
UpdateFunc: func(oldObj, newObj interface{}) { EventHandler(newObj) },
DeleteFunc: EventHandler,
})
// 启动informers
informerFactory.Start(nil)
// 等待所有缓存同步完成
informerFactory.WaitForCacheSync(nil)
select {}
}