k8s event監控利器kube-eventer對接企微告警

落魄運維發表於2020-11-15

背景

監控是保障系統穩定性的重要組成部分,在Kubernetes開源生態中,資源類的監控工具與元件監控百花齊放。

  • cAdvisor:kubelet內建的cAdvisor,監控容器資源,如容器cpu、記憶體;
  • Kube-state-metrics:kube-state-metrics通過監聽 API Server 生成有關資源物件的狀態指標,主要關注後設資料,比如 Deployment、Pod、副本狀態等;
  • metrics-server:metrics-server 也是一個叢集範圍內的資源資料聚合工具,是 Heapster 的替代品,k8s的HPA元件就會從metrics-server中獲取資料;
  • 還有node-exporter、各個官方、非官方的exporter,使用 Prometheus 來抓取這些資料然後儲存,告警,視覺化。但這些還遠遠不夠。

監控的實時性與準確性不足
大部分資源監控都是基於推或者拉的模式進行資料離線,因此通常資料是每隔一段時間採集一次,如果在時間間隔內出現一些毛刺或者異常,而在下一個採集點到達時恢復,大部分的採集系統會吞掉這個異常。而針對毛刺的場景,階段的採集會自動削峰,從而造成準確性的降低。

監控的場景覆蓋範圍不足
部分監控場景是無法通過資源表述的,比如Pod的啟動停止,是無法簡單的用資源的利用率來計量的,因為當資源為0的時候,我們是不能區分這個狀態產生的真實原因。

基於上述兩個問題,Kubernetes是怎麼解決的呢?

事件監控

在Kubernetes中,事件分為兩種,一種是Warning事件,表示產生這個事件的狀態轉換是在非預期的狀態之間產生的;另外一種是Normal事件,表示期望到達的狀態,和目前達到的狀態是一致的。我們用一個Pod的生命週期進行舉例,當建立一個Pod的時候,首先Pod會進入Pending的狀態,等待映象的拉取,當映象錄取完畢並通過健康檢查的時候,Pod的狀態就變為Running。此時會生成Normal的事件。而如果在執行中,由於OOM或者其他原因造成Pod宕掉,進入Failed的狀態,而這種狀態是非預期的,那麼此時會在Kubernetes中產生Warning的事件。那麼針對這種場景而言,如果我們能夠通過監控事件的產生就可以非常及時的檢視到一些容易被資源監控忽略的問題。

一個標準的Kubernetes事件有如下幾個重要的屬性,通過這些屬性可以更好地診斷和告警問題。

Namespace:產生事件的物件所在的名稱空間。
Kind:繫結事件的物件的型別,例如:Node、Pod、Namespace、Componenet等等。
Timestamp:事件產生的時間等等。
Reason:產生這個事件的原因。
Message: 事件的具體描述。

[root@master work]# kubectl get event --all-namespaces 
 LAST SEEN TYPE REASON OBJECT MESSAGE
default 14m Normal Created pod/busybox2 Created container busybox
default 14m Normal Started pod/busybox2 Started container busybox
default 24m Warning Failed pod/litemall-all-584bfdcd99-q6wd2 Error: ErrImagePull
default 4m47s Warning Failed pod/litemall-all-584bfdcd99-q6wd2 Error: ImagePullBackOff

ali kube-eventer

針對Kubernetes的事件監控場景,Kuernetes社群在Heapter中提供了簡單的事件離線能力,後來隨著Heapster的廢棄,相關的能力也一起被歸檔了。為了彌補事件監控場景的缺失,阿里雲容器服務釋出並開源了kubernetes事件離線工具kube-eventer。支援離線kubernetes事件到釘釘機器人、SLS日誌服務、Kafka開源訊息佇列、InfluxDB時序資料庫等等。

GitHub地址:https://github.com/AliyunContainerService/kube-eventer

下面是以企業微信機器人告警傳送為例:

[root@node1 monitoring]# cat kube-eventer.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: kube-eventer
  name: kube-eventer
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-eventer
  template:
    metadata:
      labels:
        app: kube-eventer
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      dnsPolicy: ClusterFirstWithHostNet
      serviceAccount: kube-eventer
      containers:
        - image: registry.aliyuncs.com/acs/kube-eventer-amd64:v1.2.0-484d9cd-aliyun
          name: kube-eventer
          command:
            - "/kube-eventer"
            - "--source=kubernetes:https://kubernetes.default"
            ## .e.g,dingtalk sink demo
            #- --sink=dingtalk:[your_webhook_url]&label=[your_cluster_id]&level=[Normal or Warning(default)]
            #- --sink=webhook:https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=07055f32-a04e-4ad7-9cb1-d22352769e1c&level=Warning&label=oa-k8s
            - --sink=webhook:https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=07055f32-a04e-4ad7-9cb1-d223&level=Warning&header=Content-Type=application/json&custom_body_configmap=custom-webhook-body&custom_body_configmap_namespace=kube-system&method=POST
          env:
          # If TZ is assigned, set the TZ value as the time zone
          - name: TZ
            value: "Asia/Shanghai"
          volumeMounts:
            - name: localtime
              mountPath: /etc/localtime
              readOnly: true
            - name: zoneinfo
              mountPath: /usr/share/zoneinfo
              readOnly: true
          resources:
            requests:
              cpu: 100m
              memory: 100Mi
            limits:
              cpu: 500m
              memory: 250Mi
      volumes:
        - name: localtime
          hostPath:
            path: /etc/localtime
        - name: zoneinfo
          hostPath:
            path: /usr/share/zoneinfo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-eventer
rules:
  - apiGroups:
      - ""
    resources:
      - events
      - configmaps
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kube-eventer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-eventer
subjects:
  - kind: ServiceAccount
    name: kube-eventer
    namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-eventer
  namespace: kube-system
---
apiVersion: v1
data:
  content: >-
    {"msgtype": "text","text": {"content": "EventType:{{ .Type }}\nEventNamespace:{{ .InvolvedObject.Namespace }}\nEventKind:{{ .InvolvedObject.Kind }}\nEventObject:{{ .InvolvedObject.Name }}\nEventReason:{{ .Reason }}\nEventTime:{{ .LastTimestamp }}\nEventMessage:{{ .Message }}"}}
kind: ConfigMap
metadata:
  name: custom-webhook-body
  namespace: kube-system

效果:

 

 

 

 

 

相關文章