新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

GCPのKubernetes(GKE)で、プログラムでエラーが発生したら、Slackやメールなどの外部に通知する方法です。

自分でエラー検知の仕組みを実装しなくても、GCPの設定のみで可能です。

大まかな仕組み

プログラムでエラーが発生した時に、プログラムから標準エラーにメッセージを出力するようにします。

GKEでは標準で、コンテナの標準出力および標準エラーをCloud Loggingにログとして出力してくれます。

Cloud MonitoringでCloud Loggingのログを監視して、出力があった時に外部通知するようにします。

GCPの仕組み

GKEとCloud Logging

GKEでクラスターを作成すると、デフォルトで各種ログがCloud Loggingに出力されるようになります。

ログにはコンテナからの標準出力・標準エラーも含まれていて、プログラムからは意識することなしに、標準出力・標準エラーに対して出力さえしておけば、同じものがCloud Loggingにも出力されてログとして残ります。

Cloud Monitoring

Cloud Monitoringとは、様々な指標データを蓄積して、そのデータからグラフを作成するツールです。

例えば、インスタンスのメモリ使用量データをCloud Monitoringに定期的に送るようにして、グラフにして監視するといったことができます。

Cloud Monitoringの機能の一つに、指標に条件を設定して、条件に一致した時に外部に通知を送ることができます。

今回はその機能を使って、コンテナから標準エラーに出力があった時に外部通知を送るようにします。

Cloud Monitoringはログ監視に近い印象ですが、指標はログというより、時系列に登録されていくデータベースのレコードのようなもので、Cloud Monitoringは、指標データベースと、そのデータベースの可視化・監視ツールがセットになったようなサービスです。

Cloud MonitoringとCloud Loggingの組み合わせ

Cloud Loggingは単なるログなので、ログをCloud Monitoringで監視するには、ログからCloud Monitoringに指標としてデータを送るようにします。

具体的には、Cloud Loggingで監視したいログを表示するクエリを書き、そのクエリをCloud Monitoringの指標として登録します。

すると、Cloud Loggingが定期的にそのクエリを実行し、実行結果のログ件数を、Cloud Monitoringへ指標として送るようになります。

後はCloud Monitoringで、その指標に値が入った時に、外部に通知を送るように設定すると、ログに出力があると外部に通知が送られるようになります。

手順

コンテナ

コンテナからは標準エラーに出力するだけです。

例)標準エラー出力アプリ

package main

import (
    "fmt"
    "os"
    "time"
)

func main() {
    for {
        m := time.Now().Minute()
        for i := 0; i <= m; i++ {
            fmt.Fprintf(os.Stderr, "stderr message : %+v/%+v\n", i, m)
        }
        fmt.Println("stdout message")
        time.Sleep(2 * time.Minute)
    }
}

Cloud Logging

指標を作る

Kubernetesからは、Cloud Loggingに様々なログが出力されているのですが、Cloud Loggingの「ログビューア」では、「ログ フィールド エクスプローラ」でマウスでポチポチやるだけで、多数のログの中から、指定のログに絞り込んで表示することができます。

例えば、前述のコンテナのエラーログを表示します。

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

絞り込み方法はクエリとして作成されます。

resource.type="k8s_container"
resource.labels.cluster_name="cluster-test-dev"
resource.labels.container_name="container-app-go"
severity=ERROR

このクエリのログ件数を指標として登録します。

  • 「指標を作成」をクリックします

すると「指標エディタ」が開くので、「名前」および、タイプを「カウンター」にセットして、「指標を作成」をクリックすると、このクエリを満たすログの件数を出す、オリジナルの指標が作成されます。

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

クエリは正規表現なども使えるので、pod単位でエラーログを絞り込むなど、柔軟な指定が可能です。

アラートを作る

後は、Cloud Monitoringで、先程作成した、コンテナのエラーログ件数指標でアラートを作成します。

流れ

ちょっとややこしいので、ログからアラート検知および、アラート終了までのデータの流れを先に記載します。

  • ログベースの指標は、1分毎にクエリを実行して、実行結果の件数をCloud Monitoringに送ります。クエリ結果が0件でも値0の指標として登録されます
  • 記録されたログ件数を、任意の方法で集計(計算)します。
    • 例えば、「5分毎に件数の合計を求める」など
  • 集計結果をチェックして、指定期間中条件を満たすとアラートを発生させます。
    • 例えば、「1時間の間、集計結果が常に0以上の場合にアラート発生」など
  • アラートが発生してから、条件を満たさなくなると、アラートは終了します。
    • アラートが条件を満たす限り、新しい通知は送られません。

作成

指標から集計を行います。

  • [Cloud Logging]-[ログベースの指標]-[ユーザー定義の指標]

で作成したログベースの指標の右の「...」で「指標に基づいて通知を作成する」にします。

すると、Cloud Monitoringの通知ポリシー作成に遷移します。

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

ログベースの指標は「logging/user/~」という名前で指標として登録されているので、通知ポリシーの「Metric」にその名前が設定されています。

集計指定

Cloud Monitoringには、ログベースの指標が記録されていきます。そのままだと単なるログ件数データなので、それを使って、何を集計(計算)するかを決めます。

例えば、5分毎に件数を集計します。

  • Aggregatornone
  • Period5 minute
  • [Advnced Aggregation]-[Aligner]sum

にします。

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

条件指定

「Configuration」で、上で集計した値がどうなったらアラートになるかを設定します。

例えば、1分間の間、常に1件以上エラーがあったら通知にします。

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

  • [Configuration]-[Threshold]0

これで、1分間の間、常に1件以上エラーがあったら通知が送信されます。

条件を満たしている間はアラートが続いていると判定されて、新たな通知は行われません。

条件を満たさなくなると、そのアラートは終了となり、次に条件を満たすと新しくアラートが発生して通知が行われます。

通知先指定

後は通知先を指定すると、アラートが発生すると、通知先に通知が行きます。

例)メール通知

Google Kubernetes Engine(GKE)で、コンテナでエラーが発生したらSlackやメールに通知する方法

Cloud Monitoring 補足説明

Cloud Monitoringでいくつかハマったので、使い方を簡単にまとめておきます。

Aggregatorについて

指標からグラフを作成する際、ログベースの指標は1つしかないのでグラフは1本ですが、インスタンスのメモリ使用量指標などだと、インスタンスの数だけグラフが表示されます。そして複数のグラフを1つにまとめる方法をAggregatorで指定します。今回のように、グラフ(指標)が1つしかない場合は、Aggregatornoneにします。

Alignerについて

Cloud Monitoringは柔軟に作られていて、受け取った指標の値をそのまま表示するのではなく、任意の集計をして表示します。そして、その集計方法を[Advnced Aggregation]-[Aligner]で指定します。

今回のように、ログ件数(指標)を求めるにはsumにしますし、期間中の最大値を取りたい場合はmaxにします。

countがあるのですが、これはログ件数のことではなく、ログベースの指標が送られた回数のことです。ですので、ログ件数が0でも、指標が登録された回数がカウントされます。

そして、ログベースの指標は1分毎に送られるので、例えばPeriod10 minuteにすると、countは10になります。

Configuration について

上記で指定した、指標の集計結果が、どれだけの期間条件が続けば、異常状態とするかを指定します。

例えば、エラーログを検知したらアラートとする場合は、1分間の間に1件以上あればアラートとします。

ここで指定する期間は、チェック頻度の期間ではなく、条件を満たし続ける期間です。

例えばチェック頻度を1時間毎にする場合は、ここでの頻度を1時間にするのではなく、集計頻度を1時間にします。

集計頻度を1分にして、ここでの期間を1時間にすると、60分間エラーが出続けた場合にエラーという条件になります。その場合、60分の間に1度でもエラーが無い時があると、条件は成立しません。

ログベースの指標は1分毎にデータが送られてきますが、指標によっては、不定期にデータが送られてくるものもあります。そういった場合、条件成立に使われる値はどうなるかというと、一番最後に取得した指標がそのまま続いているとして扱われます。

例えば、集計頻度を1時間にして、ここでの頻度を10分にすると、エラーが発生して集計でエラー件数が0以上になった後、その状態が1時間続くことになります。そして、それはエラーが集計されてから10分間その状態が続いていることになるので、結果として10分後にアラートが成立します。そして、そのまま50分間エラー状態が続き、その間アラートは解除されません。そして次の集計でエラーが0件になると、アラート状態が解除されます。

感想など

Cloud LoggingとCloud Monitoringを組み合わせて使うので、ドキュメントやUIが分散していてちょっととっつきにくいですね。

ハマりポイントとしては

  • Cloud Loggingそのものは単なるログで、アラート機能はなく、ログから指標を作成して、その指標を介してCloud Monitoringからアラートを生成する
  • ログベースの指標は、ログが記録されると登録されるのではなく、常に一定間隔でクエリを実行し、その実行結果を登録している
  • クエリの実行結果が0件でも指標として登録される
  • Cloud Monitoringは指標をそのまま使うのではなく、一定間隔の集計結果を使う
  • アラートは、指定期間中その状態を満たし続けた場合に発生する
  • アラートの指定指定期間中に新しい指標が登録されなかった場合は、最後の指標が継続して用いられる

といったところでしょうか。Cloud Monitoringの設定がちょっとややこしいですね。

ベンダー依存のテクニックなので、ちょっと調べて理解できる範囲に使用は留めておいて、あまり深追いはしないでおこうと思います。

関連カテゴリー記事

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com