Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

2 アジェンダ - 自己紹介 - 監視どうしてます? - 異常検知アラートとは? - Prometheus メトリクスを利用した異常検知アラートの実装 - おわりに 2

Slide 3

Slide 3 text

3 自己紹介 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

6 アジェンダ - 自己紹介 - 監視どうしてます? - 異常検知アラートとは? - Prometheus メトリクスを利用した異常検知アラートの実装 - おわりに 6

Slide 7

Slide 7 text

7 監視どうしてます? 7

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

13 しきい値アラート 監視どうしてます? - 特定の基準を超えた場合にアラートを発泡する - ex: CPU 使用率が 80% を超えたらアラート - ex: レスポンスタイムが 2.0s を上回ったらアラート 13

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

21 - 何らかの方法で「通常の動作」を定義する - 「通常の動作」の範囲内とする幅を設定する - 幅を超えたら異常であるとして検知する 異常検知 (Anomaly Detection) 異常検知アラートとは? 21 画像は https://docs.datadoghq.com/ja/monitors/monitor_types/anomaly/ より

Slide 22

Slide 22 text

22 - 「異常検知モニター」として提供されている - DataDog に送られるすべてのメトリクスに対して設定可能 既存の実装例 (DataDog) 異常検知アラートとは? 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

24 - CloudWatch metrics/alarm で利用可能 - AWS の監視、これでいいかもしれない 既存の実装例 (CloudWatch) 異常検知アラートとは? 24 パブリッククラウドいいなあ 🤔

Slide 25

Slide 25 text

25 オンプレにも 異常検知アラートがほしい! 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

27 - オンプレの監視 … Cloud Native… - Prometheus だ!! オンプレ向け異常検知アラート 異常検知アラートとは? 27 Prometheus をデータソースとした 異常検知を実装できないか?

Slide 28

Slide 28 text

28 Prometheus を利用した 異常検知アラートの実装 28

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

30 - 時間軸に沿って並べられたデータのこと - ex: 年間気温推移、株価推移、システムのメトリクス - Prometheus に格納されるデータも時系列データ 時系列データ Prometheus を利用した異常検知アラートの実装 30

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

36 - 計算量が少なくて済む - 構築済みモデルに適切な次数を与えるだけ - 次数の探索にはある程度計算が必要 - 採用実績が豊富 - DataDog (SARIMA = Seasonal-ARIMA) - BigQuery ML の時系列予測モデル ARIMA を選択した Prometheus を利用した異常検知アラートの実装 36

Slide 37

Slide 37 text

37 1. 環境を用意する 2. データを用意する 3. データの形を整える 4. データを学習用 (train), テスト用(test)に分割する 5. 問題に最適なモデルを探索する 6. 結果をテストデータで確認する ARIMA を用いた時系列予測の手順 Prometheus を利用した異常検知アラートの実装 37

Slide 38

Slide 38 text

38 - Python 3.10.6 で実装する - 機械学習といえば Python! - Jupyter Notebook で実験する - うまくいったら API として実装する - pmdarima というライブラリを使う - ARIMA を使う上で便利な物が詰まってる 環境を用意する Prometheus を利用した異常検知アラートの実装 38

Slide 39

Slide 39 text

39 - 特定のスニペットを実行したり、グラフを表示したりできる - VS Code Extension が環境構築までやってくれてすごく便利 - あなたも今すぐ `code test.ipynb` を実行! Jupyter Notebook Prometheus を利用した異常検知アラートの実装 39

Slide 40

Slide 40 text

40 - とある Kubernetes Pod の CPU 使用率を利用した - 周期的でいい感じ データを用意する Prometheus を利用した異常検知アラートの実装 40

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

42 - データ数を減らす、計算しやすい周期にする - 1時間ごとのデータなら24個で1日となる - prometheus API の step パラメータで調整 データの形を整える Prometheus を利用した異常検知アラートの実装 42 step = 600s step = 3600s

Slide 43

Slide 43 text

43 - 過学習(over fitting) を防ぐため - pandas.Serias を作成する - [datetime] が index, [float] が value - pmdarima 提供のメソッドに入れる データを学習用 (train), テスト用(test)に分割する Prometheus を利用した異常検知アラートの実装 43

Slide 44

Slide 44 text

44 - 赤がtrain, 青が test - 時系列データは index が train < test である必要がある - 過去のデータから未来を予測するので データを学習用 (train), テスト用(test)に分割する Prometheus を利用した異常検知アラートの実装 44

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

46 - このパラメータの意味するところは? - 私はよくわからないのでお近くの機械学習の方にお聞きください! 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 46

Slide 47

Slide 47 text

47 - ARIMA(p, d, q)(P, D, Q)[m] を埋めていく - 差分パラメータは、d = 1, D = 1 が一般的らしい - m は季節周期なのでデータにより個別に設定する 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 47

Slide 48

Slide 48 text

48 - 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 48 ここが m になるので、 今回は m = 24 となる

Slide 49

Slide 49 text

49 - ARIMA(p, d, q)(P, D, Q)[m] を埋めていく - 差分パラメータは、d = 1, D = 1 が一般的らしい - m は季節周期なのでデータにより個別に設定する - 今回のデータは m = 24 - p, q, P, Q を埋める必要がある 最適なモデルを探索する Prometheus を利用した異常検知アラートの実装 49

Slide 50

Slide 50 text

50 - 最適な次数を出してくれるメソッド (!!! - 総当りでモデルを作成し、最適な次数を選ぶ - 評価には赤池情報量基準(AIC) を用いる pmdarima.auto_arima() Prometheus を利用した異常検知アラートの実装 50

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

55 1. 環境を用意する 2. データを用意する 3. データの形を整える 4. データを学習用 (train), テスト用(test)に分割する 5. 問題に最適なモデルを探索する 6. 結果をテストデータで確認する ARIMA を用いた時系列予測の手順 Prometheus を利用した異常検知アラートの実装 55

Slide 56

Slide 56 text

56 - 作成したモデルで予測した結果を出す - n_periods … いくつぶん予測データを出力するか - 今回はテストデータの長さ分 - return_conf_int … 信頼区間の配列を return するか 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 56

Slide 57

Slide 57 text

57 - 信頼区間 … 統計的に真の値が含まれる可能性の高い範囲 - conf_int[][0] = 信頼区間の min - conf_int[][1] = 信頼区間の max - min < 実績値 < max なら予測はあたりということになる 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 57 グレーの範囲が 信頼区間

Slide 58

Slide 58 text

58 - 予測データとテストデータを同じ時系列でプロット - いいね! 結果をテストデータで確認する Prometheus を利用した異常検知アラートの実装 58

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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)

Slide 63

Slide 63 text

63 - 次数が既知の場合、pmdarima.ARIMA().fit() でモデルを作成できる - 探索するより計算量が少なめ exporter の実装 Prometheus を利用した異常検知アラートの実装 63

Slide 64

Slide 64 text

64 - order は tuple なので ast.literal_eval で str を tuple にする exporter の実装 Prometheus を利用した異常検知アラートの実装 64

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

66 - exporter の実装 Prometheus を利用した異常検知アラートの実装 66

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

74 - Prometheus には過去未来の時刻のメトリクスを入れることができない - モデル作成時に過去2~3時間前までのデータを使う - scrape 時に予測値を出すと、現在時刻のデータが含まれてくる Prometheus の制約 Prometheus を利用した異常検知アラートの実装 74

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

78 - Prometheus に scrape させて完成! exporter の実装 Prometheus を利用した異常検知アラートの実装 78 赤線が実績値で、 その上下が信頼区間

Slide 79

Slide 79 text

79 - 異常を検知したかというメトリクスを作った - これを監視していればある程度よい! exporter の実装 Prometheus を利用した異常検知アラートの実装 79

Slide 80

Slide 80 text

80 異常検知 API の課題 80

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

85 - 一定周期が繰り返されるものは得意 - だんだんと積み上がっていく異常は苦手 - 変化に追従してしまう 苦手な時系列が存在する 異常検知 API の課題 85

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

87 おわりに 87

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

89 - 有用性は確認できた - 特定のメトリクスの監視には役に立ちそう - 既存のしきい値監視の置き換えはまだ難しそう - まだまだやれることがある - 並列ジョブでモデル構築したり - 次数の探索をジョブで自動化したり - インフラ課題をいろいろな技術を使って解決しませんか!!! 異常検知の道はまだまだ続くよ! おわりに 89

Slide 90

Slide 90 text

90 We are HIRING !!! https://recruit.pepabo.com/ 90

Slide 91

Slide 91 text

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