Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モニタリング入門 / Monitoring Feat. VictoriaMetrics

A97eee01397705443a72a48ce29d3e19?s=47 Cybozu
June 22, 2021

モニタリング入門 / Monitoring Feat. VictoriaMetrics

A97eee01397705443a72a48ce29d3e19?s=128

Cybozu

June 22, 2021
Tweet

Transcript

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

  2. この講義のコンセプト ▶ 誰に n NecoのKubernetes環境を利⽤する開発・運⽤のメンバー ▶ 何を n モニタリングシステムの仕組みを知る n

    可視化やアラートに必要なPromQLの基本を知る n アプリケーションからメトリクスを収集する⽅法を知る n ルールに基づいてアラートを発⾏する⽅法を知る 2
  3. 3 ビジネス ü ユーザーの利⽤状況を 分析しビジネス上の意 志決定に利⽤ 運⽤ ü 問題を検出しアラート を発⾏

    ü オートスケーリング ü デプロイの⾃動化 開発 ü 性能測定 ü デバッグ ü ユーザーの利⽤状況に 応じた機能の改善 モニタリングの⽤途
  4. 4 - ⼊⾨監視より 監視とは役割ではなくスキルであり、チーム内の全員があ る程度のレベルに⾄っておくべきです。 ソフトウェアエンジニアはアプリケーションについて誰よ りも詳しいので、素晴らしいアプリケーション監視の仕組 みをデザインするには最⾼の場所にいるのです。 “

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

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

    アラート:取りだした情報に基づいて通知する 6
  7. Necoにおけるモニタリングシステム ▶ VictoriaMetricsによるモニタリングシステムを整備 n ⽇々のメンテナンスや運⽤はNecoチームが実施 n 開発チームのアプリケーションのメトリクスも、基本的なものは⾃動 で収集されている(30秒周期で収集) n 収集したメトリクスは400⽇間保存

    ▶ カスタムリソース(YAML)を⽤意するだけで、利⽤者が簡単に 拡張して利⽤することができる。 7
  8. 8 ▶ ⾼速でコスト効率がよくスケーラブルな モニタリングシステムおよび時系列データベース ▶ Prometheusの完全互換を⽬指している n Prometheusに関する知識の多くはそのまま利⽤することが可能 n PromQL(時系列データを分析するためのクエリ⾔語)

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

    メトリクスの収集ルールや、アラートルールもカスタムリ ソースで記述することができる 9
  10. モニタリングシステムの構成 10 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  11. 11 GrafanaのUI ▶ Grafana: メトリクスの可視化ツール ▶ VMAgent: メトリクスの収集 ▶ VMStorage:

    メトリクスの蓄積 ▶ VMAlert: アラートの判断 ▶ AlertManager: アラートの送信 主要コンポーネント
  12. 基本メトリクス収集のコンポーネント ▶ 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
  13. Necoの利⽤者ができること ▶ メトリクスの分析 n 基本的なメトリクスは収集済みなので、Grafanaにログインすれば すぐに分析を始められる ▶ アプリケーション独⾃のメトリクスを収集 n アプリの対応と、収集ルールの設定、カスタムリソースを⽤意

    ▶ 独⾃のルールでアラートを発⾏ n アラートルールと通知先の設定、カスタムリソースを⽤意 13
  14. デモ環境の構築 14

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

  16. メトリクスを⾒てみよう ▶ 単純なテキスト形式 ▶ デモ環境で実際のフォーマットを⾒てみよう n ブラウザからアクセスできるようにPort Forward n make

    port-forward-todo n ブラウザで以下のURLを開く n http://localhost:9999/metrics 16
  17. # 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 ラベル 値 メトリクス名 メトリクスのタイプ(後述) メトリクスの説明 メトリクスのフォーマット
  18. 18 Histogram 観測値の集計データ 例: HTTPリクエスト サイズや、リクエス トのレイテンシー Summary 観測値の集計結果 例:

    HTTPリクエスト サイズや、リクエス トのレイテンシー Gauge 現在の値を⽰す 例: ディスクの使⽤ 量、CPUの使⽤率 Counter 増加する値を⽰す 例: APIのリクエスト 数の累計、パケット の合計受信サイズ メトリクスのタイプ
  19. メトリクスはどのように蓄積されるか 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)・・・] タイムスタンプを付与して時系列データとして保存 保存
  20. 20 メトリクス名が同じでもラベルの内容が異なる ものは別のキーとして保存される。 キーの種類が増えるとパフォーマンスに悪影響 があるので増やしすぎないように注意。 時系列データのキー 時系列データ メトリクス名 ラベル名 ラベルの値

    タイムスタンプ (int64 in ms) 値 (float64) metrics_name{key="value",...} → [(t1, v1), (t2, v2), ...] 時系列データのモデル
  21. PromQL 21

  22. PromQLとは ▶ 時系列データを取得・集計するためのクエリ⾔語 ▶ PromQLの利⽤⽤途 n メトリクスを集計してパフォーマンスの分析 n 収集したメトリクスを可視化 n

    特定の条件にマッチしたときにアラートを発⾏ 22
  23. 23 ② Prometheusを選択 ① Exploreを選択 ③ PromQLを⼊⼒ ④ クエリを実⾏ GrafanaでPromQLを実⾏してみよう

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

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

    todo_api_requests_total{code="500"} Query
  26. instanceとjobラベル ▶ どのメトリクスにも必ず存在するラベル ▶ instance n メトリクスを収集したエンドポイントを⽰す n 例:アプリケーションが動いているサーバーのIPアドレス ▶

    job n 同じ⽬的を持つインスタンスの集合を⽰す n 例:アプリケーションの名前 26
  27. 27 ▶ メトリクス名を同じ名前を値として持っているラベル。 ▶ メトリクス名で正規表現マッチさせたいときに便利。 {__name__=~"^todo_.*"} Query __name__ラベル

  28. 関数 ▶ 便利な関数が数多く⽤意されている n https://prometheus.io/docs/prometheus/latest/querying/functions ▶ 引数のタイプに注意 n instant-vector or

    range-vector n 利⽤可能なメトリクスタイプが限定されている関数がある 28
  29. よく使う関数 関数名 メトリクスタイプ 説明 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
  30. 30 Grafanaで確認する場合は、Query type に Instant を指定します 指定した期間の値を取得 todo_api_requests_total[5m] range-vector 最新の値のみを取得

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

  32. 32 ▶ upメトリクス n 1: 起動している 0: 起動していない n なし:

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

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

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

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

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

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

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

    データの全数 n xxx_sum 全データの値の合計 n xxx_bucket{le=“n”} n以下の値のデータの数 39
  40. 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回
  41. histogram_quantile() ▶ 分位数(パーセンタイル)を計算するための関数 ▶ Histogramタイプのメトリクスにのみ利⽤可能 41

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

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

  44. 集計 ▶ sum, min, max, avg, count など集計をおこなう演算⼦ n https://prometheus.io/docs/prometheus/latest/querying/operators

    /#aggregation-operators ▶ byとwithoutで集計する対象のラベルを指定することができる 44
  45. 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
  46. 46 ステータスコードが同じデータを合算 sum(rate(todo_api_requests_total[5m])) by(code) Query

  47. 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 ベクトルマッチング
  48. 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
  49. 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
  50. 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
  51. 多対⼀、⼀対多の演算 ▶ 多対⼀の場合はgroup_left、⼀対多の場合はgroup_rightを利 ⽤することで、SQLのJOINのようなことができる。 ▶ namespaceに付与されたチームラベルを利⽤して、チーム ごとのメトリクス集計をしたい場合などに便利。 51

  52. 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
  53. PromQLの例 53

  54. 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使⽤率
  55. 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が何度も再起動を繰り返す
  56. 独⾃メトリクスを収集しよう 56

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

  58. モニタリングシステムの構成 58 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  59. 独⾃メトリクスの収集⽅法 ▶ アプリケーションにメトリクスAPIを実装する ▶ 収集ルールを記述する ▶ リラベル処理を記述する ▶ VMAgentをデプロイする 59

  60. 60 App PushGateway VMAgent 処理の完了時にメトリクスを送信する バッチなど時間がかかる処理の メトリクスを収集したい場合 メトリクスをPush App exporter

    VMAgent メトリクス収集⽤の別プログラム (exporter)を⽤意する アプリに⼿を加えられない場合など 基本はこれ App VMAgent アプリにメトリクスのAPIを実装する メトリクスの収集⽅式
  61. アプリにメトリクスの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
  62. メトリクスの収集ルール ▶ 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
  63. 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の収集ルールの対応
  64. サービスディスカバリ ▶ Kubernetesリソースからメトリクスの収集対象を⾃動で探す ▶ VMServiceScrape (role: endpoints) n 指定したサービスにぶら下がる全Podの全コンテナポートがメトリク ス収集の対象となる

    ▶ VMPodScrape (role: pod) n 指定したPodの全コンテナポートがメトリクス収集の対象となる 64
  65. 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
  66. 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 メタラベルとリラベル
  67. リラベル ▶ メトリクスを時系列データとして保存する前に、ラベルの情 報を整理したり、フィルタリングをおこなうための機能。 ▶ 5種類のアクションが⽤意されている n replace: マッチするラベルを置き換えたり名前を変更する n

    keep, drop: 収集するメトリクスの取捨選択をおこなう n labelkeep, labeldrop: 保存するラベルの取捨選択をおこなう 67
  68. 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
  69. ⾃動Replace設定 ▶ VictoriaMetrics Operatorはいくつかのreplaceアクションを ⾃動で設定している。 n __meta_kubernetes_namespace → namespace n

    __meta_kubernetes_service_name → service n __meta_kubernetes_pod_name → pod 69
  70. 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
  71. 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 をセミコロン区切りで書 く。 複数ラベルの指定
  72. VMAgentのデプロイ ▶ 収集ルールに従ってメトリクスを収集するプログラムをデプ ロイする必要がある ▶ VMAgentというカスタムリソースを記述するだけで、 VictoriaMetrics Operatorがデプロイしてくれる。 72

  73. 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
  74. 収集ルールのデバッグ(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
  75. 収集ルールのデバッグ(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
  76. アラートを通知してみよう 76

  77. アラートの通知 ▶ アプリケーションの運⽤時に問題をすばやく検知したい。 n 例:アプリケーションがクラッシュして⽴ち上がらない n 例:証明書の有効期限が切れた n 例:ディスクの空き容量がなくなった ▶

    Kubernetesではセルフヒールにより⾃動で問題が解決するこ とも多い。異常を検知したら即座にアラートをあげるのでは なく、しばらく異常が続いた場合にアラートをあげよう。 77
  78. 78 - ⼊⾨Prometheusより “ 理想とすべき⽬標は、オンコール担当者に対するすべての 呼び出し、チケットとして登録されたすべてのアラートが、 ⼈間による知的な対処を必要とするものになることである。 ⼈間の知性がなくても解決できるアラートなら、真っ先に ⾃動化の候補にすべきだ。

  79. モニタリングシステムの構成 79 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  80. アラートの通知⽅法 ▶ アラートのルールを書く ▶ アラートの送信設定を書く ▶ VMAlertとAlertManagerをデプロイする 80

  81. 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
  82. 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
  83. 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設定
  84. 84 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAlertmanager metadata: name: alertmanager namespace: todo

    spec: replicaCount: 1 configSecret: alertmanager-setting 設定ファイルのSecretリソースを指定 ▶ AlertManagerをデプロイす るためのカスタムリソース VMAlertManager
  85. アラートのデバッグ(1) ▶ VMAlertの設定のチェック n kubectl exec -n todo deploy/vmalert-vmalert -c

    vmalert -- sh -c 'cat /etc/vmalert/config/vm-*/*.yaml' 85
  86. 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)
  87. 87 ▶ AlertManagerをポートフォワード n kubectl –n todo port-forward sts/vmalertmanager-alertmanager 9093:9093

    ▶ ブラウザでlocalhost:9093 の画⾯を確認 アラートのデバッグ(3)
  88. まとめ 88

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

    ていきましょう。 89
  90. 参考⽂献 ▶ ⼊⾨ 監視 n モダンなモニタリングのためのデザインパターン ▶ ⼊⾨ Prometheus n

    インフラとアプリケーションのパフォーマンスモニタリ ング 90