Slide 1

Slide 1 text

1 2021/06/22 Neco 池添 明宏 Feat. VictoriaMetrics サイボウズ開運研修2021 モニタリング⼊⾨

Slide 2

Slide 2 text

この講義のコンセプト ▶ 誰に n NecoのKubernetes環境を利⽤する開発・運⽤のメンバー ▶ 何を n モニタリングシステムの仕組みを知る n 可視化やアラートに必要なPromQLの基本を知る n アプリケーションからメトリクスを収集する⽅法を知る n ルールに基づいてアラートを発⾏する⽅法を知る 2

Slide 3

Slide 3 text

3 ビジネス ü ユーザーの利⽤状況を 分析しビジネス上の意 志決定に利⽤ 運⽤ ü 問題を検出しアラート を発⾏ ü オートスケーリング ü デプロイの⾃動化 開発 ü 性能測定 ü デバッグ ü ユーザーの利⽤状況に 応じた機能の改善 モニタリングの⽤途

Slide 4

Slide 4 text

4 - ⼊⾨監視より 監視とは役割ではなくスキルであり、チーム内の全員があ る程度のレベルに⾄っておくべきです。 ソフトウェアエンジニアはアプリケーションについて誰よ りも詳しいので、素晴らしいアプリケーション監視の仕組 みをデザインするには最⾼の場所にいるのです。 “

Slide 5

Slide 5 text

モニタリングシステムの仕組み 5

Slide 6

Slide 6 text

モニタリングの基本 ▶ 収集:アプリケーションやサーバからメトリクスを集める ▶ 蓄積:集めたメトリクスを保存する ▶ 分析:保存したメトリクスから必要な情報を取り出す ▶ 可視化:取りだした情報を表⽰する ▶ アラート:取りだした情報に基づいて通知する 6

Slide 7

Slide 7 text

Necoにおけるモニタリングシステム ▶ VictoriaMetricsによるモニタリングシステムを整備 n ⽇々のメンテナンスや運⽤はNecoチームが実施 n 開発チームのアプリケーションのメトリクスも、基本的なものは⾃動 で収集されている(30秒周期で収集) n 収集したメトリクスは400⽇間保存 ▶ カスタムリソース(YAML)を⽤意するだけで、利⽤者が簡単に 拡張して利⽤することができる。 7

Slide 8

Slide 8 text

8 ▶ ⾼速でコスト効率がよくスケーラブルな モニタリングシステムおよび時系列データベース ▶ Prometheusの完全互換を⽬指している n Prometheusに関する知識の多くはそのまま利⽤することが可能 n PromQL(時系列データを分析するためのクエリ⾔語) n Scrape Rule(メトリクスを収集するルール) n Alert Rule(アラートの発⾏を判断するルール) VictoriaMetricsとは

Slide 9

Slide 9 text

VictoriaMetrics Operatorとは ▶ VictoriaMetrics関連のコンポーネントのデプロイを⾃動化し てくれるソフトウェア ▶ カスタムリソース(YAMLファイル)を⽤意するだけで、メトリ クスの収集エージェントやアラートマネージャーなどをデプ ロイできる ▶ メトリクスの収集ルールや、アラートルールもカスタムリ ソースで記述することができる 9

Slide 10

Slide 10 text

モニタリングシステムの構成 10 Kubernetes Node Node Node モニタリング対象 node- exporter kube- state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集

Slide 11

Slide 11 text

11 GrafanaのUI ▶ Grafana: メトリクスの可視化ツール ▶ VMAgent: メトリクスの収集 ▶ VMStorage: メトリクスの蓄積 ▶ VMAlert: アラートの判断 ▶ AlertManager: アラートの送信 主要コンポーネント

Slide 12

Slide 12 text

基本メトリクス収集のコンポーネント ▶ cAdvisor n コンテナごとのCPUやメモリ、I/Oの使⽤量などのメトリクスを収集 n https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md ▶ kube-state-metrics n PodやDeployment, Serviceなどのリソースのメトリクスを収集 n https://github.com/kubernetes/kube-state-metrics/tree/master/docs ▶ Node exporter n ハードウェアやOSからメトリクスを収集 n https://github.com/prometheus/node_exporter 12

Slide 13

Slide 13 text

Necoの利⽤者ができること ▶ メトリクスの分析 n 基本的なメトリクスは収集済みなので、Grafanaにログインすれば すぐに分析を始められる ▶ アプリケーション独⾃のメトリクスを収集 n アプリの対応と、収集ルールの設定、カスタムリソースを⽤意 ▶ 独⾃のルールでアラートを発⾏ n アラートルールと通知先の設定、カスタムリソースを⽤意 13

Slide 14

Slide 14 text

デモ環境の構築 14

Slide 15

Slide 15 text

k8s-hands-on ▶ https://github.com/zoetrope/k8s-hands-on ▶ ローカル環境に、モニタリングシステムが利⽤可能な Kubernetesクラスタを⽴ち上げることができます。 ▶ README.mdの内容に従ってセットアップし、Grafanaの画⾯ が開くことを確認してください。 15

Slide 16

Slide 16 text

メトリクスを⾒てみよう ▶ 単純なテキスト形式 ▶ デモ環境で実際のフォーマットを⾒てみよう n ブラウザからアクセスできるようにPort Forward n make port-forward-todo n ブラウザで以下のURLを開く n http://localhost:9999/metrics 16

Slide 17

Slide 17 text

# HELP todo_api_requests_total A counter for requests to the wrapped handler. # TYPE todo_api_requests_total counter todo_api_requests_total{code="200",method="delete"} 1 todo_api_requests_total{code="200",method="get"} 4560 ・・・ # HELP todo_in_flight_requests A gauge of requests currently being served by the wrapped handler. # TYPE todo_in_flight_requests gauge todo_in_flight_requests 0 17 ラベル 値 メトリクス名 メトリクスのタイプ(後述) メトリクスの説明 メトリクスのフォーマット

Slide 18

Slide 18 text

18 Histogram 観測値の集計データ 例: HTTPリクエスト サイズや、リクエス トのレイテンシー Summary 観測値の集計結果 例: HTTPリクエスト サイズや、リクエス トのレイテンシー Gauge 現在の値を⽰す 例: ディスクの使⽤ 量、CPUの使⽤率 Counter 増加する値を⽰す 例: APIのリクエスト 数の累計、パケット の合計受信サイズ メトリクスのタイプ

Slide 19

Slide 19 text

メトリクスはどのように蓄積されるか 19 アプリケーション metrics_a{key=value1} 123 metrics_b{key=value2} 456 VMStorage VMAgent アプリケーションは現在の メトリクス値のみを出⼒ 30秒周期で収集 metrics_a{key=value1,pod=A,namespace=X,instance=10.69.0.3} 123 metrics_b{key=value2 ,pod=A,namespace=X,instance=10.69.0.3} 456 ラベルを付与 (どこから取得したメトリクスか分かるようにする) metrics_a{key=value1,pod=A,namespace=X,instance=10.69.0.3} → [(0,123), (30,124) (60,125)・・・] metrics_b{key=value2 ,pod=A,namespace=X,instance=10.69.0.3} → [(0,456), (30,512) (60,675)・・・] タイムスタンプを付与して時系列データとして保存 保存

Slide 20

Slide 20 text

20 メトリクス名が同じでもラベルの内容が異なる ものは別のキーとして保存される。 キーの種類が増えるとパフォーマンスに悪影響 があるので増やしすぎないように注意。 時系列データのキー 時系列データ メトリクス名 ラベル名 ラベルの値 タイムスタンプ (int64 in ms) 値 (float64) metrics_name{key="value",...} → [(t1, v1), (t2, v2), ...] 時系列データのモデル

Slide 21

Slide 21 text

PromQL 21

Slide 22

Slide 22 text

PromQLとは ▶ 時系列データを取得・集計するためのクエリ⾔語 ▶ PromQLの利⽤⽤途 n メトリクスを集計してパフォーマンスの分析 n 収集したメトリクスを可視化 n 特定の条件にマッチしたときにアラートを発⾏ 22

Slide 23

Slide 23 text

23 ② Prometheusを選択 ① Exploreを選択 ③ PromQLを⼊⼒ ④ クエリを実⾏ GrafanaでPromQLを実⾏してみよう

Slide 24

Slide 24 text

24 todoアプリのリクエスト数の累計 todo_api_requests_total Query

Slide 25

Slide 25 text

25 = 完全⼀致 != ⼀致しない =~ 正規表現で⼀致 !~ 正規表現で⼀致しない ラベルによる絞り込み:コードが500のリクエストのみを取得 todo_api_requests_total{code="500"} Query

Slide 26

Slide 26 text

instanceとjobラベル ▶ どのメトリクスにも必ず存在するラベル ▶ instance n メトリクスを収集したエンドポイントを⽰す n 例:アプリケーションが動いているサーバーのIPアドレス ▶ job n 同じ⽬的を持つインスタンスの集合を⽰す n 例:アプリケーションの名前 26

Slide 27

Slide 27 text

27 ▶ メトリクス名を同じ名前を値として持っているラベル。 ▶ メトリクス名で正規表現マッチさせたいときに便利。 {__name__=~"^todo_.*"} Query __name__ラベル

Slide 28

Slide 28 text

関数 ▶ 便利な関数が数多く⽤意されている n https://prometheus.io/docs/prometheus/latest/querying/functions ▶ 引数のタイプに注意 n instant-vector or range-vector n 利⽤可能なメトリクスタイプが限定されている関数がある 28

Slide 29

Slide 29 text

よく使う関数 関数名 メトリクスタイプ 説明 absent(v instant-vector) 何でも メトリクスが存在する場合は空ベクトルを返 し、存在しない場合は値が1で⻑さ1のベクト ルを返す changes(v range-vector) 何でも 指定した範囲内で値が変化した回数 delta(v range-vector) gauge 指定した範囲内の最初と最後の差 increase(v range-vector) counter 指定した範囲内での増加量 rate(v range-vector) counter 指定した範囲内での秒間あたりの平均増加率 histogram_quantile (Φ scalar, b instant-vector) histogram 指定したバケットから分位数(0 ≤ φ ≤ 1)を 算出する(※後ほど詳しく解説します) 29

Slide 30

Slide 30 text

30 Grafanaで確認する場合は、Query type に Instant を指定します 指定した期間の値を取得 todo_api_requests_total[5m] range-vector 最新の値のみを取得 todo_api_requests_total instant-vector

Slide 31

Slide 31 text

absent() ▶ 引数に指定したメトリクスが存在する場合は空ベクトルを返 し、存在しない場合は値が1で⻑さ1のベクトルを返す。 ▶ メトリクスの取得に失敗したことを検知するのに便利。 31

Slide 32

Slide 32 text

32 ▶ upメトリクス n 1: 起動している 0: 起動していない n なし: 何らかの理由でメトリクスが収集できなかった up{job="todo/todo"} Query

Slide 33

Slide 33 text

33 ▶ absent関数を利⽤すると、指定した条件に⼀致する メトリクスが存在しないことを検出できる absent(up{job="todo/todo"}==1) Query

Slide 34

Slide 34 text

rate() ▶ 指定したレンジの1秒あたりの平均増加量を計算する ▶ Counterタイプのメトリクスのみに利⽤可能 ▶ Counterタイプのメトリクスの値は、常に増加するものなので、 そのままでは意味のある値にはならない。変化量を⾒る必要 がある。 34

Slide 35

Slide 35 text

35 1分間で約60増加 リクエスト数の累計 apiserver_request_total Query

Slide 36

Slide 36 text

36 ピークは秒間 約1リクエスト 秒間あたりのリクエスト数 rate(apiserver_request_total) Query

Slide 37

Slide 37 text

秒間あたりのリクエスト数の5分ごとの移動平均値 37 rate(apiserver_request_total[5m]) Query ピークの値が⼩さくなり タイミングも遅くなった

Slide 38

Slide 38 text

38 - ⼊⾨監視より システムのメトリクスは急激に変化しやすいので、そのまま のデータポイントを使ってアラートを送ると、誤った警報を 送ってしまいやすくなります。 この問題を回避するため、移動平均を使ってデータをならし ます(例えば5分間のデータ平均)。しかしこれによって情報 の粒度が落ち、重要なイベントを⾒逃すことに繋がります。 バランスをとって適切な度合いの平滑化を⾏う必要がありま す。 “

Slide 39

Slide 39 text

SummaryとHistogram ▶ 分位数(パーセンタイル)を扱うためのメトリクスタイプ ▶ Summaryは分位数そのものをメトリクスとして出⼒ ▶ Histogramは後から分位数を計算できるように、以下の3種類 の値をメトリクスとして出⼒ n xxx_count データの全数 n xxx_sum 全データの値の合計 n xxx_bucket{le=“n”} n以下の値のデータの数 39

Slide 40

Slide 40 text

Histogramのメトリクス例 ※le: less than or equalの略 40 todo_request_duration_seconds_bucket{handler="test",method="get",le="0.25"} 534 todo_request_duration_seconds_bucket{handler="test",method="get",le="0.5"} 1126 todo_request_duration_seconds_bucket{handler="test",method="get",le="1"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="2.5"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="5"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="10"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="+Inf"} 2231 todo_request_duration_seconds_sum{handler="test",method="get"} 1124.3332884999982 todo_request_duration_seconds_count{handler="test",method="get"} 2231 レイテンシ0.25秒以内のリクエストが534回

Slide 41

Slide 41 text

histogram_quantile() ▶ 分位数(パーセンタイル)を計算するための関数 ▶ Histogramタイプのメトリクスにのみ利⽤可能 41

Slide 42

Slide 42 text

42 リクエストの90%は1.0秒以内に完了 リクエストの90%は0.25秒以内に完了 histogram_quantile( 0.9, rate(todo_request_duration_seconds_bucket[5m]) ) Query

Slide 43

Slide 43 text

43 - ⼊⾨監視より レイテンシのレポートにパーセンタイルを使うことで、外れ 値を無視して⼤部分のユーザに対するサービス品質がどう だったのかについての有益な情報が得られます。 ただし、ある程度のデータポイントを捨てていることを忘れ ないでください。ユーザに対する最悪のシナリオについても 確認しましょう。 “

Slide 44

Slide 44 text

集計 ▶ sum, min, max, avg, count など集計をおこなう演算⼦ n https://prometheus.io/docs/prometheus/latest/querying/operators /#aggregation-operators ▶ byとwithoutで集計する対象のラベルを指定することができる 44

Slide 45

Slide 45 text

45 ▶ byで指定したラベル、もしくはwithoutで指定しなかった ラベルで集計することができる todo_api_requests_total{code=200, method=get} 100 todo_api_requests_total{code=200, method=post} 200 todo_api_requests_total{code=500, method=get} 300 todo_api_requests_total{code=500, method=post} 400 ↓ sum(todo_api_requests_total) by (code) todo_api_requests_total{code=200} 300 todo_api_requests_total{code=500} 700 by/without

Slide 46

Slide 46 text

46 ステータスコードが同じデータを合算 sum(rate(todo_api_requests_total[5m])) by(code) Query

Slide 47

Slide 47 text

47 node_filesystem_avail_bytes node_filesystem_size_bytes {device="shm",fstype="tmpfs",instance="10.244.1.3"} {device="shm",fstype="tmpfs",instance="10.244.1.3"} {device="sdb",fstype="ext4",instance="10.244.1.3"} {device="sdb",fstype="ext4",instance="10.244.1.3"} {device="shm",fstype="tmpfs",instance="10.244.1.4"} {device="shm",fstype="tmpfs",instance="10.244.1.4"} {device="sdb",fstype="ext4",instance="10.244.1.4"} {device="sdb",fstype="ext4",instance="10.244.1.4"} 演算 ▶ 左右でラベルがすべて⼀致するメトリクス同⼠をみつけて、 それぞれの値を演算する。 node_filesystem_avail_bytes / node_filesystem_size_bytes Query ベクトルマッチング

Slide 48

Slide 48 text

48 sum(rate(node_cpu_seconds_total sum(rate(node_cpu_seconds_total[5m])) {mode="idle"}[5m])) without(cpu) without(mode, cpu) {mode="idle",instance="10.244.1.3"} {instance="10.244.1.3"} {mode="idle",instance="10.244.1.4"} {instance="10.244.1.4"} {mode="idle",instance="10.244.1.5"} {instance="10.244.1.5"} modeラベルがない! ▶ 左右ですべてのラベルが⼀致するメトリクスがみつからない 場合、演算できない。 sum(rate(node_cpu_seconds_total{mode="idle"}[5m])) without(cpu) / sum(rate(node_cpu_seconds_total[5m])) without(mode, cpu) Query

Slide 49

Slide 49 text

49 sum(rate(node_cpu_seconds_total sum(rate(node_cpu_seconds_total[5m])) {mode="idle"}[5m])) without(cpu) without(mode, cpu) {mode="idle",instance="10.244.1.3"} {instance="10.244.1.3"} {mode="idle",instance="10.244.1.4"} {instance="10.244.1.4"} {mode="idle",instance="10.244.1.5"} {instance="10.244.1.5"} modeを無視してマッチ ▶ ラベルが⼀致していないメトリクス同⼠を演算する場合 n on でマッチさせるラベルを指定 n ignoring でマッチさせないラベルを指定 sum(rate(node_cpu_seconds_total{mode="idle"}[5m])) without(cpu) / ignoring(mode) sum(rate(node_cpu_seconds_total[5m])) without(mode, cpu) Query

Slide 50

Slide 50 text

50 kube_pod_container_status_restarts_total kube_namespace_labels {namespace="monitoring-system",pod="vmagent"} {namespace="monitoring-system",pod="vmsingle"} {namespace="monitoring-system",pod="operator"} {namespace="monitoring-system",label_team="admin"} {namespace="grafana", pod="grafana"} {namespace="grafana", pod="grafana-operator"} {namespace="grafana", label_team="admin"} {namespace="todo",pod="todo"} {namespace="todo",pod="request"} {namespace="todo",pod="vmagent"} {namespace="todo", label_team="user"} ▶ メトリクスが多対⼀や⼀対多の関係となる場合は、onや ignoringを指定しても演算できない。 rate(kube_pod_container_status_restarts_total[5m]) * on (namespace) kube_namespace_labels{label_team="admin"} Query

Slide 51

Slide 51 text

多対⼀、⼀対多の演算 ▶ 多対⼀の場合はgroup_left、⼀対多の場合はgroup_rightを利 ⽤することで、SQLのJOINのようなことができる。 ▶ namespaceに付与されたチームラベルを利⽤して、チーム ごとのメトリクス集計をしたい場合などに便利。 51

Slide 52

Slide 52 text

52 kube_namespace_labelsの値は必ず1なので、 かけ算をしても結果は変化しない。 {namespace="monitoring-system",pod="vmagent"} {namespace="monitoring-system",label_team="admin"} {namespace="monitoring-system",pod="vmsingle"} {namespace="monitoring-system",pod="operator"} {namespace="grafana", pod="grafana"} {namespace="grafana", label_team="admin"} {namespace="grafana", pod="grafana-operator"} 演算 ▶ onで指定したラベルが⼀致する組み合わせで、それぞれ演算 がおこなわれる。 rate(kube_pod_container_status_restarts_total[5m]) * on (namespace) group_left kube_namespace_labels{label_team="admin"} Query

Slide 53

Slide 53 text

PromQLの例 53

Slide 54

Slide 54 text

54 node_memory_Active_bytes / on (instance) node_memory_MemTotal_bytes Query ノードごとのメモリ使⽤率 1 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) Query ノードごとのCPU使⽤率

Slide 55

Slide 55 text

55 expr: argocd_app_info{sync_status!="Synced"} == 1 for: 15m Alert ArgoCDによるアプリケーションの同期に失敗している expr: (certmanager_certificate_expiration_timestamp_seconds - time()) <= 14*24*60*60 for: 120m Alert cert-managerが発⾏した証明書の有効期限が14⽇以内に切れる expr: increase(kube_pod_container_status_restarts_total[5m]) > 0 for: 15m Alert 15分の間にPodが何度も再起動を繰り返す

Slide 56

Slide 56 text

独⾃メトリクスを収集しよう 56

Slide 57

Slide 57 text

独⾃メトリクスの収集 ▶ アプリケーション独⾃のメトリクスを収集し、分析したりア ラート送信をおこないたい。 n 例:APIごとの利⽤状況を分析したい n 例:顧客ごとの機能の利⽤頻度を知りたい 57

Slide 58

Slide 58 text

モニタリングシステムの構成 58 Kubernetes Node Node Node モニタリング対象 node- exporter kube- state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集

Slide 59

Slide 59 text

独⾃メトリクスの収集⽅法 ▶ アプリケーションにメトリクスAPIを実装する ▶ 収集ルールを記述する ▶ リラベル処理を記述する ▶ VMAgentをデプロイする 59

Slide 60

Slide 60 text

60 App PushGateway VMAgent 処理の完了時にメトリクスを送信する バッチなど時間がかかる処理の メトリクスを収集したい場合 メトリクスをPush App exporter VMAgent メトリクス収集⽤の別プログラム (exporter)を⽤意する アプリに⼿を加えられない場合など 基本はこれ App VMAgent アプリにメトリクスのAPIを実装する メトリクスの収集⽅式

Slide 61

Slide 61 text

アプリにメトリクスのAPIを実装 ▶ クライアントライブラリ n https://prometheus.io/docs/instrumenting/clientlibs/ n Go, Java, Python, Rubyなど様々な⾔語向けに提供されている ▶ Go⾔語での実装例 n https://github.com/zoetrope/k8s-hands- on/blob/main/todo/server/metrics.go 61

Slide 62

Slide 62 text

メトリクスの収集ルール ▶ Prometheusでは scrape_config にルールを記述 n https://prometheus.io/docs/prometheus/latest/configuration/confi guration/#scrape_config ▶ VictoriaMetrics Operatorではカスタムリソース (VMPodScrapeやVMServiceScrape)でルールを記述 n https://github.com/VictoriaMetrics/operator/blob/master/docs/api .MD 62

Slide 63

Slide 63 text

63 role: serviceはブラックボックスモニタリング向き。 ほとんど使うことはない。 VictoriaMetrics Operator Prometheus Serviceを対象にしたメトリクス収集 VMServiceScrape kubernetes_sd_configs role: service role: endpoints (default) role: endpointslices Podを対象にしたメトリクス収集 VMPodScrape kubernetes_sd_configs role: pod VictoriaMetrics Operatorと Prometheusの収集ルールの対応

Slide 64

Slide 64 text

サービスディスカバリ ▶ Kubernetesリソースからメトリクスの収集対象を⾃動で探す ▶ VMServiceScrape (role: endpoints) n 指定したサービスにぶら下がる全Podの全コンテナポートがメトリク ス収集の対象となる ▶ VMPodScrape (role: pod) n 指定したPodの全コンテナポートがメトリクス収集の対象となる 64

Slide 65

Slide 65 text

65 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo spec: namespaceSelector: matchNames: [todo] selector: matchLabels: app.kubernetes.io/name: todo podMetricsEndpoints: - port: http scheme: http path: /metrics このラベルに⼀致するPodが メトリクス収集の対象となる 対象のPodの http という名前のポートから /metrics というパスでメトリクスを収集する ▶ Podからメトリクスを収集 するためのルールを記述 するカスタムリソース VMPodScrape

Slide 66

Slide 66 text

66 リラベル処理により、ラベルを整理 してからデータを保存する。 メタラベルは保存されない。 metrics_a{ key=value1,namespace=default,pod=todo } 123 メトリクス収集時に様々なメタラベ ルが付与される https://prometheus.io/docs/prom etheus/latest/configuration/config uration/#pod metrics_a{ key=value1, __meta_kubernetes_namespace=default, __meta_kubernetes_pod_name=todo, __meta_Kubernetes_pod_label_app=todo } 123 アプリケーションが出⼒する メトリクス metrics_a{key=value1} 123 メタラベルとリラベル

Slide 67

Slide 67 text

リラベル ▶ メトリクスを時系列データとして保存する前に、ラベルの情 報を整理したり、フィルタリングをおこなうための機能。 ▶ 5種類のアクションが⽤意されている n replace: マッチするラベルを置き換えたり名前を変更する n keep, drop: 収集するメトリクスの取捨選択をおこなう n labelkeep, labeldrop: 保存するラベルの取捨選択をおこなう 67

Slide 68

Slide 68 text

68 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: replace sourceLabels: [__meta_kubernetes_namespace] targetLabel: Kubernetes_namespace sourceLabelsに指定したラベル名を targetLabelで指定した名前に置き換える ▶ 指定したラベルの名前 や値を変更できる。 ▶ ユースケース n メタラベルを残す n ヒューマンリーダブルな 名前に変更する n 分析しやすいように値を 加⼯する Replace

Slide 69

Slide 69 text

⾃動Replace設定 ▶ VictoriaMetrics Operatorはいくつかのreplaceアクションを ⾃動で設定している。 n __meta_kubernetes_namespace → namespace n __meta_kubernetes_service_name → service n __meta_kubernetes_pod_name → pod 69

Slide 70

Slide 70 text

70 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: keep sourceLabels: [__meta_Kubernetes_pod_name] regex: todo-.* この条件に⼀致するメトリクスのみ を保存対象とする ▶ keep: 条件にマッチした メトリクスのみを保存 する。他のメトリクス は捨てる。 ▶ drop: 条件にマッチした メトリクスは捨てる。 他のメトリクスは保存 する。 Keep/Drop

Slide 71

Slide 71 text

71 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: drop sourceLabels: [__name__,__address__] regex: 'up;.*:8080' __name__ が up に⼀致し、 __address__ が .*:8080 に⼀致したら捨てる ▶ 複数ラベルの条件を指定 するには、sourceLabels をカンマ区切り、regex をセミコロン区切りで書 く。 複数ラベルの指定

Slide 72

Slide 72 text

VMAgentのデプロイ ▶ 収集ルールに従ってメトリクスを収集するプログラムをデプ ロイする必要がある ▶ VMAgentというカスタムリソースを記述するだけで、 VictoriaMetrics Operatorがデプロイしてくれる。 72

Slide 73

Slide 73 text

73 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAgent metadata: name: vmagent namespace: todo spec: replicaCount: 1 remoteWrite: - url: "http://vmsingle-database.monitoring- system.svc:8429/api/v1/write" podScrapeNamespaceSelector: matchLabels: kubernetes.io/metadata.name: todo scrapeInterval: 30s このラベルに⼀致するnamespace のVMPodScrapeを収集ルール として利⽤する 収集したメトリクスを保存する ストレージのURL 収集周期 Neco環境では30秒より短くできない ▶ メトリクスを収集する VMAgentをデプロイする ためのカスタムリソース VMAgent

Slide 74

Slide 74 text

収集ルールのデバッグ(1) ▶ VMAgentのログを確認 n kubectl logs -n todo deploy/vmagent-todo-agent -c vmagent ▶ ⽣成されたscrape_configの確認 n kubectl -n todo exec deploy/vmagent-todo-agent -c vmagent -- cat /etc/vmagent/config_out/vmagent.env.yaml 74

Slide 75

Slide 75 text

収集ルールのデバッグ(2) ▶ VMAgentのAPIをポートフォワード n kubectl port-forward -n todo deploy/vmagent-todo-agent 8429:8429 ▶ アクティブなターゲットの⼀覧 n curl localhost:8429/api/v1/targets | jq '.data.activeTargets[].labels.job' ▶ 取得しなかったターゲットの⼀覧 n curl localhost:8429/api/v1/targets | jq '.data.droppedTargets[].discoveredLabels.job' ▶ 特定ターゲットのメタラベルなどを確認 n curl localhost:8429/api/v1/targets | jq '.data.activeTargets[] | select(.labels.job=="todo/todo")' 75

Slide 76

Slide 76 text

アラートを通知してみよう 76

Slide 77

Slide 77 text

アラートの通知 ▶ アプリケーションの運⽤時に問題をすばやく検知したい。 n 例:アプリケーションがクラッシュして⽴ち上がらない n 例:証明書の有効期限が切れた n 例:ディスクの空き容量がなくなった ▶ Kubernetesではセルフヒールにより⾃動で問題が解決するこ とも多い。異常を検知したら即座にアラートをあげるのでは なく、しばらく異常が続いた場合にアラートをあげよう。 77

Slide 78

Slide 78 text

78 - ⼊⾨Prometheusより “ 理想とすべき⽬標は、オンコール担当者に対するすべての 呼び出し、チケットとして登録されたすべてのアラートが、 ⼈間による知的な対処を必要とするものになることである。 ⼈間の知性がなくても解決できるアラートなら、真っ先に ⾃動化の候補にすべきだ。

Slide 79

Slide 79 text

モニタリングシステムの構成 79 Kubernetes Node Node Node モニタリング対象 node- exporter kube- state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集

Slide 80

Slide 80 text

アラートの通知⽅法 ▶ アラートのルールを書く ▶ アラートの送信設定を書く ▶ VMAlertとAlertManagerをデプロイする 80

Slide 81

Slide 81 text

81 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMRule metadata: name: vmrule namespace: todo spec: groups: - name: todo rules: - alert: TodoErrorsHigh expr: | sum(rate(todo_api_requests_total{code="500"}[5m])) / sum(rate(todo_api_requests_total[5m])) > 0.3 for: 60s labels: severity: error annotations: summary: "Todo is returning errors for {{ $value }}% of requests" exprの結果を {{ $value }} で埋め込むことが可能 exprのクエリの条件に forの期間⼀致した場合に アラートを送信する ▶ アラートルールを記述する ためのカスタムリソース ▶ labelsやannotationsで送信 するアラートのレベルや メッセージを設定する VMRule

Slide 82

Slide 82 text

82 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAlert metadata: name: vmalert namespace: todo spec: replicaCount: 1 datasource: url: "http://vmsingle-database.monitoring- system.svc:8429" notifier: url: "http://vmalertmanager-alertmanager.todo.svc:9093" evaluationInterval: "30s" ruleNamespaceSelector: matchLabels: kubernetes.io/metadata.name: todo この条件にマッチするnamespace内にある VMRuleをアラートルールとして利⽤する メトリクスの取得元と アラートの送信先を設定 ▶ アラート送信を判断する VMAlertをデプロイする ためのカスタムリソース VMAlert

Slide 83

Slide 83 text

83 apiVersion: v1 kind: Secret metadata: name: alertmanager-setting namespace: todo type: Opaque stringData: alertmanager.yaml: | route: receiver: slack receivers: - name: 'slack' slack_configs: - api_url: 'https://hooks.slack.com/services/xxxxx' channel: ‘#xxxxx' text: "{{ .CommonAnnotations.summary }}" send_resolved: true VMRuleで指定したlabelsやannotationsを メッセージに埋め込むことができる すべてのアラートを Slackに送信する設定 ▶ アラートの送信先を設定 ▶ メール、Slack, PagerDuty, OpsGenieなどが利⽤可能 ▶ 重要度(severity)に応じた 通知先の振り分けも可能 AlertManager設定

Slide 84

Slide 84 text

84 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAlertmanager metadata: name: alertmanager namespace: todo spec: replicaCount: 1 configSecret: alertmanager-setting 設定ファイルのSecretリソースを指定 ▶ AlertManagerをデプロイす るためのカスタムリソース VMAlertManager

Slide 85

Slide 85 text

アラートのデバッグ(1) ▶ VMAlertの設定のチェック n kubectl exec -n todo deploy/vmalert-vmalert -c vmalert -- sh -c 'cat /etc/vmalert/config/vm-*/*.yaml' 85

Slide 86

Slide 86 text

86 state: pending アラートの条件に⼀致するが 指定した時間が経過していない state: firing アラートが送信された ▶ VMAlertのAPIをポートフォワード n kubectl –n todo port-forward deploy/vmalert-vmalert 8888:8080 ▶ VMAlertが読み込んだルールを確認 n curl localhost:8888/api/v1/groups | jq . ▶ VMAlertが検出したアラートを確認 n curl localhost:8888/api/v1/alerts | jq . アラートのデバッグ(2)

Slide 87

Slide 87 text

87 ▶ AlertManagerをポートフォワード n kubectl –n todo port-forward sts/vmalertmanager-alertmanager 9093:9093 ▶ ブラウザでlocalhost:9093 の画⾯を確認 アラートのデバッグ(3)

Slide 88

Slide 88 text

まとめ 88

Slide 89

Slide 89 text

まとめ ▶ PromQLの使い⽅、メトリクスの収集⽅法、アラートの通知⽅ 法について学んだ。 ▶ モニタリングは最初から最適な設定を決められるものではな く、⽇々の運⽤の中で必要なメトリクスや適切なアラート ルールが徐々に⾒えてくるもの。 ▶ アプリケーション開発と同じようにモニタリングも⽇々育て ていきましょう。 89

Slide 90

Slide 90 text

参考⽂献 ▶ ⼊⾨ 監視 n モダンなモニタリングのためのデザインパターン ▶ ⼊⾨ Prometheus n インフラとアプリケーションのパフォーマンスモニタリ ング 90