監控是保障系統穩定性的重要組成部分,在Kubernetes開源生態中,資源類的監控工具與組件監控百花齊放。node
監控的實時性與準確性不足
大部分資源監控都是基於推或者拉的模式進行數據離線,所以一般數據是每隔一段時間採集一次,若是在時間間隔內出現一些毛刺或者異常,而在下一個採集點到達時恢復,大部分的採集系統會吞掉這個異常。而針對毛刺的場景,階段的採集會自動削峯,從而形成準確性的下降。git
監控的場景覆蓋範圍不足
部分監控場景是沒法經過資源表述的,好比Pod的啓動中止,是沒法簡單的用資源的利用率來計量的,由於當資源爲0的時候,咱們是不能區分這個狀態產生的真實緣由。github
基於上述兩個問題,Kubernetes是怎麼解決的呢?web
在Kubernetes中,事件分爲兩種,一種是Warning事件,表示產生這個事件的狀態轉換是在非預期的狀態之間產生的;另一種是Normal事件,表示指望到達的狀態,和目前達到的狀態是一致的。咱們用一個Pod的生命週期進行舉例,當建立一個Pod的時候,首先Pod會進入Pending的狀態,等待鏡像的拉取,當鏡像錄取完畢並經過健康檢查的時候,Pod的狀態就變爲Running。此時會生成Normal的事件。而若是在運行中,因爲OOM或者其餘緣由形成Pod宕掉,進入Failed的狀態,而這種狀態是非預期的,那麼此時會在Kubernetes中產生Warning的事件。那麼針對這種場景而言,若是咱們可以經過監控事件的產生就能夠很是及時的查看到一些容易被資源監控忽略的問題。數據庫
一個標準的Kubernetes事件有以下幾個重要的屬性,經過這些屬性能夠更好地診斷和告警問題。json
Namespace:產生事件的對象所在的命名空間。
Kind:綁定事件的對象的類型,例如:Node、Pod、Namespace、Componenet等等。
Timestamp:事件產生的時間等等。
Reason:產生這個事件的緣由。
Message: 事件的具體描述。api
[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
針對Kubernetes的事件監控場景,Kuernetes社區在Heapter中提供了簡單的事件離線能力,後來隨着Heapster的廢棄,相關的能力也一塊兒被歸檔了。爲了彌補事件監控場景的缺失,阿里雲容器服務發佈並開源了kubernetes事件離線工具kube-eventer。支持離線kubernetes事件到釘釘機器人、SLS日誌服務、Kafka開源消息隊列、InfluxDB時序數據庫等等。微信
GitHub地址:https://github.com/AliyunContainerService/kube-eventerapp
下面是以企業微信機器人告警發送爲例:工具
[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
效果: