本文の内容は、2020年7月9日に Jorge Salamero Sanzが投稿したブログ(https://sysdig.com/blog/alerting-kubernetes/)を元に日本語に翻訳・再構成した内容となっております。
Kubernetesプラットフォームとオーケストレーションでのアラートのベストプラクティスに関するステップバイステップのクックブックです。PromQLアラートの例も含みます。
Kubernetesとモニタリングを初めて使用する場合は、最初に本番環境でのKubernetesの監視をお読みになることをおすすめします。ここでは、監視の基礎とオープンソースツールについて説明しています。
効果的なアラートは監視戦略の基盤にあります。当然、オーケストレーションされたコンテナ環境とKubernetesへの移行に伴い、アラート戦略も進化する必要があります。
これは、いくつかの主要な理由によるものです。その多くは、kubernetesを監視する方法で説明しました。
新しいインフラストラクチャーレイヤー:サービスとホストの間に、コンテナとコンテナオーケストレーターという新しいレイヤーができました。これらは監視する必要のある新しい内部サービスであり、アラートシステムはそれらを認識する必要があります。
マイクロサービスのアーキテクチャ:コンテナは、以前のサービスのようにノードと結合されていないため、従来のモニタリングは効果的に機能しません。実行中のサービスインスタンスの静的な数はありません(カナリアデプロイや自動スケーリングのセットアップを考えてください)。プロセスがインフラストラクチャー内の別の場所で再スケジュールされている可能性があるため、1つのノードでプロセスが強制終了されていても問題ありません。
新しいスケールと集約の要件:サービスが複数のコンテナに分散し、それらすべてのモニタリングシステムレベルとサービス固有のメトリクスに加えて、Kubernetesがもたらすすべての新しいサービスを使用して、モニタリングおよびアラートシステムはこれらのメトリクスすべてを大規模に取り込むことができるのでしょうか? また、さまざまな視点からメトリクスを確認する必要があります。メトリクスにKubernetesに存在するさまざまなラベルを自動的にタグ付けし、監視システムがKubernetesメタデータを理解している場合、各状況で必要に応じてメトリクスを集計またはセグメント化できます。
視認性の欠如:コンテナはブラックボックスです。従来のツールは、パブリックモニタリングエンドポイントに対してのみチェックできます。問題のサービスを深く監視する場合は、コンテナ内で何が起こっているのかを確認できる必要があります。
これらの問題を念頭に置いて、Kubernetes環境に関するアラートのベストプラクティスを見ていきましょう。Kubernetesアラートチュートリアルでは、次の内容を取り上げます。
最初に、オンコールローテーションの効率とメンタルヘルスを改善するために、アラートを送信するときに守るべき一連の基本ルールをまとめます。
ホストレイヤーでのアラートは、クラウドインスタンス、VM、またはベアメタルサーバーの監視と大きく異なるべきではありません。ほとんどの場合、ホストがアップまたはダウン/到達不能であり、リソースの可用性(CPU、メモリ、ディスクなど)が問題になります。
主な違いは、アラートの重大度です。以前は、システムのダウンは、おそらくアプリケーションのダウンと処理するインシデントがあったことを意味していました(効果的な高可用性を排除)。Kubernetesを使用すると、サービスをホスト間で移動できるようになり、アプリを実行するのに十分なサービスがある限り、ホストアラートでベッドから目覚めることはありません。死んだホストが、あるはずの新しいホストに交換されていることを確認する必要があるだけです。
まだ考慮すべきいくつかのオプションを見てみましょう。
ホストがダウンしているか到達できない場合は、通知を受け取ることができます。この単一のアラートをインフラストラクチャー全体に適用します。私たちの場合、ネットワーク接続の問題で騒々しいアラートを表示したくないので、5分の待機時間を与えます。通知を受信したい速さによっては、この値を1〜2分に減らすこともできますが、通知がフラッピングする可能性があります(頻繁にアップ、ダウンします)。
このドキュメントの後半では、オーケストレーションに高可用性システムとして機能する別のレイヤーがあるため、1つのノードの障害はそれほど重要ではないことがわかります。とにかく、アクティブなノードが負荷を処理できることを確認できるように、実行中の負荷を参照して、残りのノード数を監視する必要があります。さらに、別のノードの障害がすべてのワークロードを実行するためのリソースの不足を引き起こす瞬間に注意する必要があります。
これは少し複雑なアラートです。このアラートは、インフラストラクチャー全体のすべてのファイルシステムに適用できます。あらゆる場所でスコープとして設定し、マウント(Sysdig fs.mountDir内)ごとに個別の評価/アラートを発行することに成功しました。
これは80%を超える使用率をトリガーする一般的なアラートですが、95%などの高いしきい値を持つ2番目の優先度の高いアラートや、ファイルシステムに応じて異なるしきい値など、異なるポリシーが必要になる場合があります。
異なるサービスまたはホストに異なるしきい値を作成する場合は、スコープを特定のしきい値を適用する場所に変更するだけです。
さらに高度なディスクアラートが必要な場合は、PromQLに追加機能があり、線形予測を実行して、現在のレートでディスクがどれだけ速く満たされているかを確認できます。
PromQLクエリー:
(predict_linear(node_filesystem_free{job="node"}[1h],43200 )) < 0
このアラートは、現在の速度で12時間以内にディスクがいっぱいになる場合にトリガーされます。
このカテゴリのいつもの容疑者は、負荷、CPU使用率、メモリ、スワップ使用率に関するアラートです。おそらく、通知を送信する必要がありますが、長時間の間にこれらのいずれかが著しく高い場合は、誰かを起こさないでください。しきい値、待機時間、アクション可能なアラートがなくアラートシステムがどの程度うるさくなるかの間で妥協点を見つける必要があります。
これらのリソースのメトリクスをセットアップする場合は、Sysdigモニターで以下のメトリクス名を確認してください。
このカテゴリには、インフラストラクチャーの一部であるクラウドプロバイダーリソースのモニタリングも含まれます。
コンテナオーケストレーションレベルでの監視とアラートは2つあります。一方では、Kubernetesによって処理されるサービスが定義した要件を満たしているかどうかを監視する必要があります。一方、Kubernetesのすべてのコンポーネントが稼働していることを確認する必要があります。
etcdは、Kubernetesの分散サービスディスカバリ、コミュニケーションコマンドチャネルです。etcdの監視は、分散キー値データベースの監視と同じくらい深く行うことができますが、ここでは簡単に説明します。etcdは、構成されたインスタンスの半分以上が実行されている場合に機能するので、これをアラートしましょう。
PromQLクエリー:
count(up{job="etcd"} == 0) > (count(up{job="etcd"} == 0) / 2 - 1)
Kubernetes APIサーバーは、Kubernetesコントロールプレーンの中心です。繰り返しになりますが、このサービスの監視はそれ自体が仕事であり、「Kubernetes APIサーバーを監視する方法」で詳しく説明しています。とりあえず、サービスがダウンした場合のアラートを設定しましょう。
PromQLクエリー:
(absent(up{job="kube-apiserver"})) == 1
Kubeletは、Kubernetesのコントロールプレーン内の非常に重要なサービスです。ノード内のポッドによって記述されたコンテナを実行するのはこのコンポーネントなので、これをゴールデンシグナルで通知し、ポッドのスタートレートと継続時間を確認できます。ここでの長い待機時間は、コンテナランタイムのパフォーマンスの低下、またはコンテナイメージへのアクセスを試みる際の追加の問題を示している可能性があります。Kubeletの監視方法については、Kubeletをモニタリングする方法をご覧ください。
PromQLクエリー:
(histogram_quantile(0.99,sum(rate(kubelet_pod_worker_duration_seconds_bucket{job="kubelet"}[5m])) by (instance,le)) * on(instance) group_left(node) kubelet_node_name ) > 60
スケジューラーはコンテナを障害が発生したノードのポッドから他の使用可能なノードに生成するため、ノードの障害はKubernetesの問題ではありません。しかし、ノードが不足している場合はどうなりますか?デプロイされたアプリケーションのリソース要件が既存のノードをオーバーブッキングした場合はどうなりますか?クウォータリミットに達していますか?
これらの場合のアラートは、スタンバイにしたいノードの数、または既存のノードにオーバーサブスクリプションをプッシュする距離に依存するため、簡単ではありません。ノードのステータスを監視するには、メトリクスkube_node_status_readyおよびkube_node_spec_unschedulableでアラートを出します。
この例は、この式です。これは、ノードの1つに障害が発生した場合に、要求されたすべてのリソースの合計がクラスターのキャパシティよりも大きい場合にアラートがトリガーされることを意味します。
sum(namespace:kube_pod_container_resource_requests_cpu_cores:sum) / sum(node:node_num_cpu:sum) >
(count(node:node_num_cpu:sum)-1) / count(node:node_num_cpu:sum)
キャパシティについてアラートを発行する場合は、CPUとメモリのスケジュールされた各ポッド要求を合計し、それが各ノードkube_node_status_capacity_cpu_coresおよびkube_node_status_capacity_memory_bytesを超えないことを確認する必要があります。
たとえば、次のクエリーは、リクエストされたリソースが使用可能な割り当ての90%を超えた場合にアラートを出します。
100 * kube_resourcequota{job="kubernetes-service-endpoints", type="used"} / ignoring(instance, job, type) (kube_resourcequota{job="kubernetes-service-endpoints", type="hard"} > 0)
> 90
サービスレベルを見ると、すでにサービスをクラスタリングしている場合は、Kubernetesの前に行っていたものとそれほど変わらないはずです。MySQL/MariaDBやMongoDBなどのデータベースについて考えてみましょう。レプリケーションのステータスと遅延を確認できます。それでは、今考慮すべきことはありますか?
はい!サービスがどのように動作し、グローバルに実行されるかを知りたい場合は、モニタリングツールの機能を活用して、コンテナのメタデータに基づいてメトリクスの集計とセグメンテーションを行う必要があります。
「Kubernetes を監視する方法」で説明したように、Kubernetesはデプロイメント内のコンテナにタグを付けるか、サービスを通じて公開されています。ここで、アラートを定義するときにそれを考慮する必要があります。たとえば、運用環境のみのスコープアラートは、おそらくネームスペースによって定義されます。
Kubernetesには、複数のポッドを持つアプリケーションを処理するためのいくつかのオプションがあります。Deployment、ReplicaSets、ReplicationControllersです。それらの違いはほとんどありませんが、3つを使用して、同じアプリケーションを実行する多数のインスタンスを維持できます。そこで、スケールアップとスケールダウンを行うと、実行中のインスタンスの数を動的に変更でき、このプロセスは自動スケーリングで自動化することもできます。
実行中のコンテナの数が変化する理由はいくつかあります。これには、ノードに障害が発生したため、または十分なリソースがなく、ポッドが強制排除されたために別のホストでコンテナを再スケジュールすることも含まれます(詳しくは、Kubernetes pod evictedとスケジューリングの問題を理解する)、新しいバージョンのローリングデプロイメントなど。
長期間実行されているレプリカまたはインスタンスの数が、希望するレプリカの数よりも少ない場合は、何かが適切に機能していない(ノードまたはリソースが不足している、KubernetesまたはDocker Engineの障害、Dockerイメージが破損している)の症状など)。
このようなアラート:
kube_deployment_spec_replicas{job="kubernetes-service-endpoints"}
!= kube_deployment_status_replicas_available{job="kubernetes-service-endpoints"}
これはすべてのサービスで比較され、Kubernetesアラート設定ではほぼ必須です。前に述べたように、この状況はコンテナの再スケジュールおよび移行中に許容される.spec.minReadySecondsため、各コンテナの構成済みの値(コンテナの開始から準備完了状況で使用可能になるまでの時間)に注意してください。また.spec.strategy.rollingUpdate.maxUnavailable、ローリングデプロイメント中にオフラインにすることができるコンテナの数を定義するものを確認することもできます。
以下は、名前がのクラスターwordpress-wordpress内のwordpressネームスペース内のデプロイメントにこの条件が適用されたアラートの例kubernetes-devです。
前のアラートと同様ですが、優先度が高くなっています(たとえば、これは深夜にページングされる候補です)、特定のアプリケーションでコンテナが実行されていない場合にアラートを出します。
次の例では、同じデプロイメントにアラートを適用しますが、実行中のポッドが1分間に1未満の場合にトリガーします。
壊れた新しいバージョンをデプロイするときに、十分なリソースが利用できない場合や、一部の要件や依存関係が整っていない場合、コンテナまたはポッドがループで継続的に再起動する可能性があります。これはCrashLoopBackOffと呼ばれます。これが発生すると、ポッドは準備完了ステータスにならず、実行不可としてカウントされるため、このシナリオはすでにアラートによってキャプチャーされています。それでも、インフラストラクチャー全体でこの動作をキャッチし、特定の問題をすぐに知らせるアラートを設定したいと思います。それはあなたの睡眠を妨げる種類のアラートではなく、有用な情報を提供するものです。
これは、過去2分間に4回を超える再起動を検出したインフラストラクチャー全体に適用された例です。
アプリケーションが期待どおりに動作することを確認できるメトリクスは、ワーキングメトリクスまたはゴールデンシグナルと呼ばれます。これらのメトリクスを生成するには、通常、Prometheusメトリクス、statsd、またはJMXを介してアプリケーションをインストルメント化する必要があります。
このカテゴリでよく見られるメトリクスとアラートは次のとおりです。
次の例は、Prometheusカスタムメトリクスを使用して、本番のネームスペース prodのJavaアプリデプロイメントで、10分のウィンドウで10秒間のレイテンシーを監視するパブリックREST APIエンドポイントのアラートです。
PromQLクエリー:
histogram_quantile(0.95,sum(rate(http_request_duration_seconds_bucket{code=~"20+",kubernetes_namespace="prod",app="javaapp"}[5m])) by (le)) > 10
コンテナオーケストレーションプラットフォームを使用して、システム内を移動する部分の数を増やす方法を見てきました。Kubernetesのコンテナネイティブのモニタリングとアラートを設定することは、信頼性の高いインフラストラクチャーを構築するための重要な要素です。
Kubernetesのアラート戦略は、インフラストラクチャーレイヤーだけに焦点を当てるのではなく、アプリケーションのワークロードとそのメトリクスが存在する、ホストとKubernetesノードの下部から上部までのスタック全体を理解する必要があります。Kubernetesとクラウドプロバイダーのメタデータを活用してメトリクスとアラートを集約およびセグメント化できることは、すべてのレイヤーにわたって効果的なアラートを行うための要件です。
Sysdigアラート機能は、使いやすいアラートエディターとPromQLのすべての機能を組み合わせて、計算されたメトリクスと数学関数を使用して高度なアラートを作成します。Sysdig Monitorを使用すると、DevOpsチームは、大規模なPrometheusモニタリングを活用して、Kubernetes環境を監視およびアラートを生成できます。
しかし、まだ終わっていません。フォローアップの推奨事項は多数あり、Kubernetes Monitoring Fundamentalsガイドで詳細を確認することをお勧めします。
Sysdigをまだテストしていませんか?今すぐ無料トライアルにサインアップしてください!