Kubernetesクラスタ故障からの学習の最大化


This article was originally written for my personal blog


数ヶ月後からNU.nl 開発チームは少数のkubernetesクラスタを操作する.我々は、Kubernetesの可能性を見て、それがどのように我々の生産性を増やすことができて、それが我々のCI/CD実行をどのように改善することができるかについて見ます.現在、我々は、我々が知識と信頼を構築したならば、我々が我々のロギングとビルディングツールセットの一部をKubernetesに加えて、いくつかの小さな(内部の)顧客に面した労働負担を加えます.
最近我々のチームはクラスタの一つにいくつかの問題に直面した.クラスタを完全に下ろすのと同じくらい重くはありませんが、確かに、いくつかの内部的に使用されるツールやダッシュボードのユーザーエクスペリエンスに影響を与えます.
偶然、私はミュンヘンのデヴォプスコン2018を訪れました"Staying Alive: Patterns for Failure Management from the Bottom of the Ocean" この事件に非常によく関連している.
話(エンジニアリングマネージャー)は、失敗を防止して、処理するのに、Devopsチームをより効果的にするいろいろな方法に集中しました.対処される話題の1つは、破局が通常失敗のカスケードによって引き起こされる方法でした.

A post-mortem that blames an incident only on the root cause, might only cover ~15% of the issues that led up to the incident.


このようにthis list of postmortem templates , それらの多くは'根本原因(s)'(複数)を含んでいます.それにもかかわらず、イベントのチェーンは簡単に見落とされることができます、特に状況の多くのように、根の原因を取り除くか、固定することは問題を去ります.
それで、失敗のカスケードが我々の事件につながって、我々の学習を最大にするのを見ましょう.

事件


我々のチームは、不規則なふるまいを示している多くのサービスの報告を受けました:時々のエラーページ、遅い反応とタイムアウト.
Grafanaを通して調査しようとして、我々はGrafanaとPrometheusに影響を及ぼしている類似したふるまいを経験しました.コンソールからクラスタを調べました.
$: kubectl get nodes
NAME                                          STATUS     ROLES     AGE       VERSION
ip-10-150-34-78.eu-west-1.compute.internal    Ready      master    43d       v1.10.6
ip-10-150-35-189.eu-west-1.compute.internal   Ready      node      2h        v1.10.6
ip-10-150-36-156.eu-west-1.compute.internal   Ready      node      2h        v1.10.6
ip-10-150-37-179.eu-west-1.compute.internal   NotReady   node      2h        v1.10.6
ip-10-150-37-37.eu-west-1.compute.internal    Ready      master    43d       v1.10.6
ip-10-150-38-190.eu-west-1.compute.internal   Ready      node      4h        v1.10.6
ip-10-150-39-21.eu-west-1.compute.internal    NotReady   node      2h        v1.10.6
ip-10-150-39-64.eu-west-1.compute.internal    Ready      master    43d       v1.10.6
NotReady , 良い.様々なノードを記述します(不健康なものだけでなく)
$: kubectl describe node ip-10-150-36-156.eu-west-1.compute.internal

<truncated>

Events:
  Type     Reason                   Age                From                                                     Message
  ----     ------                   ----               ----                                                     -------
  Normal   Starting                 36m                kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Starting kubelet.
  Normal   NodeHasSufficientDisk    36m (x2 over 36m)  kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeHasSufficientDisk
  Normal   NodeHasSufficientMemory  36m (x2 over 36m)  kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeHasSufficientMemory
  Normal   NodeHasNoDiskPressure    36m (x2 over 36m)  kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeHasNoDiskPressure
  Normal   NodeHasSufficientPID     36m                kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeHasSufficientPID
  Normal   NodeNotReady             36m                kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeNotReady
  Warning  SystemOOM                36m (x4 over 36m)  kubelet, ip-10-150-36-156.eu-west-1.compute.internal     System OOM encountered
  Normal   NodeAllocatableEnforced  36m                kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Updated Node Allocatable limit across pods
  Normal   Starting                 36m                kube-proxy, ip-10-150-36-156.eu-west-1.compute.internal  Starting kube-proxy.
  Normal   NodeReady                36m                kubelet, ip-10-150-36-156.eu-west-1.compute.internal     Node ip-10-150-36-156.eu-west-1.compute.internal status is now: NodeReady
それは、ノードのオペレーティングシステムがプロセスを殺す前にkubelet として記憶を取り戻すことができましたdescribed in the Kubernetes docs .
クラスタ内のノードは自動スケーリンググループの一部です.それで、私たちが断続的な停電をして、その時、グラファナに達する問題があったと考えて、我々はNotReady ノードが1つずつ新しいノードが安定したままであるかどうかを確認します.これは、新しいノードが正しく表示されませんでしたが、いくつかの既存のノードまたは新しいノードがすぐにステータスになったNotReady .
しかしながら、プロメテウスとグラファナでは、安定したままのノードで予定されていたので、少なくとも私たちはより多くのデータを分析し、根本的な原因はすぐに明らかになった.

根本原因


One of the dashboards 我々のGrafanaセットアップでは、ポッドメモリとCPU使用のためにグラフ全体の合計だけでなくグラフを示します.これはすぐに我々の問題の原因を示した.

どこにも行こうとしないそれらの線は、すべてのポッドランニングですElastAlert . ログのために、我々はAntiticSearchクラスタを走らせています、そして、最近、我々はログに基づいてアラートを誘発するために、エラストアラートで実験していました.事件の直前に導入された警告の1つは、我々のCloudfront-* インデックスはある期間の間新しいドキュメントを受信しません.そのクラウドフロントディストリビューションのスループットは数百万のリクエスト/時間であるので、これは明らかにメモリ使用量の大きな増加を引き起こしました.後知恵でdigging deeper into documentation , 私たちはよく使用してuse_count_query //max_query_size .

失敗のカスケード


したがって、根本的な原因は、調査、固定された.事件は、右?念頭に置いてからの引用を念頭に置いて、まだ学習の85 %が発見されるので、ダイビングしよう:

警告なし


根本的な原因がエラストアラートに関連していたので、明らかに我々は警告に取り組んでいました.行動するいくつかのデータは、現在のところ、ログメッセージ(キーワードの出現)またはKubernetesクラスタの外側のシステムのような弾性検索で利用可能です.PromeTheusまた、我々はまだ設定する必要があります警告マネージャがあります.それらの2つの源の他に、我々はAPMのために新しい遺物を使います.ソースに関係なく、おそらく収束する必要があります、それは少なくとも定義の警告規則から始まります.
解決
  • CPU、メモリおよびディスクスペースのようなリソース使用に関連するアラートを定義します.
  • 可能性が複数のソースを組み合わせた戦略を警告し続ける研究.
  • クラスタ問題に影響されるGrafanaダッシュボード


    PrometheusとGrafanaはKubernetesクラスタ(いくつかのヘルムチャートをインストールし、あなたはかなりアップして実行している)で設定するのは非常に簡単です.しかし、クラスタに到達できない場合は、ブラインドです.
    解決
  • クラスタの外にメトリクスをエクスポートして、Grafanaをクラスタから動かしてください.これは非常によく説明されているがin this article at robustperception.io . 利点は、複数のクラスタのダッシュボードのための単一の移動をポイントしている可能性があります.私の知る限りKublr 複数のクラスタを監視するための同様のセットアップを使用します.
  • クラスタの位置はEC 2であっても別々のKubernetesクラスタである可能性がある.
  • 完全に我々のエルクスタックから利益を得ない


    私たちはEC 2ベースのエルクスタックを実行しています.また、Kebernetesクラスタからのログとメトリックは、FileBeatとMetricbeatデーモンセットによってエクスポートされます.したがって、クラスタのGrafanaでアクセスできなかったデータは、ELKスタックにも存在しました.しかし、どちらも適切に可視化されなかったか、見落とされました.
    これは一般的にややトリッキーな主題です:1つの手の弾性検索はとにかく中央化されたログのためにとにかく必要になる可能性がありますので、1つの停止のソリューションかもしれないので、メトリックを行うことができます.しかし、スケールではそれは実際に動作するように、オンボードは、より多くの例ダッシュボード(IMO)から恩恵を受けることができます.
    一方、Prometheusは設定するのが簡単です、Kubernetes Ecoシステムのデフォルト技術であり、Grafanaの利用可能なダッシュボードと対になって、非常に簡単に入ることができます.
    解決
  • いずれかのエルクで重要なメトリクスを可視化またはprometheus/grafanaの可用性を向上させる.
  • 改善メトリクス戦略.
  • エラアラートポッド上のCPUとメモリの制限はありません


    エラスティックアラートをインストールするためのヘルムチャートallows specifying resource requests and limits , しかし、これらはデフォルト値(一般的ではない)を持ちません.
    リソース制限の設定を強制するためにconfigured default and limit memory requests for our namespace .
    解決
  • ヘルム値によるリソース制限を指定します.
  • 名前空間の設定によって、メモリ要求のデフォルト値enが制限されます.
  • 顧客が直面する作業負荷に影響するOPSサービス


    顧客のワークロードおよび監視/ロギングツールは、同じリソースセットを共有するすべてのリソースを消費する増幅効果のリスクがあります.増加したトラフィックは、増加したCPU/メモリの圧力を引き起こし、より多くのCPU/メモリの圧力などを引き起こし、より多くのログ/メトリックボリュームを引き起こします.
    我々はすでに、すべてのログ記録、監視、CI/CDツーリングを生産クラスタ内の専用のノードグループに移動する予定でした.私たちの経験に応じて、専用の'ツール'クラスタを持つオプションもあります.
    決議案(既に計画されている)
  • ビルド、ログ&監視作業負荷から顧客に直面するワークロードを分離します.
  • 展開されたエラストアラート変更のチームに対する認識はありません


    新しい警告がコードレビューを通過したけれども、それが合併されて、配備されたという事実は皆に知られていませんでした.さらに重要なことは、チームメンバーの1つによってコマンドラインを介してインストールされていたため、クラスタ内のどのようなアプリケーションが更新されているかを示す情報源はなかった.
    解決
  • オートメーションによってすべてを展開する
  • Aを考えるGitOps 新しいアプリケーションのバージョンを展開するためのアプローチ:開発者によってよく知られているツールを使用して、“状態にする”とコードの変更の歴史.
  • いいえ煙テスト


    我々がパイプラインを使用しているエラストアラートアップデートを配備したならば、我々は配備の後に『煙テスト』ステップを加えたかもしれません.これは、メモリ不足やメモリの制限を超えたPODのためのPOD再起動を引き起こす可能性があります.
    解決
  • 煙テストステップを含むパイプラインを介して展開します.
  • チームの一部に制限されたKubernetesの操作に関する知識


    私たちのチーム(ほとんどのチームとして)さまざまなトピックの専門知識の様々なレベルの人々から成ります.いくつかの雲とデップの経験を持って、いくつかのフロントエンドやDJango専門家などは、Kubernetesは全く新しい技術であり、確かに私たちのチームのために、知識は普及しているように普及していない.アジャイルチームによって実践されたすべての技術と同様に:devopsは、単一の(一部の)チームに限定されるべきではありません.幸いにも経験豊富なチームメンバーはインフラストラクチャ経験がほとんどなかったオンラインティームメンバーを支援するために利用できました.
    決議案(既に計画されている)
  • Kubernetes関連の仕事(一般的に関連した雲インフラストラクチャ)を確実にすることはチーム・スプリントの一部であり、より経験豊富なメンバーとのペアで、すべてのチームメンバーによって拾われます.
  • ワークショップ深い特定のトピックにダイビング.
  • 包む


    明らかになるように、エラストアラート問題自体を修正することは氷山の一角だけでした.この一見単純な事件から学ぶことは、もっとたくさんありました.この記事に記載されているほとんどのポイントは、すでに我々のレーダーの上にありました、しかし、彼らの重要性は強調されました.
    スクラム(またはカンバン)のアイテムにこれらの学習を回すと、集中的な方法で私たちのプラットフォームとプラクティスを改善し、我々の進歩を測定することができます.
    チームとしての学習と改善は「やかましいポストmortems」を許す会社文化を必要として、単に「事件の数」または「解決する時間」に集中しないだけです.引用を終えるheard at a DevOps conference :

    Success consists of going from failure to failure without loss of enthusiasm - Winston Churchill