Utilizing and monitoring kubernetes cluster resources more effectively

kubernetes クラスターリソースの効率的な使用と監視

gavin.zhou
Orangesys
9 min readMar 28, 2019

--

kubernetes向けリソース使うと監視の記事を読みました。やはり、kubernetes向け監視とリソースの使うなら、prometheus + grafanaが標準仕様となる感じだった。参考になりますから、和訳しました。

私はKube Eagleを作りました。これは小~中くらいのサイズのクラスターの中で、クラスターのリソースをより視覚化できるようにした優れたツールを提供するprometheus exporterです。最適なマシンタイプを使うこと、そして私のアプリケーションのリソースの制限を微調整することでついに、数百ドルも節約できました。ようやく私のワークロード.に適切なものになったのです。

kube eagleの特性をより詳しく見ていく前に、使用例とよりよいモニタリングのためになぜそれが必要かということを説明させてください。

https://github.com/google-cloud-tools/kube-eagle

私はそれぞれ4~50ほどのノードを持つ多様なクラスターの管理を担当していました。最大200ほどのクラスターの中で走っている様々なマイクロサービスとアプリケーションが存在し、利用可能なハードウェア リソースをより効率的にユーティライズするために、大部分のデプロイメントはburstable RAMとCPUリソースを伴ってコンフィグされます。もしポッドが利用可能なリソースが必要なのであれば、このようにポッドはそのリソースを取得するかもしれません。しかし、それらはそのノード上にあるスケジュール化されることから他のアプリケーションをブロックすることはありません。素晴らしいと思いませんか?

私たちの全体的なクラスターCPU(8%)とRAM利用(40%)は比較的低かったのです。私たちはよく排除されたポッドに関する問題に直面します。それらのポッドはノード上の利用可能なRAM以上のものを配分しようとしていたからです。その時は、kubernetesのリソースをモニターするための一つのダッシュボードしか持っていませんでした。そしてそれはこのように見えます。

cAdvisorメトリックのみを使用したGrafana dashboard

ダッシュボードのようなものを使うことで、簡単に高いRAMとCPU使用のノードを見つけることができます。そして、すぐに過剰にユーティライズしたノードを認識することができます。言うまでもなく、あなたが排除されたポッドの原因を解決しようとするときが本当に大変なのです。その排除を避ける一つの選択肢としては、全てのポッド上の(リクエストと制限のあるリソースはイコールです)保証されたリソースをセットすることです。その欠点は、ハードウェアのユーティライゼーションをより悪くしてしまうということです。クラスター幅の数百ものギガバイトのRAMが利用可能なのですが、他のノードがまだ4~10GBの無料RAMも残っている一方で、あるノードは一見RAM不足になっています。

表面上はkubernetesスケジューラーは自分たちのワークロードをスケジュールしていないように見えます。そのため、利用可能なリソース全体に分散されるのです。kubernetesスケジューラーは色々なコンフィギュレーションに注意をしておかなければいけません。例えば、アフィニティー・ルール、taintsとtolerations(”汚れ”を”容認”できるならscheduleできる仕組み)、ノードの選択などですが、これらは利用可能なノードのセットに制限をかけます。私の場合そういったコンフィギュレーションはありませんでした。もしそのような場合であれば、ポッドのスケジューリングはそれぞれのノード上でリクエストされたリソースを基本としたものになります。

もっともアンリザーブド(リザーブされていない)リソースを持つノードと安全にリクエストされたリソースの状態はポッドを走らせるために選択されるでしょう。私たちの場合であれば、こえはノード上のそのリクエストされたリソースが、実際の利用と調和することはないということを意味します。そのリソースが、この目的のためによりよいリソースモニタリングを提供するときにKube Eagleが保護する場所であるということです。

・ ・ ・

私が取り扱ってきたほとんどのKubernetesクラスターはクラスターをモニタリングするためにノード エクスポーターKube State メトリックをただ走らせているだけでした。ノードエクスポーターがディスク使用状況についてのメトリック、IO状態、CPU & RAMの使用状況、Kubernetes オブジェクトについてのメトリックをエクスポーズするkube stateエクスポーター、リクエストされ、そして制限をかけたCPU / RAMリソースのようなメトリックについても報告してくれます。

私たちは私たちの取り組む問題に関する本当に価値のある情報を得るためにGrafanaの中にあるリソースリクエストと制限メトリックを伴うUsage Metrics (利用状況総計値)を集計する必要があります。この与えられた2つのツールを使うことで、悲しいことに思っているよりやっかいなことになります。というのもそのラベルが異なる名前になってしまうからです。そして、いくつかのメトリックはそれらを簡単に収集するためにメタデータラベルが不足しているということになります。Kube Eagleはそれをあなたの代わりに行います。そして、これこそがそのメトリックを基本として生成された提案されたダッシュボードなのです。

Kube Eagle Dashboard (https://grafana.com/dashboards/9871)

私たちはリソースを伴うあらゆる問題を認識し、解決することができました。そしてそれは最終的には多くのハードウェアリソースを節約できることにつながります。

1.それらのマイクロサービスをデプロイしたデベロッパーはそれらのサービスが実際どれくらいのリソースが必要かということが分かりませんでした。(もしくはそういうことにあまり注目していなかっただけかもしれません) 簡単に間違ってコンフィギュアされたリソースリクエストを認識するモニタリングを適当な場所に持っていませんでした。というのもこれには、リソースリクエストと制限を伴った利用状況を見る必要があるからです。今、デベロッパーは新しく提供されたprometheusメトリックを使用できます。このメトリックで実際の利用状況とリソースリクエストと制限を受け入れることができます。

2.JVMアプリケーションできる限り多くのRAMを取得します。もし75%以上RAMが利用中なのであれば、ガベージコレクタはメモリーをリリースするだけです。ほとんどのサービスはRAMの中ではburstableでした。そしてそれはいつもJMVが消費します。このように私たちは全てのJavaサービス上では思ったより高いRAMの使用状況だったのです。

3.Kubernetesスケジューラーがすべての他のアプリケーションのためのノードを飛ばしてしまうくらい大きすぎるRAMを持っているアプリケーションもあります。実際の使用状況は他の全てのノードよりも低かったとしてもです。その大きなRAMリクエストは、バイトの中でのリソースリクエストに特化していて、うっかり他の数値を加えてしまったデベロッパーが起こすものなのです。2Gb RAMの代わりに20Gb RAMはずっとリクエストをされていて、誰もそれに気が付きません。そのアプリケーションには3つの返信が来ていて、このように3つの異なるノードは割り当て超過によって影響を受けています。

4.このリソース制限を受け入れ、適切なリクエストを伴ったポッドを再スケジューリングした後、全体のノードにおいて完璧にバランスの取れたハードウェアのユーティライゼーションを達成しました。私たちはそのおかげで、数個のノードをシャットダウンできたということに気が付きました。それから、間違ったマシンタイプ(高いメモリを持つマシンではなくCPUが最適化されたマシン)を使っていたことに気が付いたのです。マシンタイプを変更してからは、再びより多くのノードを排除することができるようになりました。

Summary:まとめ

利用可能なハードウェアのユーティライゼーションのメリットをより効率的にしてくれるクラスターの中でのburstableリソースのコンフィギュレーションですが、それはまたkubernetesスケジューラーがリソースリクエストを基本としたポッドスケジューリングをする際には色々な問題を引き起こす可能性もあります。問題にぶつかることなくより優れたキャパシティーのユーティライゼーションを実現するために、しっかりとしたモニタリング対策をすべきです。Kube Eagle (prometheus エクスポーターと grafanaダッシュボード)はこれを目標に今まで生成されてきています。そしてこの課題に取り組む皆さんをサポートしています。

Orangesys.ioでは、kuberneteの運用、DevOps、監視のお手伝いをさせていただいています。ぜひ私たちにおまかせください。

--

--