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

しきい値監視からの卒業! Prometheus による機械学習を用いた異常検知アラートの実装

Takuya TAKAHASHI
November 22, 2022
700

しきい値監視からの卒業! Prometheus による機械学習を用いた異常検知アラートの実装

CNDT2022 で発表した内容です

Takuya TAKAHASHI

November 22, 2022
Tweet

Transcript

  1. 1 しきい値監視からの卒業! Prometheus による機械学習を用いた 異常検知アラートの実装 GMO ペパボ株式会社 高橋 拓也

  2. 2 アジェンダ - 自己紹介 - 監視どうしてます? - 異常検知アラートとは? - Prometheus

    メトリクスを利用した異常検知アラートの実装 - おわりに 2
  3. 3 自己紹介 3

  4. 4 高橋拓也 自己紹介 GMO ペパボ株式会社でインフラエンジニアをやっています。 コードを書くことと Kubernetes が好きです。 自宅サーバを飼っています。 Twitter:

    @takutaka1220 GitHub: takutakahashi 4
  5. 5 宣伝: GMOペパボでは CNDT 2022 で 5セッション登壇しています! 自己紹介 - 全部終わっちゃってるので、アーカイブを御覧ください!

    - Dynamic VM Scheduling in OpenStack by Kazuhiko Yamashita - k8s Operatorで運用負担減&ハイブリッドクラウドのコスト最適化をした話 by Chiaki Sugawara - 実例から学ぶ Kubernetes Custom Controller のステータス管理 by Takuya Takahashi - ペパボのSREが生産性の向上を目指しCloud Nativeなチーム作り実践し た話 by Ryuichi Watanabe - しきい値監視からの卒業! Prometheus による機械学習を用いた異常 検知アラートの実装 by Takuya Takahashi 5
  6. 6 アジェンダ - 自己紹介 - 監視どうしてます? - 異常検知アラートとは? - Prometheus

    メトリクスを利用した異常検知アラートの実装 - おわりに 6
  7. 7 監視どうしてます? 7

  8. 8 - 監視手法 - メトリクス監視、外形監視、etc… - 監視対象 - ワークロードの CPU、メモリ使用率、etc…

    - レスポンスコード、レイテンシ、etc… - プラットフォームの正常性 - Kubernetes API は動いているか? - クラスタ内通信は動いているか? - オートスケーラーは動いているか? - etc… 大クラウドネイティブ時代でもなくならないもの、それは監視 監視どうしてます? 8
  9. 9 - 監視手法 - メトリクス監視、外形監視、etc… - 監視対象 - ワークロードの CPU、メモリ使用率、etc…

    - SLO が Violation していないか - プラットフォームの正常性 - Kubernetes API は動いているか? - クラスタ内通信は動いているか? - オートスケーラーは動いているか? - etc… 大クラウドネイティブ時代でもなくならないもの、それは監視 監視どうしてます? 9 監視めちゃめちゃ大変
  10. 10 監視するものはどういうものがあるか - システムメトリクス - CPU 使用率、メモリ使用率、ネットワーク帯域 etc - 想定より高くなってないか?

    - サービスメトリクス - ステータスコード - 想定より失敗が多くないか? - リクエストレイテンシ - 想定より遅くなっていないか? - サービスやプラットフォームの健全性 - 外形監視、ネットワーク疎通監視 - 正常に動いているか? (true or false の2値) 監視どうしてます? 10
  11. 11 監視するものはどういうものがあるか - システムメトリクス - CPU 使用率、メモリ使用率、ネットワーク帯域 etc - 想定より高くなってないか?

    - サービスメトリクス - ステータスコード - 想定より失敗が多くないか? - リクエストレイテンシ - 想定より遅くなっていないか? - サービスやプラットフォームの健全性 - 外形監視、ネットワーク疎通監視 - 正常に動いているか? (true or false の2値) 監視どうしてます? 11
  12. 12 監視するものはどういうものがあるか - システムメトリクス - CPU 使用率、メモリ使用率、ネットワーク帯域 etc - 想定より高くなってないか?

    - サービスメトリクス - ステータスコード - 想定より失敗が多くないか? - リクエストレイテンシ - 想定より遅くなっていないか? 監視どうしてます? 12 - システムメトリクス - CPU 使用率、メモリ使用率、ネットワーク帯域 etc - 想定より高くなってないか? - サービスメトリクス - ステータスコード - 想定より失敗が多くないか? - リクエストレイテンシ - 想定より遅くなっていないか? - サービスやプラットフォームの健全性 - 外形監視、ネットワーク疎通監視 - 正常に動いているか? (true or false の2値) しきい値を用いてアラートを発泡する
  13. 13 しきい値アラート 監視どうしてます? - 特定の基準を超えた場合にアラートを発泡する - ex: CPU 使用率が 80%

    を超えたらアラート - ex: レスポンスタイムが 2.0s を上回ったらアラート 13
  14. 14 しきい値はどうやって決める? 監視どうしてます? - 平常時の負荷から決める - 普段は CPU 使用率が 40%

    だから 60% をしきい値にする 14
  15. 15 しきい値はどうやって決める? 監視どうしてます? - 平常時の負荷から決める - 普段は CPU 使用率が 40%

    だから 60% をしきい値にする - ピーク時に60%超えちゃってアラートが頻発... 15
  16. 16 しきい値はどうやって決める? 監視どうしてます? - 平常時の負荷から決める - 普段は CPU 使用率が 40%

    だから 60% をしきい値にする - ピーク時に60%超えちゃってアラートが頻発... - 繁忙期にはベースの負荷が高まりアラート... 16
  17. 17 しきい値の見直しは大変 監視どうしてます? - しきい値を定める目的は? - 「いつもの挙動」と違う挙動を見つけるため 17

  18. 18 しきい値の見直しは大変 監視どうしてます? - しきい値を定める目的は? - 「いつもの挙動」と違う挙動を見つけるため 18

  19. 19 しきい値の見直しは大変 監視どうしてます? - しきい値を定める目的は? - 「いつもの挙動」と違う挙動を見つけるため 19 異常検知アラートという手法があります!

  20. 20 異常検知アラートとは? 20

  21. 21 - 何らかの方法で「通常の動作」を定義する - 「通常の動作」の範囲内とする幅を設定する - 幅を超えたら異常であるとして検知する 異常検知 (Anomaly Detection)

    異常検知アラートとは? 21 画像は https://docs.datadoghq.com/ja/monitors/monitor_types/anomaly/ より
  22. 22 - 「異常検知モニター」として提供されている - DataDog に送られるすべてのメトリクスに対して設定可能 既存の実装例 (DataDog) 異常検知アラートとは? 22

  23. 23 - CloudWatch metrics/alarm で利用可能 - AWS の監視、これでいいかもしれない 既存の実装例 (CloudWatch)

    異常検知アラートとは? 23
  24. 24 - CloudWatch metrics/alarm で利用可能 - AWS の監視、これでいいかもしれない 既存の実装例 (CloudWatch)

    異常検知アラートとは? 24 パブリッククラウドいいなあ 🤔
  25. 25 オンプレにも 異常検知アラートがほしい! 25

  26. 26 - オンプレのメトリクス... 監視 … Cloud Native… - Prometheus だ!!

    オンプレ向け異常検知アラート 異常検知アラートとは? 26
  27. 27 - オンプレの監視 … Cloud Native… - Prometheus だ!! オンプレ向け異常検知アラート

    異常検知アラートとは? 27 Prometheus をデータソースとした 異常検知を実装できないか?
  28. 28 Prometheus を利用した 異常検知アラートの実装 28

  29. 29 - 異常検知は「時系列データの予測」の問題に置き換えられる - 既知のデータを使って未来の値を予測する - 実際の値と予測値を比較する 異常検知ってなにすればできるの? Prometheus を利用した異常検知アラートの実装

    29
  30. 30 - 時間軸に沿って並べられたデータのこと - ex: 年間気温推移、株価推移、システムのメトリクス - Prometheus に格納されるデータも時系列データ 時系列データ

    Prometheus を利用した異常検知アラートの実装 30
  31. 31 - 予測がしやすいデータ - 周期がある - 欠損がない すべてのデータが予測できるわけではない Prometheus を利用した異常検知アラートの実装

    31
  32. 32 - 予測しづらいデータ - ランダムである すべてのデータが予測できるわけではない Prometheus を利用した異常検知アラートの実装 32

  33. 33 - 異常検知は「時系列データの予測」の問題に置き換えられる - 既知のデータを使って未来の値を予測する - 実際の値と予測値を比較する 異常検知ってなにすればできるの? Prometheus を利用した異常検知アラートの実装

    33
  34. 34 - 時系列データの予測モデルはいくつか存在する - ARIMA - Auto-Regressive Integrated Moving Average

    - 自己回帰(AR)と差分(I), 移動平均(MA)を組み合わせたモデルらしい - DataDog の異常検知モニターでも使用されている - LSTM - Long Short Term Memory - リカレントニューラルネットワークというものを使った深層学習 - etc… 時系列データの予測モデル Prometheus を利用した異常検知アラートの実装 34
  35. 35 - 時系列データの予測モデルはいくつか存在する - ARIMA - Auto-Regressive Integrated Moving Average

    - 自己回帰(AR)と差分(I), 移動平均(MA)を組み合わせたモデルらしい - DataDog の異常検知モニターでも使用されている - LSTM - Long Short Term Memory - リカレントニューラルネットワークというものを使った深層学習 - etc… 時系列データの予測モデル Prometheus を利用した異常検知アラートの実装 35
  36. 36 - 計算量が少なくて済む - 構築済みモデルに適切な次数を与えるだけ - 次数の探索にはある程度計算が必要 - 採用実績が豊富 -

    DataDog (SARIMA = Seasonal-ARIMA) - BigQuery ML の時系列予測モデル ARIMA を選択した Prometheus を利用した異常検知アラートの実装 36
  37. 37 1. 環境を用意する 2. データを用意する 3. データの形を整える 4. データを学習用 (train),

    テスト用(test)に分割する 5. 問題に最適なモデルを探索する 6. 結果をテストデータで確認する ARIMA を用いた時系列予測の手順 Prometheus を利用した異常検知アラートの実装 37
  38. 38 - Python 3.10.6 で実装する - 機械学習といえば Python! - Jupyter

    Notebook で実験する - うまくいったら API として実装する - pmdarima というライブラリを使う - ARIMA を使う上で便利な物が詰まってる 環境を用意する Prometheus を利用した異常検知アラートの実装 38
  39. 39 - 特定のスニペットを実行したり、グラフを表示したりできる - VS Code Extension が環境構築までやってくれてすごく便利 - あなたも今すぐ

    `code test.ipynb` を実行! Jupyter Notebook Prometheus を利用した異常検知アラートの実装 39
  40. 40 - とある Kubernetes Pod の CPU 使用率を利用した - 周期的でいい感じ

    データを用意する Prometheus を利用した異常検知アラートの実装 40
  41. 41 - Prometheus から REST API でデータを取得 - unix time,

    value の配列が得られる データを用意する Prometheus を利用した異常検知アラートの実装 41
  42. 42 - データ数を減らす、計算しやすい周期にする - 1時間ごとのデータなら24個で1日となる - prometheus API の step

    パラメータで調整 データの形を整える Prometheus を利用した異常検知アラートの実装 42 step = 600s step = 3600s
  43. 43 - 過学習(over fitting) を防ぐため - pandas.Serias を作成する - [datetime]

    が index, [float] が value - pmdarima 提供のメソッドに入れる データを学習用 (train), テスト用(test)に分割する Prometheus を利用した異常検知アラートの実装 43
  44. 44 - 赤がtrain, 青が test - 時系列データは index が train

    < test である必要がある - 過去のデータから未来を予測するので データを学習用 (train), テスト用(test)に分割する Prometheus を利用した異常検知アラートの実装 44
  45. 45 - データにより適切なモデルへの入力が異なる - ARIMA モデルでは以下の入力を必要とする - p … 自己回帰

    (AR) のパラメータ - d … 差分 (I) のパラメータ - q … 移動平均 (MA) のパラメータ - ARIMA(p, d, q) と表現する - Seasonal-ARIMA はさらに季節周期の次数 (P, D, Q) と周期 m がある - 合わせて ARIMA(p, d, q)(P, D, Q)[m] と表記される 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 45
  46. 46 - このパラメータの意味するところは? - 私はよくわからないのでお近くの機械学習の方にお聞きください! 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 46

  47. 47 - ARIMA(p, d, q)(P, D, Q)[m] を埋めていく - 差分パラメータは、d

    = 1, D = 1 が一般的らしい - m は季節周期なのでデータにより個別に設定する 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 47
  48. 48 - 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 48 ここが m になるので、 今回は

    m = 24 となる
  49. 49 - ARIMA(p, d, q)(P, D, Q)[m] を埋めていく - 差分パラメータは、d

    = 1, D = 1 が一般的らしい - m は季節周期なのでデータにより個別に設定する - 今回のデータは m = 24 - p, q, P, Q を埋める必要がある 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 49
  50. 50 - 最適な次数を出してくれるメソッド (!!! - 総当りでモデルを作成し、最適な次数を選ぶ - 評価には赤池情報量基準(AIC) を用いる pmdarima.auto_arima()

    Prometheus を利用した異常検知アラートの実装 50
  51. 51 - pmdarima.auto_arima() Prometheus を利用した異常検知アラートの実装 51

  52. 52 - pmdarima.auto_arima() Prometheus を利用した異常検知アラートの実装 52 AIC が小さいほど いいモデル

  53. 53 - pmdarima.auto_arima() Prometheus を利用した異常検知アラートの実装 53 最適な次数が出た!

  54. 54 - ARIMA(p, d, q)(P, D, Q)[m] を埋めていく - 差分パラメータは、d

    = 1, D = 1 が一般的らしい - m は季節周期なのでデータにより個別に設定する - 今回のデータは m = 24 - p, q, P, Q を埋める必要がある - auto_arima() により、以下の次数が選ばれた - ARIMA(1,1,1)(2,1,1)[24] 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 54
  55. 55 1. 環境を用意する 2. データを用意する 3. データの形を整える 4. データを学習用 (train),

    テスト用(test)に分割する 5. 問題に最適なモデルを探索する 6. 結果をテストデータで確認する ARIMA を用いた時系列予測の手順 Prometheus を利用した異常検知アラートの実装 55
  56. 56 - 作成したモデルで予測した結果を出す - n_periods … いくつぶん予測データを出力するか - 今回はテストデータの長さ分 -

    return_conf_int … 信頼区間の配列を return するか 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 56
  57. 57 - 信頼区間 … 統計的に真の値が含まれる可能性の高い範囲 - conf_int[][0] = 信頼区間の min

    - conf_int[][1] = 信頼区間の max - min < 実績値 < max なら予測はあたりということになる 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 57 グレーの範囲が 信頼区間
  58. 58 - 予測データとテストデータを同じ時系列でプロット - いいね! 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 58

  59. 59 作成したモデルで 予測 API を実装する 59

  60. 60 - アラートが出せるような API として実装する - 異常検知メトリクスとして Prometheus で収集、監視すると良さそう API

    を実装する Prometheus を利用した異常検知アラートの実装 60
  61. 61 - https://github.com/takutakahashi/promad で実装中 - クエリと次数を入力に持ち、異常かどうかを出力する - 引き続き pmdarima を使うため

    Python で実装する exporter の実装 Prometheus を利用した異常検知アラートの実装 61
  62. 62 - 次数を手に入れたのでそれを入力値として持つ - メトリクスの定義を rules.yaml にまとめる exporter の実装 Prometheus

    を利用した異常検知アラートの実装 62 % cat ./rules.yaml - name: pod_cpu query: sum(rate(container_cpu_usage_seconds_total{pod=~"workload-pod.*"}[5m])) arima: order: (1,1,1) # (p,d,q) seasonal_order: (2,1,1,24) # (P,D,Q,m)
  63. 63 - 次数が既知の場合、pmdarima.ARIMA().fit() でモデルを作成できる - 探索するより計算量が少なめ exporter の実装 Prometheus を利用した異常検知アラートの実装

    63
  64. 64 - order は tuple なので ast.literal_eval で str を

    tuple にする exporter の実装 Prometheus を利用した異常検知アラートの実装 64
  65. 65 - fit() の入力には prometheus をクエリしたデータを入れる - pd.Series に変換して入れるとよい exporter

    の実装 Prometheus を利用した異常検知アラートの実装 65 query_range() メソッドで prometheus にリクエストしてるよ
  66. 66 - exporter の実装 Prometheus を利用した異常検知アラートの実装 66

  67. 67 - exporter の実装 Prometheus を利用した異常検知アラートの実装 67 model.predict() で予測値と信頼区間を出して

  68. 68 - exporter の実装 Prometheus を利用した異常検知アラートの実装 68 現在時刻と一番近い時刻の予測値を出して

  69. 69 - exporter の実装 Prometheus を利用した異常検知アラートの実装 69 現在時刻の実績値を出して

  70. 70 - exporter の実装 Prometheus を利用した異常検知アラートの実装 70 現在値が信頼区間に入っているかを計算して

  71. 71 - exporter の実装 Prometheus を利用した異常検知アラートの実装 71 prometheus がスクレイピングできる形式に 変換してレスポンスする

  72. 72 - exporter の実装 Prometheus を利用した異常検知アラートの実装 72 現在時刻と一番近い時刻の予測値を出して

  73. 73 - Prometheus には過去未来の時刻のメトリクスを入れることができない Prometheus の制約 Prometheus を利用した異常検知アラートの実装 73 exporter

    の出力には時刻情報はない
  74. 74 - Prometheus には過去未来の時刻のメトリクスを入れることができない - モデル作成時に過去2~3時間前までのデータを使う - scrape 時に予測値を出すと、現在時刻のデータが含まれてくる Prometheus

    の制約 Prometheus を利用した異常検知アラートの実装 74
  75. 75 - Prometheus には過去未来の時刻のメトリクスを入れることができない - scrape 時には、予め予測値として作成しておいたものを出す Prometheus の制約 Prometheus

    を利用した異常検知アラートの実装 75
  76. 76 - Prometheus には過去未来の時刻のメトリクスを入れることができない - scrape 時には、予め予測値として作成しておいたものを出す Prometheus の制約 Prometheus

    を利用した異常検知アラートの実装 76 現在時刻 一番近い予測値
  77. 77 - exporter として現在時刻の予測値を出力する exporter の実装 Prometheus を利用した異常検知アラートの実装 77

  78. 78 - Prometheus に scrape させて完成! exporter の実装 Prometheus を利用した異常検知アラートの実装

    78 赤線が実績値で、 その上下が信頼区間
  79. 79 - 異常を検知したかというメトリクスを作った - これを監視していればある程度よい! exporter の実装 Prometheus を利用した異常検知アラートの実装 79

  80. 80 異常検知 API の課題 80

  81. 81 - 作ってみて気づいた事実 これだけではしきい値監視を卒業できない 異常検知 API の課題 81

  82. 82 - データ間隔が 1h のメトリクスひとつに対し、 - 2.8GHz の CPU 2000m

    割当を100%消費し、 - 大体1分くらい リソース使用量が多い 異常検知 API の課題 82
  83. 83 - データ間隔が 1h のメトリクスひとつに対し、 - 2.8GHz の CPU 2000m

    割当を100%消費し、 - 大体1分くらい - さらに傾向が変わるとモデルを作り直さないといけなかったり - 時間経過によりモデルの鮮度が落ちるので作り直さないとだったり リソース使用量が多い 異常検知 API の課題 83
  84. 84 - データ間隔が 1h のメトリクスひとつに対し、 - 2.8GHz の CPU 2000m

    割当を100%消費し、 - 大体1分くらい - さらに傾向が変わるとモデルを作り直さないといけなかったり - 時間経過によりモデルの鮮度が落ちるので作り直さないとだったり リソース使用量が多い 異常検知 API の課題 84 すべてのメトリクスを異常検知モニタリングするには リソース使用量削減の工夫が必要そう
  85. 85 - 一定周期が繰り返されるものは得意 - だんだんと積み上がっていく異常は苦手 - 変化に追従してしまう 苦手な時系列が存在する 異常検知 API

    の課題 85
  86. 86 - Seasonal-ARIMA が苦手というだけなので、別の手法を使うと良さそう - CloudWatch は 12,000 以上の内部モデルにルーツを持っている。。。 苦手な時系列が存在する

    異常検知 API の課題 86
  87. 87 おわりに 87

  88. 88 - 有用性は確認できた - 特定のメトリクスの監視には役に立ちそう - 既存のしきい値監視の置き換えはまだ難しそう - まだまだやれることがある -

    並列ジョブでモデル構築したり - 次数の探索をジョブで自動化したり 異常検知の道はまだまだ続くよ! おわりに 88
  89. 89 - 有用性は確認できた - 特定のメトリクスの監視には役に立ちそう - 既存のしきい値監視の置き換えはまだ難しそう - まだまだやれることがある -

    並列ジョブでモデル構築したり - 次数の探索をジョブで自動化したり - インフラ課題をいろいろな技術を使って解決しませんか!!! 異常検知の道はまだまだ続くよ! おわりに 89
  90. 90 We are HIRING !!! https://recruit.pepabo.com/ 90

  91. 91 ARIMA モデルについて 参考文献 https://www.salesanalytics.co.jp/datascience/datascience087/ 91