Kubernetes でのイベント収集とアラートの監視

Kubernetes でのイベント収集とアラートの監視

Kubernetes でのイベント監視

マイクロサービスとクラウドネイティブの発展に伴い、Kubernetes の拡張性、スケーラビリティ、自動化、高い安定性に依存してビジネスの安定性を確保するため、Kubernetes にビジネスを展開する企業がますます増えています。

ただし、Kubernetes 自体は複雑な管理システムです。企業ビジネスのインフラストラクチャであるため、クラスタ内で実行されるビジネス システムとクラスタは企業にとって非常に重要になっています。そのため、実際の業務では、Kubernetes自体とビジネスの可観測性を向上させるために必要な監視方法を使用します。一般的なものは次のとおりです。

  • cAdvisor を使用して、CPU やメモリなどのコンテナ リソース メトリックを取得します。
  • kube-state-metrics を使用して、Deployment や Pod のステータスなど、リソース オブジェクトのステータス インジケーターを取得します。
  • metrics-server を使用して、クラスター全体のリソース データ インジケーターを取得します。
  • 特定のコンポーネントのメトリックを取得するには、node-exporter などのさまざまな公式および非公式のエクスポーターを使用します。

ほとんどの監視シナリオでは、Pod、Node などの特定のリソースを監視します。ただし、Kubernetes には、Pod のスケジュール設定や再起動など、リソースでは表現できない、つまり特定のリソースではないシナリオもあります。 Kubernetes では、このようなシナリオは主に事件と呼ばれます。

Kubernetes には、次の 2 種類のイベントがあります。

  • 警告イベント、予期しない状態間でイベントの状態遷移が発生します。
  • 通常のイベント: 予想される状態は現在の状態と一致しています。

ここでは、説明のために Pod を使用します。 Pod を作成すると、最初に Pending 状態になり、次に Creating 状態 (主にイメージのプル) になり、次に NotReady 状態 (主にアプリケーションの起動とヘルスチェックの合格を待機) になり、最後に Running 状態になります。このプロセス全体で通常のイベントが生成されます。ただし、実行プロセス中に、ノードの削除、OOM などの何らかの異常な理由により Pod が他の状態になった場合、この状態遷移中に警告イベントが生成されます。 Kubernetes では、他の方法を使用してビジネスの安定性を確保できます。たとえば、アフィニティ スケジューリングとアンチアフィニティ スケジューリングを使用して、ポッドをノードまたは同じアベイラビリティ ゾーンにスケジュールすることを回避し、PDB を使用して、ノードの削除によって単一のポッドが使用できなくなることを回避できます。警告イベントがビジネス全体の安定性に致命的な影響を与えることはないかもしれませんが、イベントを監視することでクラスターの状態変化を認識できれば、ギャップを見つけるのに役立ち、見落としがちな問題を認識するのにも役立ちます。

Kubernetes では、すべてのイベントはイベント システムを通じて API サーバーに記録され、最終的に Etcd に保存されます。これらは、API または kubectl を通じて表示できます。次に例を示します。

次のようなオブジェクトのイベントを表示することもできます。

イベントには、時間、タイプ、オブジェクト、原因、説明が含まれます。イベントを通じて、デプロイメント、スケジュール、実行、停止など、アプリケーションのライフサイクル全体を理解できます。イベントを使用して、システム内で発生する例外を把握することもできます。各 Kubernetes コンポーネントのソース コードは、コンポーネントがトリガーする可能性のあるイベント タイプを定義します。たとえば、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 に保存され、デフォルトでは 1 時間のみ保存されます。 Etcd 自体はいくつかの複雑な分析操作をサポートしていないため、それらの操作は Etcd に受動的に保存することしかできず、他のシステムへのアクティブなプッシュはサポートされません。通常、手動でのみ表示できます。

実際には、Kubernetes イベントには次のような他の要件があります。

  • 異常事態が発生した場合にはアラートを発報したいと考えています。
  • より長いイベントの歴史的なイベントを照会したい。
  • クラスターイベントの柔軟な統計分析を実行したい。

このため、クエリやアラートに使用できるように、Kubernetes イベントを個別に収集する必要があります。

コミュニティには、イベントの収集とアラートのためのツールが多数あります。私がよく使う 2 つのツールは次のとおりです。

  • kube-eventer: Alibaba Cloud がリリースしたイベント収集ツール。
  • kube-event-exporter: Github 上の別のイベント収集作業。

実際の作業では、基本的に収集機能とアラーム機能を満たすことができるいずれかを選択できます。ここでは、アラーム用に kube-eventer を使用し、表示および分析のために ES にイベントを収集するために kube-event-exporter を使用して、上記の 2 つのプラグインを同時に使用します。

イベントアラートにはkube-eventerを使用する

kube-eventer のアラーム チャネルには、WeChat for Business、DingTalk、および webhook を使用できます。ニーズに合わせてお選びいただけます。各コンポーネントの具体的な使用方法は、プロジェクトのdocs/enディレクトリにあります。ここでは、Webhook を使用して WeChat for Enterprise にアラームを送信することを選択します。

(1)まず、企業のWeChatグループにWebhookロボットを作成し、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" ## .eg,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发生时间: {{ .LastTimestamp }}\n详细信息: {{ .Message }}"}} kind: ConfigMap metadata: name: custom-webhook-body namespace: monitoring

Webhook 構成では、level=Warning が追加されます。これは、警告イベントのみが通知されることを意味します。さらに、namespaces フィールドを使用して、アラートする必要がある名前空間を渡すことができ、kinds フィールドを使用して、アラートする必要があるオブジェクトをフィルター処理することができます。たとえば、Node の Warning イベントのみを送信する必要がある場合は、level=warning&kinds=Node と記述できます。たとえば、アラーム ストームをあまり生成せず、システム OOM イベントなどの特定の理由でのみアラームを送信する場合は、 reasnotallow=SystemOOM待機を追加できます。

kube-eventer Pod が起動すると、Enterprise WeChat は次のような条件を満たすイベントアラートを受信できます。

kube-event-exporter を使用してクラスター イベントを収集する

上記では、イベントアラームに kube-eventer を使用していますが、これは基本的に履歴イベントを保存しません。実際には、過去のイベントを照会し、それらに対して何らかのイベント分析を行う必要がある場合があります。 ES は、Kibana を介したコンテンツの収集と表示および分析によく使用されるため、ここでは kube-event-exporter を使用して Kubernetes イベントを ES に収集します。

kube-event-exporter は、イベントを ES に直接保存することも、イベントを Kafka に送信して、Logstash を介して Kafka のデータを使用して ES に保存することもできます。ここでは、環境の現在の状態に基づいて、イベントを 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

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 でテンプレートを作成します。 Kibanaの開発ツールで操作できます。声明は次のとおりです。

 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 で収集されたイベントを表示できます。

データが利用可能であれば、クエリと分析はシンプルで簡単になります。たとえば、今日のイベントの原因が「Unhealthy」である合計回数をカウントする最も簡単な方法は、次のように Kibana でチャートを作成することです。

上記は、Kubernetes でクラスター イベントを収集してアラートを送信する方法です。これは巨人の肩を直接使用しています。また、イベントアラームのスイッチの追加をサポートし、イベントアラームを任意にオン/オフにできるなど、企業内で再度開放して機能を充実させることもできます。

リンク

[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。

<<:  Alibaba Cloud クラウド監視リアルタイムデータを自社構築の Prometheus に接続

>>:  仕事の効率を2倍にする: Gitの実用的なコマンド集

推薦する

2012 年の Google SEO の 3 つのトレンドについて簡単に説明します

2011 年、Google の Panda アルゴリズムは数回のアップデートを経て、コンテンツの品質...

VMware とパートナーは、データとデジタル主権を包括的に強化するためにクラウド主権の新たな領域を計画しています。

デジタル経済の時代において、データは企業の中核資産となり、ビジネス革新を加速させることができます。ク...

Ce氏:SEOにおけるキーワードセグメンテーション技術についての簡単な説明

背景情報: Ce氏——Ceenの「世界名靴淘宝」プロモーションコンテストの特別審査員昇格コンテストの...

強力で顧客中心の内部ページコピーを書くにはどうすればよいでしょうか?

以前お話しした4Pと4Cを覚えていますか?それぞれの特徴は主に4Pが製品中心、4Cが顧客中心であるこ...

ウェブサイトの権限が低下した後のウェブサイトの運用方法

はじめに:私は2年以上にわたってメイクアップ写真ネットワークの宣伝を行ってきました。この仕事の経験の...

Kubernetes アンチパターンを回避するためのガイド

Kubernetes を使い始めたばかりでも、アプリケーションでの使用を検討している場合でも、Kub...

スピード: Linode - 8か月間50ドル/クレジットカード無料

Linode が再び 50 ドルをプレゼントします。アカウント残高を 55 ドルにするには、クレジッ...

ブランドは労働者の日にマーケティングの機会をどのように活用できるでしょうか?

企業にとってお祭りはいくらあっても足りません。運営スタッフは、お祭りがあるときはイベントを企画し、お...

フォーラムコミュニティを宣伝する方法: フォーラムコミュニティを宣伝する方法

インターネット上では、ほぼ毎日さまざまな種類のフォーラムが開設され、同様に、毎日さまざまな種類のフォ...

農産物および副産物のインターネットマーケティングに関する簡単な分析

食料は国民の第一のニーズであり、農産物や副産物の生産は国民の日常生活と密接に関係しています。中国は伝...

Goで開発された分散型ユニークID生成システム

[[433936]]今日は、分散環境で一意の ID を生成することを主な機能とするオープンソース プ...

IoTエコシステム: エッジコンピューティング

現代の IoT エコシステムのほとんどは、インターネットへの安全な接続に依存しています。デバイスはク...

Hudong Baikeを使用して高品質の外部リンクを作成する方法

周知のとおり、外部リンクの品質は SEO の全体的な効果に関係しています。高品質の外部リンクをどのよ...

Googleが利用規約を更新、プライバシー論争を巻き起こす

グーグルは4月14日に利用規約を更新し、Gmailで送受信されたメールがソフトウェアによって自動的に...

テンセントカンファレンスのユーザー数が1億人を突破、最大2,000人の同時参加をサポートするエンタープライズ版をリリース

発売から245日後、Tencent Meetingのユーザー数は1億人を突破し、最も早く1億ユーザー...