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, 不再赘述.
网友评论