k8s 事件监听工具kubewatch

2022-07-05  本文已影响0人  国服最坑开发

TL;DR

简单来说, 我希望把 `kubectl get event`事件对接到集群外面, 直接推送到企业微信.

0x01 原理

直接使用开源组件 kubewatch
这个组件支持 http webhook , 我们只需要另行简单开发一个 webhook接口就好了.

按官方文档部署时, 有一个坑, webhook一直无法被调用.
最后还是按自己的方式尝试解决:

在启动Pod时 添加env , 指定webhook的 URL参数: KW_WEBHOOK_URL

0x02 部署文件

下面这个文件可以直接部署: kubectl apply -f a.yaml

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: kubewatch
data:
  .kubewatch.yaml: |
    resource:
      deployment: true
      replicationcontroller: true
      replicaset: true
      daemonset: true
      services: true
      pod: true
      secret: true
      configmap: true
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubewatch
rules:
- apiGroups: ["", "apps"]
  resources: ["namespaces","deployments","pods","services", "replicationcontrollers"]
  verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubewatch
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubewatch
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubewatch
subjects:
  - kind: ServiceAccount
    name: kubewatch
    namespace: default
---
apiVersion: v1
kind: Pod
metadata:
  name: kubewatch
  namespace: default
spec:
  serviceAccountName: kubewatch
  containers:
  - image: bitnami/kubewatch
    imagePullPolicy: Always
    name: kubewatch
    volumeMounts:
    - name: config-volume
      mountPath: /root
    env:
      - name: KW_WEBHOOK_URL
        value: "http://10.10.10.10:8080"
  restartPolicy: Always
  volumes:
  - name: config-volume
    configMap:
      name: kubewatch

0x03 Webhook数据结构

查看源码发现调用webhook时, 会发起一个post请求, body 为 json 字符串

下面是go语言的处理实现:


import (
    "fmt"
    "github.com/gin-gonic/gin"
    "os"
    "time"
)

// WebhookMessage for messages
type WebhookMessage struct {
    EventMeta EventMeta `json:"eventmeta"`
    Text      string    `json:"text"`
    Time      time.Time `json:"time"`
}

// EventMeta containes the meta data about the event occurred
type EventMeta struct {
    Kind      string `json:"kind"`
    Name      string `json:"name"`
    Namespace string `json:"namespace"`
    Reason    string `json:"reason"`
}

func main() {
    r := gin.Default()
    r.POST("/", func(c *gin.Context) {
        var body WebhookMessage
        if c.BindJSON(&body) != nil {
            c.JSON(200, gin.H{"err": "invalid param"})
            return
        }
        // 发送微信消息: SendTextMessage(body.ToWeChatString())
        c.JSON(200, gin.H{"reason": body.EventMeta.Reason})
    })
    r.Run(":8080")
}

关于微信发消息, 自行baidu, 不再赘述.

上一篇 下一篇

猜你喜欢

热点阅读