自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Kubernetes中的事件收集以及監(jiān)控告警

云計算 云原生
Kubernetes本身是一個復(fù)雜的管理系統(tǒng),它既然是作為企業(yè)業(yè)務(wù)的基礎(chǔ)設(shè)施,其本身以及運行在集群內(nèi)部的業(yè)務(wù)系統(tǒng)對于企業(yè)來說都變得非常重要。為此,在實際工作中,我們會借助需要的監(jiān)控手段來提升Kubernetes本身以及業(yè)務(wù)的可觀測性。

Kubernetes中的事件監(jiān)控

隨著微服務(wù)以及云原生的發(fā)展,越來越多的企業(yè)都將業(yè)務(wù)部署運行到Kubernetes中,主要是想依托Kubernetes的可擴(kuò)展、可伸縮、自動化以及高穩(wěn)定性來保障業(yè)務(wù)的穩(wěn)定性。

然而,Kubernetes本身是一個復(fù)雜的管理系統(tǒng),它既然是作為企業(yè)業(yè)務(wù)的基礎(chǔ)設(shè)施,其本身以及運行在集群內(nèi)部的業(yè)務(wù)系統(tǒng)對于企業(yè)來說都變得非常重要。為此,在實際工作中,我們會借助需要的監(jiān)控手段來提升Kubernetes本身以及業(yè)務(wù)的可觀測性,常見的有:

  • 使用cAdvisor來獲取容器的資源指標(biāo),比如cpu、內(nèi)存;
  • 使用kube-state-metrics來獲取資源對象的狀態(tài)指標(biāo),比如Deployment、Pod的狀態(tài);
  • 使用metrics-server來獲取集群范圍內(nèi)的資源數(shù)據(jù)指標(biāo);
  • 使用node-exporter等一系列官方以及非官方的exporter來獲取特定組件的指標(biāo);

在大部分的監(jiān)控場景中,我們都是對特定資源進(jìn)行特定監(jiān)控,比如Pod,Node等。但是,在Kubernetes中還有一些場景是無法通過資源來表述的,就是說它們不是特定的資源,比如Pod調(diào)度、重啟,在Kubernetes中,這類場景主要稱之為事件。

在Kubernetes中,存在兩種事件:

  • Warning事件,事件的狀態(tài)轉(zhuǎn)換是在非預(yù)期的狀態(tài)之間產(chǎn)生。
  • Normal事件,期望達(dá)到的狀態(tài)和目前的狀態(tài)是一致的。

在這里,我們用Pod來進(jìn)行說明。當(dāng)創(chuàng)建Pod的時候,會先進(jìn)入Pending狀態(tài),然后再進(jìn)入Creating狀態(tài)(主要是在拉取鏡像),再進(jìn)去NotReady狀態(tài)(主要是應(yīng)用啟動并且等待健康檢測通過),最后進(jìn)入Running狀態(tài),這整個過程就會生成Normal事件。但是,如果在運行過程中,如果Pod因為一些異常原因進(jìn)入其他狀態(tài),比如節(jié)點驅(qū)逐、OOM等,在這個狀態(tài)轉(zhuǎn)換的過程中,就會產(chǎn)生Warning事件。在Kubernetes中,我們可以通過其他辦法來保障業(yè)務(wù)的穩(wěn)定性,比如為了避免Pod調(diào)度到一個節(jié)點或者同可用區(qū)等而采用親和性以及反親和性調(diào)度,為了避免節(jié)點驅(qū)逐導(dǎo)致某個單個Pod不可用而采用的PDB等,也許某個Warning事件并不會對整個業(yè)務(wù)的穩(wěn)定性帶來致命的影響,但是如果能夠通過監(jiān)控事件的手段來感知集群的某個狀態(tài)變化是有助于進(jìn)行查漏補(bǔ)缺的,也有助于我們感知一些容易忽略的問題。

在Kubernetes中,所有事件都通過事件系統(tǒng)記錄到APIServer中,并且最終存入在Etcd中,我們可以通過API或者kubectl進(jìn)行查看,比如:

也可以查看某個對象的事件,比如:

圖片

事件包含了時間、類型、對象、原因以及描述等,通過事件我們能夠知道應(yīng)用的部署、調(diào)度、運行、停止等整個生命周期,也能通過事件去了解系統(tǒng)中正在發(fā)生的一些異常。在Kubernetes各個組件的源碼中都會定義該組件可能會觸發(fā)的事件類型,比如在kubelet的源碼中定義了許多的事件類型,如下:

package events

// Container event reason list
const (
 CreatedContainer        = "Created"
 StartedContainer        = "Started"
 FailedToCreateContainer = "Failed"
 FailedToStartContainer  = "Failed"
 KillingContainer        = "Killing"
 PreemptContainer        = "Preempting"
 BackOffStartContainer   = "BackOff"
 ExceededGracePeriod     = "ExceededGracePeriod"
)

// Pod event reason list
const (
 FailedToKillPod                = "FailedKillPod"
 FailedToCreatePodContainer     = "FailedCreatePodContainer"
 FailedToMakePodDataDirectories = "Failed"
 NetworkNotReady                = "NetworkNotReady"
)
......

Kubernetes事件最終是存在Etcd中,默認(rèn)只保存1小時,由于Etcd本身并不支持一些復(fù)雜的分析操作,只能被動地存在Etcd中,并不支持主動推送到其他系統(tǒng),通常情況下只能手動去查看。

在實際中,我們對Kubernetes事件還有其他的需求,比如:

  • 希望對異常的事件做告警處理;
  • 希望查詢更長事件的歷史事件;
  • 希望對集群事件進(jìn)行靈活的統(tǒng)計分析;

為此,我們需要單獨對Kubernetes事件進(jìn)行收集,以便適用于查詢以及告警。

在社區(qū)中,有很多工具來做事件的收集以及告警,我常用的兩個工具是:

  • kube-eventer:阿里云推出的事件收集工具;
  • kube-event-exporter:Github上另外一個事件收集工作;

在實際工作中,可以選擇使用其中一個,基本都能滿足收集以及告警功能。在這里,我將同時使用上面兩個插件,用kube-eventer來進(jìn)行告警,用kube-event-exporter將事件收集到ES中進(jìn)行查看和分析。

使用kube-eventer進(jìn)行事件告警

kube-eventer的告警通道可以是企業(yè)微信、釘釘以及webhook??梢愿鶕?jù)需要進(jìn)行選擇,每個組件的具體使用方法在項目的docs/en目錄中,這里選擇使用webhook將告警發(fā)送到企業(yè)微信中。

(1)首先需要在企業(yè)微信群里創(chuàng)建一個webhook機(jī)器人,然后獲取webhook地址。

(2)在Kubernetes集群中部署kube-eventer。

# cat kube-eventer.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: kube-eventer
  name: kube-eventer
  namespace: monitoring
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:v1.2.7-ca03be0-aliyun
          name: kube-eventer
          command:
            - "/kube-eventer"
            - "--source=kubernetes:https://kubernetes.default.svc.cluster.local"
            ## .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:http://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=888888-888-8888-8888-d35c52ff2e0b&level=Warning&header=Content-Type=application/json&custom_body_cnotallow=custom-webhook-body&custom_body_configmap_namespace=monitoring&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: monitoring
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-eventer
  namespace: monitoring
---
apiVersion: v1
data:
  content: >-
    {"msgtype": "text","text": {"content": "集群事件告警\n事件級別: {{ .Type }}\n名稱空間: {{ .InvolvedObject.Namespace }}\n事件類型: {{ .InvolvedObject.Kind }}\n事件對象: {{ .InvolvedObject.Name }}\n事件原因: {{ .Reason }}\n發(fā)生時間: {{ .LastTimestamp }}\n詳細(xì)信息: {{ .Message }}"}}
kind: ConfigMap
metadata:
  name: custom-webhook-body
  namespace: monitoring

在webhook的配置中增加了level=Warning,表示只要Warning事件才會告警通知,除此之外,還可以通過namespaces字段來過來需要告警的命名空間,通過kinds字段來過濾需要告警的對象,比如只需要發(fā)送Node的Warning事件,則可以寫成level=warning&kinds=Node。再比如,如果不想產(chǎn)生非常多的告警風(fēng)暴,只發(fā)送某些特定原因的告警,比如系統(tǒng)OOM的事件,可以增加reasnotallow=SystemOOM等待。

當(dāng)kube-eventer的Pod啟動完成后,企業(yè)微信即可收到滿足條件的事件告警,比如:

圖片

使用kube-event-exporter收集集群事件

上面使用kube-eventer進(jìn)行事件告警,本質(zhì)上并沒有存儲歷史事件,而實際中可能需要查詢歷史事件并且對其做一些事件分析,而ES是常用于進(jìn)行內(nèi)容收集并通過kibana進(jìn)行查看和分析,所以這里我們將使用kube-event-exporter收集Kubernetes事件到ES中。

kube-event-exporter可以直接將事件存入ES,也可以將事件發(fā)送到kafka,然后再通過Logstash消費Kafka中的數(shù)據(jù)將其存入ES。在這里,我基于環(huán)境現(xiàn)狀,將事件發(fā)送給Kafka,然后再消費收集到ES。

(1)部署kube-event-exporter

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: monitoring
  name: event-exporter
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: event-exporter
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - kind: ServiceAccount
    namespace: monitoring
    name: event-exporter
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: event-exporter-cfg
  namespace: monitoring
data:
  config.yaml: |
    logLevel: error
    logFormat: json
    route:
      routes:
        - match:
            - receiver: "kafka"
          drop:
            - kind: "Service"
    receivers:
      - name: "kafka"
        kafka:
          clientId: "kubernetes"
          topic: "kubenetes-event"
          brokers:
            - "192.168.100.50:9092"
            - "192.168.100.51:9092"
            - "192.168.100.52:9092"
          compressionCodec: "snappy"
          layout: #optional
            kind: "{{ .InvolvedObject.Kind }}"
            namespace: "{{ .InvolvedObject.Namespace }}"
            name: "{{ .InvolvedObject.Name }}"
            reason: "{{ .Reason }}"
            message: "{{ .Message }}"
            type: "{{ .Type }}"
            timestamp: "{{ .GetTimestampISO8601 }}"
            cluster: "sda-pre-center"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: event-exporter
  namespace: monitoring
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: event-exporter
        version: v1
    spec:
      serviceAccountName: event-exporter
      containers:
        - name: event-exporter
          image: ghcr.io/resmoio/kubernetes-event-exporter:latest
          imagePullPolicy: IfNotPresent
          args:
            - -cnotallow=/data/config.yaml
          volumeMounts:
            - mountPath: /data
              name: cfg
      volumes:
        - name: cfg
          configMap:
            name: event-exporter-cfg
  selector:
    matchLabels:
      app: event-exporter
      version: v1

當(dāng)kube-event-exporter的Pod啟動過后,可以在kafka中查看到收集的事件,如下:

圖片

(2)部署logstash將事件存入ES

kind: Deployment
apiVersion: apps/v1
metadata:
  name: kube-event-logstash
  namespace: log
  labels:
    app: kube-event-logstash
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-event-logstash
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: kube-event-logstash
      annotations:
        kubesphere.io/restartedAt: '2024-02-22T09:03:36.215Z'
    spec:
      volumes:
        - name: kube-event-logstash-pipeline-config
          configMap:
            name: kube-event-logstash-pipeline-config
            defaultMode: 420
      containers:
        - name: kube-event-logstash
          image: 'logstash:7.8.0'
          env:
            - name: XPACK_MONITORING_ELASTICSEARCH_HOSTS
              value: 'http://192.168.100.100:8200'
            - name: XPACK_MONITORING_ELASTICSEARCH_USERNAME
              value: jokerbai
            - name: XPACK_MONITORING_ELASTICSEARCH_PASSWORD
              value: JeA9BiAgnNRzVrp5JRVQ4vYX
            - name: PIPELINE_ID
              value: kube-event-logstash
            - name: KAFKA_SERVER
              value: '192.168.100.50:9092,192.168.100.51:9092,192.168.100.52:9092'
            - name: ES_SERVER
              value: 'http://192.168.100.100:8200'
            - name: ES_USER_NAME
              value: jokerbai
            - name: ES_USER_PASSWORD
              value: JeA9BiAgnNRzVrp5JRVQ4vYX
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name
            - name: PIPELINE_BATCH_SIZE
              value: '4000'
            - name: PIPELINE_BATCH_DELAY
              value: '100'
            - name: PIPELINE_WORKERS
              value: '4'
            - name: LS_JAVA_OPTS
              value: '-Xms2g -Xmx3500m'
          resources:
            limits:
              cpu: '2'
              memory: 4Gi
            requests:
              cpu: '2'
              memory: 4Gi
          volumeMounts:
            - name: kube-event-logstash-pipeline-config
              mountPath: /usr/share/logstash/pipeline
          livenessProbe:
            tcpSocket:
              port: 9600
            initialDelaySeconds: 39
            timeoutSeconds: 5
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          readinessProbe:
            tcpSocket:
              port: 9600
            initialDelaySeconds: 39
            timeoutSeconds: 5
            periodSeconds: 30
            successThreshold: 1
            failureThreshold: 2
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: node/category
                    operator: In
                    values:
                      - app
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-event-logstash-pipeline-config
  namespace: log
data:
  logstash.conf: |-
    input {
      kafka {
        id => "kafka_plugin_id"
        bootstrap_servers => "${KAFKA_SERVER}"
        client_id => "logstash"
        group_id => "logstash"
        decorate_events => true
        topics => ["kubenetes-event"]
        codec => json {
          charset => "UTF-8"
        }
      }
    }

    output {
        elasticsearch {
          hosts => "${ES_SERVER}"
          user => "${ES_USER_NAME}"
          password => "${ES_USER_PASSWORD}"
          index => "kubernetes-event-%{+YYYY.MM}"
          manage_template => false
          template_name => "kubernetes-event"
        }
    }

部署之前,先在ES中創(chuàng)建template,可以在kibana中的dev tools中進(jìn)行操作,語句如下:

PUT _template/kubernetes-event
{
    "index_patterns" : [
      "*kubernetes-event*"
    ],
    "settings": {
      "index": {
        "highlight": {
          "max_analyzed_offset": "10000000"
        },
        "number_of_shards": "2",
        "number_of_replicas": "0"
      }
    },
    "mappings": {
      "properties": {
        "cluster": {
          "type": "keyword"
        },
        "kind": {
          "type": "keyword"
        },
        "message": {
          "type": "text"
        },
        "name": {
          "type": "keyword"
        },
        "namespace": {
          "type": "keyword"
        },
        "reason": {
          "type": "keyword"
        },
        "type": {
          "type": "keyword"
        },
        "timestamp": {
          "type": "keyword"
        }
      }
    },
    "aliases": {}
}

然后再在Kubernetes集群中部署Logstash。然后就可以在Kibana上查看收集到的事件了,如下:

圖片

只要數(shù)據(jù)有了,不論是查詢還是做分析,都變得簡單容易了。比如最簡單得統(tǒng)計今天事件原因為Unhealthy所發(fā)生的總次數(shù),可以在Kibana中創(chuàng)建圖表,如下:

圖片

以上就是在Kubernetes中對集群事件進(jìn)行收集和告警,這是站在巨人的肩膀上直接使用。在企業(yè)中還可以對其進(jìn)行二次開放以將功能更豐富,比如支持對事件告警增加開關(guān),可以任意開啟或者關(guān)閉某個事件告警。

鏈接

[1] https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/events/event.go?spm=a2c6h.12873639.article-detail.7.c8585c576FGh7o&file=event.go。

[2] https://github.com/AliyunContainerService/kube-eventer。

[3] https://github.com/resmoio/kubernetes-event-exporter。

責(zé)任編輯:姜華 來源: 運維開發(fā)故事
相關(guān)推薦

2024-02-23 14:57:40

2022-05-05 07:25:03

Supervisor監(jiān)控Python

2022-07-29 21:23:54

Grafana微服務(wù)

2022-07-28 06:50:52

微服務(wù)業(yè)務(wù)系統(tǒng)

2021-06-21 08:59:55

監(jiān)控Netflix優(yōu)化

2021-06-21 08:30:14

Netflix監(jiān)控系統(tǒng)微服務(wù)

2024-01-05 11:49:30

K8S監(jiān)控告警

2025-03-13 08:01:32

2023-12-20 08:13:54

K8S監(jiān)控管理

2022-01-21 08:36:21

LogstashZabbix監(jiān)控

2020-10-09 06:55:23

監(jiān)控告警日志

2022-11-08 00:00:00

監(jiān)控系統(tǒng)Prometheus

2020-12-10 10:00:59

監(jiān)控Java可視化

2025-01-06 10:38:04

2019-03-19 08:41:38

Linux運維變更

2022-07-28 08:45:40

Web應(yīng)用監(jiān)控與告警

2019-01-17 08:38:03

Redis監(jiān)控內(nèi)存

2023-04-20 07:12:33

夜鶯監(jiān)控夜鶯

2020-12-17 09:25:46

運維Prometheus監(jiān)控

2021-09-27 19:41:31

監(jiān)控Sentry Alerts
點贊
收藏

51CTO技術(shù)棧公眾號