$30 off During Our Annual Pro Sale. View Details »

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

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

Cybozu
PRO

June 22, 2021
Tweet

More Decks by Cybozu

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  14. デモ環境の構築
    14

    View Slide

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

    View Slide

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

    View Slide

  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
    ラベル 値
    メトリクス名
    メトリクスのタイプ(後述)
    メトリクスの説明
    メトリクスのフォーマット

    View Slide

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

    View Slide

  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)・・・]
    タイムスタンプを付与して時系列データとして保存
    保存

    View Slide

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

    View Slide

  21. PromQL
    21

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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回

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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
    ベクトルマッチング

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  53. PromQLの例
    53

    View Slide

  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使⽤率

    View Slide

  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が何度も再起動を繰り返す

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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の収集ルールの対応

    View Slide

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

    View Slide

  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

    View Slide

  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
    メタラベルとリラベル

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  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
    をセミコロン区切りで書
    く。
    複数ラベルの指定

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  78. 78
    - ⼊⾨Prometheusより

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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設定

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

  88. まとめ
    88

    View Slide

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

    View Slide

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

    View Slide