コストが最適化された Kubernetes アプリケーションを GKE で実行するためのベスト プラクティス

このドキュメントでは、Google Cloud に備えられた柔軟性を活用するため、コストが最適化されたアプリケーションを GKE で実行するための Google Kubernetes Engine(GKE)の機能、オプション、ベスト プラクティスについて説明します。このドキュメントは、Kubernetes、Google Cloud、GKE、自動スケーリングを十分に理解していることを前提としています。

はじめに

Kubernetes の普及に伴い、ワークロードにマルチテナント Kubernetes クラスタを使用する企業、Platform-as-a-Service(PaaS)プロバイダ、Software as a Service(SaaS)プロバイダが増えています。これは、1 つのクラスタで、さまざまなチーム、部門、顧客、環境に属するアプリケーションを実行できることを意味します。Kubernetes で提供されるマルチテナンシーを使用すると、企業は複数の小規模なクラスタではなく、少数の大規模なクラスタを管理できるようになり、適切なリソースの使用、管理の簡素化、断片化の減少などのメリットが得られます。

時間が経つにつれて、Kubernetes クラスタが急速に拡大している企業の中には、コストの大幅な増加を経験することがあります。これは、Kubernetes のようなクラウドベースのソリューションを採用している従来型の企業の中に、クラウドの専門知識を持つ開発者や運用担当者がいないことが原因となって起こります。このようなクラウドの readiness が不足している場合、アプリケーションが自動スケーリング中に不安定になる(たとえば、1 日の中の定期的な時間帯でトラフィックが不安定になる)こと、または突然のバーストや急激な増加(テレビ コマーシャルや、ブラック フライデーやサイバー マンデーなど、記録的なスケールのイベントなど)につながります。この問題の「修正」を試みるとき、こうした企業では、柔軟性に欠ける環境で、今まで通りのやり方を使用してクラスタを過剰にプロビジョニングする傾向があります。過剰にプロビジョニングすると、アプリケーションで使用される CPU とメモリ割り当てが、1 日のほとんどの時間帯で大幅に増加します。

このドキュメントでは、GKE でコスト最適化された Kubernetes ワークロードを実行するためのベスト プラクティスについて説明します。次の図に、この方法の概要を示します。

費用に応じて Kubernetes アプリケーションを最適化する方法。

コストが最適化されたアプリケーションを構築するための基本は、チーム間にコスト削減の文化を広めることです。この方法では、コストについての検討を開発プロセスの始めに行うだけでなく、アプリケーションが実行されている環境(ここでは GKE 環境)をよく理解する必要があります。

低コストで安定したアプリケーションを実現するには、自動スケーリング、マシンタイプ、リージョンの選択など、いくつかの機能と構成を正しく設定または調整する必要があります。また、ワークロードの種類についても検討が必要です。ワークロードの種類とアプリケーションの要件によっては、コストをさらに削減するために、別の構成が必要になることがあります。最後に、開発サイクルの早い段階でベスト プラクティスを実施できるように、費用のモニタリングとガードレールの作成を行う必要があります。

次の表は、GKE が解決をサポートする課題をまとめたものです。ドキュメント全体をお読みになることをおすすめしますが、この表に全体の内容の概要を示しています。

課題 アクション
GKE で簡単に費用を削減したい。 適切なリージョンを選択し、確約利用割引を申し込みE2 マシンタイプを使用します。
GKE の費用について理解する必要がある。 GKE クラスタを観察し、推奨事項を確認して、GKE 使用状況測定を有効化します。
既存のワークロードで GKE の弾力性を最大限に利用したい。 HorizontalPodAutoscalerクラスタ オートスケーラーを確認し、オートスケーラーとオーバープロビジョニングのベスト プラクティスを理解します。
最も効率的なマシンタイプを使用したい。 ワークロードに適切なマシンタイプを選択します。
クラスタ内の多くのノードがアイドル状態になる。 クラスタ オートスケーラーのベスト プラクティスを確認します。
バッチジョブのコスト削減を強化する必要がある。 バッチ ワークロードのベスト プラクティスを確認します。
サービス ワークロードのコスト削減を強化する必要がある。 サービス ワークロードのベスト プラクティスを確認します。
Pod のリソース リクエストのサイジング方法がわかりません。 VerticalPodAutoscaler(VPA)を使用しますが、HorizontalPodAutoscaler(HPA)と VPA の組み合わせのベスト プラクティスに注意してください。
自動スケーリングやメンテナンス アクティビティ中にアプリケーションが不安定になる。 Kubernetes 用のクラウドベースのアプリケーションを用意して、Metrics Server の仕組みとモニタリング方法を理解します。
アプリケーションのリソース使用量に開発者の注意を向けるにはどうすればよいですか? コスト削減の文化を広めGKE Enterprise Policy Controller の使用を検討し、コスト節約手法を適用するための CI/CD パイプラインを設計して、Kubernetes リソース割り当てを使用します
エコシステムのコストをさらに削減するには、他にどのようなことを考慮する必要がありますか? 小規模な開発クラスタを確認し、ロギングとモニタリングの戦略を確認して、リージョン クラスタとマルチゾーン クラスタにおけるリージョン間の下り(外向き)トラフィックを確認します。

GKE のコスト最適化機能とオプション

コストが最適化された Kubernetes アプリケーションは、GKE の自動スケーリングに大きく依存します。GKE での費用、信頼性、スケーリングのパフォーマンスのバランスをとるには、自動スケーリングの仕組みとどのような選択肢があるのかを理解する必要があります。このセクションでは、GKE 自動スケーリングと、サービス ワークロードとバッチ ワークロードの両方に役立つ、その他のコスト最適化の構成について説明します。

GKE 自動スケーリングを微調整する

自動スケーリングは、Google Cloud のお客様がインフラストラクチャの稼働時間を最小化することによって、必要なインフラストラクチャに対してのみ料金を支払うようにするために GKE が使用するものです。つまり、自動スケーリングでは、1)ワークロードとその基盤となるインフラストラクチャが需要の増加前に開始され、2)需要が落ちた場合はシャットダウンすることで、コストを節約します。

次の図に、このコンセプトを示します。Kubernetes では、ワークロードは Pod 内で実行されるコンテナ化されたアプリケーションであり、一連のノードで構成される基盤となるインフラストラクチャは、ワークロードを実行するために十分なコンピューティング能力を提供する必要があります。

自動スケーリングでは、1)ワークロードとその基盤となるインフラストラクチャを需要が増加する前に開始し、2)需要が落ちたときにシャットダウンすることにより、コストを削減します。

次の図に示すように、この環境ではスケーラビリティの次元が 4 つあります。ワークロードとインフラストラクチャは、Pod や Node の追加と削除によって水平スケーリングが可能であり、Pod や Node のサイズを増減することで垂直にスケーリングできます。

コストが最適化された環境の 4 つのスケーラビリティ ディメンション。

GKE では、次のような機能を使用してこれらの自動スケーリングのシナリオを処理します。

次の図に、こうしたシナリオを示します。

HPA、VPA、CA、およびノードの自動プロビジョニングのシナリオを使用する。

以降、このセクションでは、GKE の自動スケーリング機能の詳細と、サービス ワークロードとバッチ ワークロードの両方に役立つその他のコスト最適化構成について説明します。

HorizontalPodAutoscaler

HorizontalPodAutoscaler(HPA)は、負荷を表す指標に基づいて Pod で実行されるアプリケーションのスケーリングを目的としています。CPU 使用率またはその他のカスタム指標(1 秒あたりのリクエスト数など)のいずれかを構成できます。つまり HPA は、Pod のレプリカの追加と削除を行い、使用量の急増に対応するためにすばやく起動でき、ワークロードの不安定性を回避するために正常にシャットダウンできるステートレス ワーカーに最適です。

HPA のターゲット使用率のしきい値を使用すると、スケーリングを自動的にトリガーするタイミングをカスタマイズできます。

上の図のように、HPA では使用率のしきい値をパーセンテージで指定する必要があります。これにより、スケーリングを自動的にトリガーするタイミングをカスタマイズできます。この例で、ターゲット CPU 使用率は 70% です。つまり、新しいレプリカが起動している間、ワークロードはリクエストの処理に 30% の CPU バッファを使用します。バッファのサイズを小さくすると、初期のスケールアップは回避されますが、リクエストの急増でアプリケーションが過負荷状態になる可能性があります。ただし、バッファを大きくするほどリソースが複雑になり、コストが増加します。正確なターゲットはアプリケーションごとに異なります。急増中は 2~3 分間リクエストを処理できるだけのバッファサイズを考慮する必要があります。アプリケーションが数秒で起動することを保証していても、クラスタ オートスケーラーがクラスタに新しいノードを追加する場合や、リソース不足で Pod がスロットリングされる場合は、この時間が長くなります。

アプリケーションで HPA を有効にするためのベスト プラクティスは次のとおりです。

詳細については、HorizontalPodAutoscaler の構成をご覧ください。

VerticalPodAutoscaler

使用量の急増に対して迅速に対応するための Pod の追加と削除を行う HPA とは異なり、VerticalPodAutoscaler(VPA)は、Pod を時系列でモニタリングし、Pod が必要とする CPU とメモリリソースの最適な量を徐々に割り出します。安定性とコスト効率のために、適切なリソースを設定することが重要です。Pod リソースが小さすぎると、アプリケーションがスロットルされるか、メモリ不足エラーのために失敗する可能性があります。リソースが大きすぎると、リソースが無駄に消費され、結果として請求額も大きくなります。VPA は、HPA によって処理されないステートレスとステートフルのワークロードや、適切な Pod リソース リクエストがわからない場合に向いています。

VPA は、Pod が常に上限で動作していることを検出し、より大きなリソースで Pod を再作成します。

前の図に示すように、VPA は、Pod が上限で実行されていることを検出して、大きなリソースで Pod を再作成します。逆に、Pod の使用率が十分に低い場合はスケールダウンが行われます。

VPA は次の 3 つのモードで動作できます。

  • Off: このモードは、レコメンデーション モードとも呼ばれますが、VPA は Pod を変更しません。推奨値は計算され、VPA オブジェクトで詳細を確認できます。
  • Initial: VPA は Pod の作成時にのみリソース リクエストを割り当て、後で変更することはありません。
  • Auto: VPA は Pod のライフサイクル期間中に CPU リクエストとメモリ リクエストを更新します。これは、Pod が削除されて、CPU とメモリが調整された後、新しい Pod が開始されることを意味します。

VPA の使用を考える場合は、VPA による推奨値を取得するための Off モードから始めることをおすすめします。推奨値は、24 時間以上(できれば 1 週間以上)稼働した後に取得するようにします。その後、確信がある場合に限り、Initial モードまたは Auto モードに切り替えることを検討します。

アプリケーションで Initial モードまたは Auto モードのいずれかを使用して VPA を有効にするためのベスト プラクティスは次のとおりです。

Auto モードの使用を検討しているかどうかにかかわらず、次の対応を実施していることも確認してください。

  • トラフィックを受信している間でもアプリケーションを再起動できるようにします。
  • Pod 停止予算(PDB)を追加して、同時に停止できる Pod の数を管理します。

詳細については、垂直 Pod 自動スケーリングの構成をご覧ください。

HPA と VPA の混在

公式の推奨事項では、CPU とメモリのいずれかに VPA と HPA を混在させることはできません。ただし、VPA でレコメンデーション モードを使用している場合や、HPA でカスタム指標(たとえば 1 秒あたりのリクエスト数など)を使用する場合は、それらを安全に混在させることが可能です。VPA と HPA を混在させる場合は、デプロイメントが十分なトラフィックを受信している(つまり、常に HPA の最小レプリカ数を超えて動作している)ことを確認してください。これにより、VPA は Pod のリソースのニーズを把握できます。

VPA の制限事項の詳細については、垂直 Pod 自動スケーリングの制限をご覧ください。

クラスタ オートスケーラー

クラスタ オートスケーラー(CA)は、基盤となるコンピュータ インフラストラクチャのサイズを自動的に変更します。CA は、クラスタ内で実行する場所がなく、十分に活用されていないノードを削除する Pod 用のノードを提供します。CA はインフラストラクチャ コストに合わせて最適化されています。つまり、クラスタ内に 2 つ以上のノードタイプがある場合、CA は特定の需要に適した最も低価格のノードを選択します。

HPA や VPA とは異なり、CA は負荷指標には依存しません。その代わりに、スケジューリング シミュレーションと宣言された Pod リクエストに基づきます。HPA または VPA のいずれかを使用するときは、CA を有効にすることをおすすめします。こうすることで、Pod オートスケーラーが容量の追加が必要と判断した場合に、基盤となるインフラストラクチャを拡張できます。

CA は、トラフィックの急増を処理するためにコンピューティング能力を自動的に追加、削除します。

これらの図に示すように、CA は、トラフィックの急増を処理するためにコンピューティング容量を自動的に追加、削除し、お客様が休んでいるときは費用を節約します。すべてのアプリケーションの Pod 停止予算(PDB)を定義することをおすすめします。PDB が 1 度に停止できるレプリカの数を制御する場合、CA スケールダウン フェーズでは特に重要です。

特定の Pod はオートスケーラーによる再起動ができないため、一時的な中断を発生させた場合、Pod が稼働するノードは削除できません。たとえば、システム Pod(metrics-serverkube-dns など)やローカル ストレージを使用する Pod は再起動されません。ただし、システム Pod に PDB を定義するか、オートスケーラーによる再起動に適したローカル ストレージを使用する Pod の "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" アノテーションを設定することによってこの動作を変更することが可能です。さらに、別のノードプールで再起動できない長時間実行 Pod を実行することを検討します。これにより、他のノードのスケールダウンが中断されないようにします。最後に、ログ内の CA イベントを分析する方法を確認して、特定のスケーリング アクティビティが期待どおりに行われなかった理由を理解します。

ワークロードが不注意によるノードの再起動や処理能力の低下に対して柔軟性がある場合、プリエンプティブル VM を含むクラスタまたはノードプールを作成することによってさらに費用を節約できます。CA が想定どおりに機能するためには、Pod のリソース リクエストが Pod を正常に機能させるために十分な大きさを持つ必要があります。リソース リクエストが小さすぎると、ノードに十分なリソースがない場合があり、実行時に Pod がクラッシュするか問題が発生する可能性があります。

クラスタでクラスタ オートスケーラーを有効化するためのベスト プラクティスの概要を次に示します。

  • HPA または VPA を使用して、ワークロードを自動スケーリングします。
  • 選択した Pod オートスケーラーに記載されているベスト プラクティスに従ってください。
  • 適切なリソース リクエストと上限を設定するか、VPA を使用して、アプリケーションのサイズを適切に設定します。
  • アプリケーションの PDB を定義します。
  • スケールダウンをブロックするシステム Pod に対する PDB を定義します。たとえば、kube-dns。クラスタの一時的な中断を回避するため、レプリカが 1 つしかないシステム Pod(metrics-server など)には PDB を設定しないでください。
  • 有効期間の短い Pod と独立したノードプールで再起動できる Pod を実行します。これにより、実行時間の長い Pod によるスケールダウンがブロックされます。
  • クラスタでアイドル状態のノードを構成することで、オーバープロビジョニングを回避します。そのため、最小容量(多くの企業の場合は夜間)を把握して、その容量をサポートするノードプールの最小ノード数を設定する必要があります。
  • リクエストの急増時、処理するための追加容量が必要な場合は、オートスケーラーとオーバー プロビジョニングで説明している一時停止 Pod を使用します。

詳細については、クラスタの自動スケーリングをご覧ください。

ノードの自動プロビジョニング

ノード自動プロビジョニング(NAP)とは、新しいノードプールを自動的に追加するほか、ユーザーの代わりにノードプールのサイズを管理する、クラスタ オートスケーラーの仕組みのことです。ノードの自動プロビジョニング機能が有効でないと、GKE はユーザーの作成したノードプール セットに含まれるノードだけを新たな対象として扱います。ノード自動プロビジョニング機能を利用すると、GKE では新しいノードプールが自動的に作成および削除されます。

ノード自動プロビジョニングを使用すると、スケジュール設定されたワークロードに合うノードプールを動的に作成することにより、リソースの浪費を削減することにつながります。ただし、新しいノードプールの作成が必要な場合、自動スケーリングのレイテンシが若干高くなることがあります。ワークロードが不注意によるノードの再起動や処理能力の低下に対して柔軟性がある場合、Pod にプリエンプティブル VM を容認する構成を作ることによってさらに費用を節約できます。

ノード自動プロビジョニングを有効にする際のおすすめの方法は次のとおりです。

  • クラスタ オートスケーラーのすべてのベスト プラクティスに従う。
  • アプリケーションがトラフィックを受信していないときに NAP がクラスタで大きな変更を行わないように、リソースの最小サイズと最大サイズを設定する。
  • HorizontalPodAutoscaler を使用してワークロードを処理する場合は、NAP が自動スケーリングのレイテンシを増大させる可能性があるため、目標使用率バッファを少し大きくすることを検討する。

詳細については、ノード自動プロビジョニングの使用サポートされていない機能をご覧ください。

オートスケーラーとオーバープロビジョニング

費用を抑えるには、前のセクションの説明に従って、オートスケーラーを有効にすることを強くおすすめします。すべてのシナリオに合う構成は存在しないため、トラフィックの増加にオートスケーラーが適切な対応を行えるように、ワークロードの設定を調整する必要があります。

ただし、HorizontalPodAutoscaler セクションに記載した通り、インフラストラクチャのプロビジョニングによりスケールアップには時間がかかることがあります。時間と想定されるスケールアップのシナリオの違いを可視化するには、次の図を検討します。

時間と想定されるスケールアップ シナリオの違いを可視化する。

クラスタに新しい Pod をデプロイするための十分なスペースがある場合、ワークロードのスケールアップ シナリオのいずれかが開始されます。つまり、ある既存のノードにアプリケーションがデプロイされたことがない場合は、コンテナ イメージをダウンロードした後、Pod を起動する必要があります(シナリオ 1)。ただし、同じノードでアプリケーションの新しい Pod レプリカを起動する必要がある場合は、イメージのダウンロードが不要なため、合計のスケールアップ時間は短くなります(シナリオ 2)。

クラスタに新しい Pod をデプロイするための十分なスペースがない場合、インフラストラクチャとワークロードのスケールアップ シナリオの 1 つが開始されます。つまり、クラスタ オートスケーラーは新しい Node をプロビジョニングし、必要なソフトウェアを起動した後、アプリケーションの起動を行う必要があります(シナリオ 1)。ノード自動プロビジョニングを使用する場合は、スケジュール設定されたワークロードに応じて、新しいノードプールが必要になることがあります。この状況では、クラスタ オートスケーラーがノードとノードプールをプロビジョニングする必要があるため、合計スケールアップ時間が長くなります(シナリオ 2)。

新しいインフラストラクチャが必要になるようなシナリオでは、クラスタを過度に稼働させないでください。つまり、過剰にプロビジョニングする必要がありますが、スケールアップ時に想定されるピーク時のリクエストを処理するために必要とされるバッファの確保だけを行います。

この種類のオーバープロビジョニングには、主に次の 2 つの戦略があります。

  • HPA 使用率の目標を微調整する。適切な CPU 目標を見つけるには、次の式を使用すると簡単で安全です。

    (1 - buff)/(1 + perc)

    • buff は、CPU が 100% になることを回避するために設定できる安全バッファです。CPU が 100% になると、リクエスト処理のレイテンシが通常よりかなり大きくなるため、この変数を使用します。
    • perc は、2~3 分で予想されるトラフィックの増加率です。

    たとえば、リクエストの 30% の増加が予想されていて、10% のセキュア バッファを定義することで CPU が 100% にならないようにする数式は、次のようになります。

    (1 - 0.1)/(1 + 0.3) = 0.69

  • 一時停止 Pod を構成する。クラスタ オートスケーラーを構成してノードを事前にスピンアップする方法はありません。代わりに、負荷の急増に対応するバッファを提供するために HPA 使用率の目標を設定できます。ただし、大規模なバーストが想定される場合は、小さな HPA 使用率目標の設定では不十分か、コストが非常に高くなる可能性があります。

    この問題に対する代替策は、一時停止 Pod を使用することです。一時停止 Pod とは、優先度が低い何もしないデプロイメントですが、クラスタ内に空き容量を確保します。優先度の高い Pod がスケジュールされると、一時停止 Pod が強制排除されて、優先度の高い Pod ですぐに置き換えられます。強制排除された一時停止 Pod が再スケジュールされ、クラスタに空き容量がない場合は、クラスタ オートスケーラーによってそれに合う新しいノードが起動されます。一時停止 Pod はノードごとに 1 つだけにすることをおすすめします。たとえば、4 CPU ノードを使用している場合は、一時停止 Pod の CPU リクエストを 3,200 m 程度で構成します。

適切なマシンタイプを選択する

自動スケーリング以外にも、他の構成を使用することで、コストが最適化された Kubernetes アプリケーションを GKE で実行できる場合があります。このセクションでは、適切なマシンタイプの選択について説明します。

プリエンプティブル VM

プリエンプティブル VM(PVM)とは、最長持続時間が 24 時間で、可用性が保証されない Compute Engine VM インスタンスのことです。PVM を使用すると、標準の Compute Engine VM よりも最大で 80% 費用が安くなりますが、GKE クラスタで慎重に使用することをおすすめします。GKE の PVM は、エフェメラルで保証がない PVM の性質にそれほど影響されないため、バッチジョブやフォールト トレラントなジョブの実行に適しています。PVM の制約を扱えるシステムとアーキテクチャを準備している場合を除き、ステートフルなワークロードやサービス ワークロードでは、PVM を使用しないでください。

ワークロードの種類にかかわらず、次の制約に注意する必要があります。

  • プリエンプティブル ノードは誤ってシャットダウンされる可能性があり、Pod Disruption Budget が無視されることがあります。
  • ノードのプリエンプションにより Pod の猶予期間が無視されると、Pod が綺麗にシャットダウンされる保証はありません。
  • ノードがプリエンプトされ、Pod が動作しなくなったことを GKE が検出するまでに数分かかる場合があります。これにより、Pod が新しいノードへ再スケジューリングされる時間に遅れが生じます。

こうした制約を軽減するため、コミュニティ Node Termination Event Handler プロジェクト(重要: これは正規の Google プロジェクトではありません)をクラスタにデプロイできます。このプロジェクトにより、Compute Engine ノード終了イベントを Kubernetes の綺麗な Pod の終了に変換するアダプタが提供されます。このコミュニティ プロジェクトですべての PVM の制約が解決されるわけではなく、Pod 停止予算は引き続き無視される可能性があります。その結果、Pod を再スケジュールするのに時間がかかることがあります。

最後に、PVM の空きは保証されず、一部のリージョンでは簡単に利用可能な PVM がなくなることがあります。この制限を回避するには、PVM がないバックアップ ノードプールを設定することをおすすめします。クラスタ オートスケーラーはインフラストラクチャ コストを重視するため、PVM を優先します。

詳細については、GKE でのプリエンプティブル VM の実行コストが最適化された Spot VM を使用して GKE でウェブ アプリケーションを実行するをご覧ください。

E2 マシンタイプ

E2 マシンタイプ(E2 VM)は、N1 マシンタイプと比べて 31% のコスト削減を実現したコスト最適化 VM です。E2 VM は、ウェブサーバー、マイクロサービス、ビジネス クリティカルなアプリケーション、小規模から中規模のデータベース、開発環境など、幅広いワークロードに適しています。

E2 VM の詳細と、他の Google Cloud マシンタイプとの比較については、E2 VM におけるパフォーマンス重視の動的リソース管理マシンタイプをご覧ください。

適切なリージョンを選択する

コストに制約がある場合、GKE クラスタを実行する場所が重要になります。料金はコンピューティング リージョンによって変わります。これには多くの要因が関係しています。このため、ワークロードは最も低価格のオプションで実行し、レイテンシがユーザーに影響を与えないようにしてください。バッチジョブの実行など、ワークロードがリージョン間でデータをコピーする場合は、このデータの移動費用も考慮する必要があります。

適切なリージョンを選択する方法の詳細については、Compute Engine のリージョン選択に関するベスト プラクティスをご覧ください。

確約利用割引を申し込む

数年間 Google Cloud を使用する予定がある場合は、VM の使用量に対して大幅な割引が適用される、確約利用割引の利用を強くおすすめします。確約利用契約を結ぶと、コンピューティング リソースに対する 1 年間または 3 年間の支払いを確約する代わりに、そのコンピューティング リソースを割引価格(最大 70% 割引)で購入します。commit するリソースの量が不明な場合は、最小コンピューティング使用量(夜間など)を確認し、その量に対する支払いを確約します。

マシンタイプ別の確約利用料金に関する詳細は、VM インスタンスの料金をご覧ください。

小規模な開発クラスタを確認する

費用を最小限に抑える必要がある小規模な開発クラスタの場合は、Autopilot クラスタの使用を検討してください。この運用モードのクラスタでは、システム Pod、オペレーティング システムの費用、またはスケジュールされていないワークロードに対して課金されません。

ロギングとモニタリングの戦略を確認する

Cloud LoggingCloud Monitoring を使用してアプリケーションとインフラストラクチャにオブザーバビリティを提供する場合は、使用した分だけ課金されます。ただし、インフラストラクチャとアプリケーションのログが多くなるほど、ログの保存期間が長くなり、そのコストも高くなります。同様に、外部指標やカスタム指標が多くなるほど、コストが嵩みます。Cloud Logging、Cloud Monitoring、アプリケーション パフォーマンス管理のコスト最適化に従って、ロギングとモニタリングの戦略を確認します。

リージョン クラスタとマルチゾーン クラスタにおけるリージョン間の下り(外向き)トラフィックを確認する

使用可能な GKE クラスタのタイプには、シングルゾーンマルチゾーンリージョンがあります。複数ゾーンにわたってノードが高可用性を持っているため、リージョン クラスタとマルチゾーン クラスタは本番環境に適しています。ただし、ゾーン間の下り(外向き)トラフィックによって課金されます。本番環境では、ゾーン間でトラフィック負荷をモニタリングし、API を改善して負荷を最小限に抑えることをおすすめします。また、Pod 間のアフィニティと反アフィニティ構成を使用し、異なるサービスの依存 Pod を、同じノード内または同じアベイラビリティ ゾーン内の同じ場所に配置して、それらの間のコストとネットワーク レイテンシを最小化することも検討してください。このトラフィックをモニタリングするおすすめの方法は、デフォルトでは無効になっている GKE 使用状況測定下り(外向き)ネットワーク エージェントを有効にすることです。

非本番環境の場合は、単一ゾーンクラスタをデプロイすることを、費用削減の点でおすすめします。

ワークロード タイプに合わせて環境を準備する

企業によって費用と可用性の要件は異なります。ワークロードは、バーストや急増に迅速に対応する必要があるサービス ワークロードと、最終的な作業結果を注視するバッチ ワークロードに分けられます。サービス ワークロードでは、スケールアップ レイテンシが小さいことが求められます。バッチ ワークロードでは、サービス ワークロードと比べて、レイテンシは許容されます。これらのワークロード タイプに対する異なる期待により、異なるコスト節約方法をより柔軟に選択できます。

バッチ ワークロード

バッチ ワークロードは最終的な作業結果を注視するため、GKE でのコストの節約が可能になります。これは、通常このワークロードでは、ジョブ起動時のある程度のレイテンシは許容されるためです。この許容により、クラスタ オートスケーラーにジョブがスケジュールされたときのみに新しいノードをスピンアップするためのスペースが与えられ、ジョブの終了時に削除されます。

最初のおすすめの方法は、ラベルとセレクタおよび taint と容認機能を使用することによって、バッチ ワークロードを異なるノードプールに分離することです。その理由は次のとおりです。

  • クラスタ オートスケーラーは、Pod を再起動する必要がない場合、空のノードをすばやく削除できます。バッチジョブの終了時に、現在は空である専用ノード上でワークロードが稼働している場合、クラスタによりスケールダウン処理が高速化されます。スケールダウンの速度をさらに改善するには、CA の使用率最適化プロファイルを構成することを検討してください。
  • 一部の Pod は再起動できないため、そのノードのスケールダウンは完全にブロックされます。システム Pod を含むこれらの Pod は、スケールダウンに影響しないように、異なるノードプールで実行する必要があります。

2 つ目の推奨方法は、ノードの自動プロビジョニングを使用して、一致する taint または容認機能があるジョブ専用のノードプールを自動的に作成する方法です。これにより、異なるノードプールをすべて設定しなくてもワークロードを分離できます。

プリエンプティブル VM のエフェメラルで非保証型の性質の影響を受けないフォールト トレラント ジョブを実行する場合にのみ、プリエンプティブル VM を使用することをおすすめします。

これらのプラクティスに従う環境を設定する方法については、ノード自動プロビジョニングを使用したマルチテナント GKE クラスタでのリソース使用量の最適化のチュートリアルをご覧ください。

サービス ワークロード

バッチ ワークロードとは異なり、サービス ワークロードでは、バーストや急激な増加に可能な限り迅速に対応する必要があります。こうしたトラフィックの急増は、テレビ CM、ブラック フライデーなど記録的スケールのイベント、ニュース速報など、さまざまな要因により発生します。これをアプリケーションで処理できるように準備する必要があります。

このような急激な増加の処理における問題点は、一般に次に挙げる原因のいくつかに関連しています。

  • アプリケーションを Kubernetes 上で稼働する準備ができていない(たとえば、イメージサイズが大きなアプリ、起動に時間がかかる、Kubernetes 構成が最適でないなど)。
  • アプリケーションが GPU のように、プロビジョニングに時間がかかるインフラストラクチャに依存している。
  • オートスケーラーとオーバー プロビジョニングが適切に設定されていない。

クラウドベースの Kubernetes アプリケーションを準備する

このセクションのベスト プラクティスの中には、費用を節約する方法もあります。ただし、これらのベスト プラクティスは、オートスケーラーでアプリケーションを確実に機能させることを目的としているため、実装することを強くおすすめします。

アプリケーションの処理能力を把握する

アプリケーションの処理能力を計画する際は、アプリケーションが処理できる同時リクエストの数、必要な CPU とメモリの量、負荷が高い状態での応答の様子を確認します。ほとんどのチームはこのような処理能力を把握していないので、負荷がかかった状態でアプリケーションがどのように動作するかをテストすることをおすすめします。自動スケーリングをオフにした単一のアプリケーション Pod レプリカを隔離して、実際の使用状況の負荷をシミュレートしたテストを行います。これは、Pod ごとの処理能力を把握するのに役立ちます。その後に、クラスタ オートスケーラー、リソース リクエストと上限、HPA または VPA のいずれかを構成することをおすすめします。次に、アプリケーションに対して再度負荷をかけますが、突然のバーストや急増をシミュレートするため、負荷の強度を高めます。

理想的には、レイテンシの懸念をなくすため、これらのテストは、アプリケーションが Google Cloud で実行されているリージョンまたはゾーンから実行する必要があります。テストツールには、自作のスクリプトや、Apache BenchmarkJMeterLocust などの高度なパフォーマンス ツールのどちらも使用できます。

テストを実施する方法の例については、Google Kubernetes Engine を使用した負荷分散テストをご覧ください。

アプリケーションを垂直および水平に拡張できるようにする

アプリケーションの拡大と縮小が可能であることを確認してください。つまり、CPU とメモリを増設するか、Pod レプリカをさらに追加してトラフィックの増加に対処します。これにより、オートスケーラーを異なる設定にすることと、ノードサイズを変更することのどちらがアプリケーションに適切なのかをテストする柔軟性が得られます。残念ながら、アプリケーションの中には、単一スレッドのものや、ワーカーやサブプロセスの数が固定数であることによる制限を持つものがあり、こうしたアプリケーションでは、アーキテクチャを完全にリファクタリングしない限り、このテストを行うことはできません。

適切なリソース リクエストと制限を設定する

アプリケーションの処理能力を把握することで、コンテナ リソースで何を構成する必要があるか判断できます。Kubernetes のリソースは主に CPU とメモリ(RAM)で定義されます。spec.containers[].resources.requests.<cpu|memory> リクエストを使用して、アプリケーションの実行に必要な CPU またはメモリの量を構成し、spec.containers[].resources.limits.<cpu|memory> リクエストを使用して上限を構成します。

リソース リクエストを正しく設定すると、Kubernetes スケジューラはそれを使用して、Pod を配置するノードを決定できます。これにより、Pod が正常に機能するノードに配置されることが保証されるため、安定性が向上し、リソースの無駄が軽減されます。さらに、リソースの上限を定義すると、これらのアプリケーションは、コンピューティング ノードで提供される基盤となるインフラストラクチャを一部しか使用しなくなります。

コンテナ リソースを設定する場合は、リクエストと上限に同じ量のメモリを使用し、より大きい CPU 上限を使用する、または CPU 上限を無制限にすることをおすすめします。次にデプロイメントの例を示します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wp
  template:
    metadata:
      labels:
        app: wp
    spec:
      containers:
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"

上記パターンの詳細については、Kubernetes のリソース外の処理をご覧ください。簡単に表現すると、コンピュータのリソースが枯渇するとノードが不安定になるということです。この状況を回避するには、kubelet を使用して、リソースの不足合計を監視し、リソースを大量に消費する Pod をランク付けすることにより、リソースの枯渇を防止します。CPU が取り合いになると、その Pod はリクエストに制限される場合があります。ただし、メモリは圧縮可能なリソースではないため、メモリが枯渇した場合は Pod を停止する必要があります。Pod の削除(結果として環境の不安定化)を回避するには、リクエストされたメモリをメモリ制限に設定する必要があります。

また、VPA をレコメンデーション モードで使用して、特定のアプリケーションの CPU とメモリ使用量を判断することもできます。VPA はアプリケーションの使用状況に基づいてこれらのレコメンデーションを提供するため、本番環境などの環境では、この機能を有効にして、実際のトラフィックで使用することをおすすめします。VPA ステータスと、リソースのリクエストと上限の推奨事項を含むレポートが生成されます。これらの値は、デプロイ マニフェストで静的に指定できます。アプリですでに HPA を定義している場合は、HPA と VPA の混合をご覧ください。

コンテナの無駄をできる限り排除する

コンテナ内でアプリケーションを実行する場合、コンテナ構築のベスト プラクティスに従うことが重要です。これらのコンテナを Kubernetes で実行する場合は、アプリケーションをいつでも開始または停止できるため、これらのベスト プラスティスの一部はさらに重要になります。このセクションでは、主に次の 2 つのベスト プラクティスについて説明します。

  • 可能な限りイメージを小さくします。クラスタ オートスケーラーがクラスタに新しいノードをプロビジョニングするたびに、そのノードで実行されるイメージをノードがダウンロードする必要があるため、小さなイメージを用意することをおすすめします。イメージが小さいほど、ノードのダウンロードが高速になります。

  • アプリケーションをできる限り早く起動します。一部のアプリケーションでは、クラスの読み込み、キャッシュの保存など、起動に数分かかる場合があります。Pod の起動に長時間を要する場合、アプリケーションの起動中にお客様のリクエストがエラーになることがあります。

システムを設計する際、特にバーストやスパイクが予想される場合は、次の 2 つの方法を検討してください。イメージサイズを小さくし、早く起動させることで、スケールアップのレイテンシが短縮されます。その結果、不安定性を過度に心配することなく、トラフィックの増加を適切に処理できます。こうした方法は、GKE の自動スケーリングで説明されている自動スケーリングのベスト プラクティスとよりうまく連携します。

コンテナを構築する方法の詳細については、コンテナ構築のベスト プラクティスをご覧ください。

アプリケーションに Pod Disruption Budget を追加する

Pod 停止予算(PDB)では、自発的な中断から同時に削除できる Pod の数が制限されます。つまり、定義された停止予算は、ロールアウト、ノードのアップグレード、すべての自動スケーリング アクティビティで考慮されます。ただし、ハードウェア障害、カーネル パニック、誤った VM の削除など、偶発的な事象が発生した場合、この予算は保証されません。

クラスタ オートスケーラーの圧縮フェーズ中に PDB が考慮される場合は、すべてのアプリケーションに対して Pod Disruption Budget を定義することをおすすめします。これにより、CA がクラスタをスケールダウンしているときでも、ロードバランサをサポートするために必要なレプリカの最小数を制御できます。

詳細については、アプリケーションの停止予算を指定するをご覧ください。

アプリケーションに有用な readiness probe と liveness probe を設定する

意味のあるプローブを設定すると、アプリケーションは起動してトラフィックを受信する準備ができた場合にのみトラフィックを受信します。GKE は、readiness probe を使用して、Pod をロードバランサに追加するタイミングとロードバランサから削除するタイミングを決定します。GKE は、liveness probe を使用して、Pod を再起動するタイミングを決定します。

liveness probe は、特定の Pod が進行できない状態であることを Kubernetes に伝えるのに役立ちます(たとえば、デッドロック状態が検出されたときなど)。readiness probe は、アプリケーションがトラフィックを受信できない状態であることを Kubernetes に伝えるのに役立ちます(起動時に大きなキャッシュ データを読み込んでいる間など)。

スケールアップ アクティビティ中にアプリケーションの正しいライフサイクルを確保するには、次の手順を行うことが重要です。

  • すべてのコンテナ用に readiness probe を定義します。
  • アプリケーションが起動時に読み込まれるキャッシュに依存している場合、readiness probe は、キャッシュが完全に読み込まれた後にのみ、使用できる状態になったことを通知する必要があります。
  • アプリケーションがすぐにサービスを開始できる場合は、適切なデフォルト プローブの実装としては、できる限り単純に、HTTP エンドポイントが 200 ステータス コードを返すなどの方法があります。
  • 接続プールに使用可能なリソースがあるかどうかを確認するなど、より高度なプローブを実装する場合は、単純な実装と比較してエラー率が上昇していないことを確認します。
  • 決して他のサービスにプローブのロジックでアクセスしてはいけません。これらのサービスがすぐに応答しない場合、Pod のライフサイクルが損なわれる可能性があります。

詳細については、Liveness probe、Readiness probe、Startup Probe の構成をご覧ください。

アプリケーションが Kubernetes の想定どおりにシャットダウンされていることを確認する

オートスケーラーは、スパイクに対応して新しい Pod とノードを起動し、スパイクが終わると削除します。つまり、Pod の処理中にエラーが発生しないようにするには、高速起動か綺麗なシャットダウンのいずれかを行う必要があります。

Kubernetes はエンドポイントとロードバランサを非同期で更新するため、動作の中断を生じることのないシャットダウンを確実に行うためにこれらのベスト プラクティスに従うことが重要です。

  • SIGTERM の直後に新しいリクエストの受信を停止しないでください。アプリケーションは直ちに停止するのではなく、処理中のすべてのリクエストと、Pod の終了処理が開始された後の受信接続リクエストを終了します。Kubernetes によるすべての kube-proxies とロードバランサを更新には時間がかかることがあります。これらの更新前にアプリケーションが終了すると、クライアント側でリクエストの一部にエラーが発生する可能性があります。
  • アプリケーションが上記の手法に沿っていない場合は、preStop フックを使用してください。ほとんどのプログラムは、リクエストの受け付けを直ちには停止しません。ただし、サードパーティのコードを使用している場合や、nginx など、制御できないシステムを管理している場合は、preStop フックは、アプリケーションを変更することなく正常なシャットダウンをトリガーするのに適した選択肢です。一般的な戦略の 1 つは、preStop フックで実行して、数秒のスリープにより SIGTERM を延期することです。これにより、Kubernetes で Pod の削除プロセスを完了するための追加の時間が付与され、クライアント側で接続エラーが減少します。
  • クリーンアップの SIGTERM を処理します。アプリケーションがクリーンアップする必要がある場合、またはプロセスが完了する前に保持する必要があるメモリ内の状態がアプリケーションにある場合は、この時点で行います。このシグナルを検出する方法は、プログラミング言語によって異なるため、それぞれの言語で適切な方法を確認してください。
  • アプリケーションのニーズに合わせて terminationGracePeriodSeconds を構成します。アプリケーションによっては、デフォルトの 30 秒より長くかかる場合もあります。その場合、terminationGracePeriodSeconds を指定する必要があります。値が大きいと、ノードのアップグレードやロールアウトの時間が長くなる可能性があります。値が小さいと、Pod の終了プロセスが完了するのに十分な時間を確保できない場合があります。いずれにしても、クラスタ オートスケーラーは 10 分間だけアプリを使用します。このため、アプリケーションの終了期間は 10 分未満にすることをおすすめします。
  • アプリケーションがコンテナ ネイティブの負荷分散を使用している場合、SIGTERM を受け取った際は、readiness probe を失敗するようします。このアクションはロードバランサに直接伝わり、バックエンド Pod に対する新しいリクエストの転送が停止されます。ヘルスチェックの構成とエンドポイント プログラミングの間の競合に応じて、バックエンド Pod が早期にトラフィックから除外される可能性があります。

詳細については、Kubernetes のベスト プラクティス: 猶予期間による終了をご覧ください。

NodeLocal DNSCache を設定する

GKE マネージド DNS は、すべての GKE クラスタにデプロイされるアドオンである kube-dns によって実装されます。負荷の高い DNS アプリケーションを実行する場合は、デフォルトの kube-dns-autoscaler 構成では十分でない場合があります(デフォルトでは、クラスタ内のノードとコアの数に基づいて kube-dns レプリカの数を調整します)。このシナリオでは、DNS クエリが遅くなるか、タイムアウトする可能性があります。多くの企業では、この問題を軽減するために kube-dns-autoscaler ConfigMap を調整して、クラスタ内の kube-dns レプリカの数を増やしています。この方法は想定どおりに機能しますが、リソースの使用量と GKE の総コストが増加します。

コストを最適化し、スケーラビリティを高めるもう 1 つの方法として、クラスタ内に NodeLocal DNSCache を構成する方法があります。NodeLocal DNSCache は、DNS ルックアップのレイテンシを改善し、DNS ルックアップ時間の整合性をより高め、各クラスタノードで DNS キャッシュを実行することで、kube-dns への DNS クエリの数を削減するオプションの GKE アドオンです。

詳細については、NodeLocal DNSCache の設定をご覧ください。

Ingress によるコンテナ ネイティブの負荷分散を使用する

コンテナ ネイティブの負荷分散により、ロードバランサは Kubernetes Pod を直接ターゲットにすることができ、ネットワーク エンドポイント グループ(NEG)と呼ばれるデータモデルを使用してトラフィックを Pod に均等に分散できます。このアプローチにより、ネットワーク パフォーマンスが向上して、可視性が高まり、高度な負荷分散機能が有効になり、Google Cloud のフルマネージド トラフィック コントロール プレーンの Traffic Director をサービス メッシュに対して使用できます。

このような利点のため、コンテナ ネイティブの負荷分散が Ingress による負荷分散に推奨されるソリューションです。NEG を GKE Ingress と一緒に使用すると、Ingress コントローラで L7 ロードバランサの作成が容易になります。たとえば、仮想 IP アドレス、転送ルール、ヘルスチェック、ファイアウォール ルールなどを簡単に作成できます。

クラスタ オートスケーラーを使用する場合、コンテナネイティブの負荷分散はさらに重要になります。NEG 以外のロードバランサの場合、スケールダウン中は、クラスタ オートスケーラーがノード インスタンスを終了する前に、負荷分散プログラミングとコネクション ドレインが完了しないことがあります。バックエンド Pod がノードに存在しない場合でも、ノードを介して流れている進行中の接続が中断する可能性があります。

コンテナ ネイティブの負荷分散は、次のすべての条件が満たされている場合、デフォルトで Services に対して有効になります。

  • Service が GKE クラスタ 1.17.6-gke.7 以降で作成されている。
  • VPC ネイティブ クラスタを使用している場合。
  • 共有 VPC を使用していない場合。
  • GKE ネットワーク ポリシーを使用していない場合。

詳細については、Ingress GKE のドキュメントコンテナ ネイティブ負荷分散の使用をご覧ください。

指数バックオフでの再試行の使用を検討する

Kubernetes で実行されているマイクロサービス アーキテクチャでは、次の例のようなさまざまな理由で、一時的な障害が発生する可能性があります。

これらの問題はエフェラメルなものであり、しばらくしてからサービスを再度呼び出すことで、これらの障害を軽減できます。ただし、リクエストによって宛先サービスが過負荷になりすぎないように、指数バックオフを使用してこれらの呼び出しを行うことが重要です。

このような再試行パターンを円滑に行うため、多くの既存ライブラリには指数再試行ロジックが実装されています。自分で選択したライブラリを使用することも、独自のコードを書くこともできます。IstioAnthos Service Mesh(ASM)を使用する場合は、ユーザーに代わって再試行を行うプロキシレベルのリトライ メカニズムを選択できます。

すでに挿入されている情報が再挿入されないように、アプリケーションがサービス呼び出しの再試行をサポートすることが重要です。一連の再試行が最終的なユーザーのレイテンシに影響を与える可能性があり、適切に計画しなければタイムアウトする可能性があります。

環境をモニタリングし、コスト最適化の構成と手法を適用する

多くの中規模および大規模の企業では、集中型プラットフォームとインフラストラクチャ チームが、全社の Kubernetes クラスタの作成、メンテナンス、モニタリングを担当します。これは、リソースの使用量についてアカウンタビリティがあることと、すべてのチームが会社のポリシーを遵守していることを確認することに対する強力なニーズを表しています。このセクションでは、費用関連の手法をモニタリングと適用に関するオプションについて説明します。

GKE クラスタを観察し、推奨事項を確認する

Kubernetes クラスタでは、コンテナ、Pod、サービス、クラスタ全体の特長を確認することによりリソースの使用率をチェックできます。この作業はさまざまな方法で実行できますが、最初は Monitoring Dashboard で GKE クラスタを監視することをおすすめします。これにより、クラスタの使用状況に関する時系列データが提供されるため、インフラストラクチャ、ワークロード、サービスから集約してスパンを行えます。

この方法は手始めとしては良いものですが、Google Cloud には次のような選択肢もあります。

  • Google Cloud コンソールの [GKE クラスタ] ページで、[通知] 列を確認します。クラスタのリソース使用率が高い場合は、UI に表示されたヒントから、割り当てられた量とリクエストされた量を把握できます。

    GKE クラスタリストに移動

  • Google Cloud コンソールの [推奨事項] ページで、費用の削減の提案カードを探します。

    おすすめハブに移動

詳細については、GKE クラスタの監視おすすめハブのスタートガイドをご覧ください。

GKE 使用状況測定を有効にする

大まかな費用の内訳を確認できる、より柔軟な手法が必要な場合は、GKE 使用状況測定をお試しください。GKE 使用状況測定を使用すると、GKE クラスタの使用状況プロファイルを名前空間とラベルで分類して確認できます。これは、クラスタのワークロードのリソース リクエストとリソース消費量(CPU、GPU、TPU、メモリ、ストレージ、下り(外向き)ネットワークなど)に関する情報を追跡します。

GKE 使用状況測定は、GKE クラスタの全体的なコスト構造、最もコストの高いチームやアプリケーション、使用頻度やコストが急増した環境やコンポーネント、無駄が多いチームを把握するために使用できます。リソース リクエストと実際の使用率を比較すると、どのワークロードに過不足があるか、またはオーバープロビジョニングされているかを確認できます。

デフォルトの Looker Studio テンプレートを活用できますが、さらに一歩進んで、組織のニーズに応じてダッシュボードをカスタマイズすることもできます。GKE 使用状況測定とその前提条件の詳細については、クラスタ リソースの使用についてをご覧ください。

Metrics Server の仕組みを把握してモニタリングする

Metrics Server は、GKE 組み込み自動スケーリング パイプラインのコンテナ リソース指標の提供元です。Metrics Server は kubelets から指標を取得し、Kubernetes Metrics API を介して公開します。HPA と VPA により、これらの指標が自動スケーリング開始の判断に使われます。

GKE 自動スケーリングの健全性のために、正常な Metrics Server が必要です。GKE metrics-server デプロイメントでは、リサイザの nanny がインストールされます。これは、クラスタのノード数に応じて CPU とメモリが追加または削除することにより、Metrics Server コンテナを垂直方向に拡張します。Pod のインプレース更新は、Kubernetes ではまだサポートされていないため、新しい必須リソースを適用するには Nanny で metrics-server Pod を再起動する必要があります。

再起動はすぐに行われますが、オートスケーラーにより対応が必要と判断されるためのレイテンシの合計時間は、metrics-server のサイズ変更後にわずかに増加する場合があります。急速に変化するクラスタで Metrics Server の頻繁な再起動を避けるため、GKE 1.15.11-gke.9 以降、nanny は、サイズ変更の遅延をサポートしています

Metric Server を使用する場合は、次のベスト プラクティスに従ってください。

  • metrics-server のサイズ変更の遅延をサポートする GKE バージョンを選択する。その場合、metrics-server-nanny コンテナの metrics-server デプロイ YAML ファイルに scale-down-delay 構成が含まれているかどうかを確認します。
  • metrics-server のデプロイをモニタリングする。Metrics Server が停止している間、自動スケーリングは機能しません。このデプロイを最優先のモニタリング サービスでモニタリングする。
  • GKE の自動スケーリングで説明しているベスト プラクティスに従ってください。

Kubernetes のリソースの割り当てを使用する

マルチテナント クラスタでは、通常、異なる名前空間にデプロイされたアプリケーションにさまざまなチームが関わります。集中型のプラットフォームとインフラストラクチャ グループの場合は、1 つのチームが必要以上に多くのリソースを使用する場合があるという懸念があります。すべてのクラスタのコンピューティング リソースを不足させることや、スケールアップのトリガーが多すぎると、コストが増える可能性があります。

この問題に対処するには、リソースの割り当てを使用する必要があります。リソースの割り当てでは、名前空間内のオブジェクトで使用されるリソースの量を管理します。割り当て(CPU とメモリ)とストレージ リソース単位またはオブジェクト数から割り当てを設定できます。リソースの割り当てを通じて、各テナントで使用されるクラスタ リソースがそれぞれの割り当て量を超えないようにできます。

詳細については、Namespace のメモリと CPU の割り当てを構成するをご覧ください。

GKE Enterprise Policy Controller の使用を検討する

GKE Enterprise Policy Controller(APC)は、セキュリティ、規制、任意のビジネスルールに関連するポリシーへのクラスタの準拠を確認、監査、適用する Kubernetes 動的アドミッション コントローラです。Policy Controller は、制約を使用してクラスタのコンプライアンスを適用します。たとえば、クラウドベース Kubernetes アプリケーションの準備セクションに記載されているように、多くのベスト プラクティスではクラスタに制約を設定できます。その場合、Kubernetes のベスト プラクティスに厳密に従っていないデプロイは拒否されます。このようなルールを適用すると、予期しないコストの急増を回避し、自動スケーリング時にワークロードの不安定さを低減できます。

独自のルールを適用して書き込む方法について詳しくは、制約の作成制約テンプレートの作成をご覧ください。GKE Enterprise のお客様でない場合は、APC が構築されているオープンソース ソフトウェアである Gatekeeper の使用を検討してください。

コスト節約手法を適用する CI / CD パイプラインを設計する

GKE Enterprise Policy Controller は、GKE クラスタに非遵守のソフトウェアをデプロイしないようにするために使用できます。ただし、事前 commit チェック、pull リクエスト チェック、配信ワークフロー、またはご使用の環境に適した手順のいずれにおいても開発サイクルの早い段階でこれらのポリシー制約を適用することをおすすめします。これにより、構成ミスをすばやく見つけて修正し、ガードレールを作成することで、注意すべき点を把握できます。

CI/CD パイプラインで kpt 関数を使用して、Kubernetes 構成ファイルが GKE Enterprise Policy Controller によって適用される制約に適合しているかどうかを検証し、リソースの使用率またはデプロイメントのコストの見積もりを行うこともできます。このようにして、費用関連の問題が検出されたときにパイプラインを停止できます。また、たとえばレプリカの数を増やすような構成用に別のデプロイメント承認プロセスを作成することもできます。

詳細については、CI パイプラインでの Policy Controller の使用、配信プラットフォームの完全な例については、GKE Enterprise による最新の CI / CD をご覧ください。

コスト削減の文化を広げる

多くの組織では、インフラストラクチャの複雑さを解消するため、抽象化とプラットフォームを作成しています。これは、仮想マシンから Kubernetes にサービスを移行する企業にとって一般的な方法です。また、デベロッパーが本番環境のアプリケーションを独自に構成できる場合もあります。ただし、Kubernetes クラスタに一度も触れたことのないデベロッパーはいないでしょう。

このセクションで推奨している方法は、抽象化の使用を完全に停止するべきという意味ではありません。代わりに、Google Cloud の費用を確認して、インフラストラクチャで開発者や運用担当者をトレーニングする場合に使用します。これを行うには、従来のクラスやオンライン クラス、ディスカッション グループ、ピアレビュー、ペア プログラミング、CI / CD とコスト削減のゲーミフィケーションなど使用できる、学習インセンティブとプログラムを作成します。たとえば、Kubernetes の世界では、3 GB イメージ アプリケーション、readiness probe の欠落、HPA の構成ミスの影響を理解することは重要です。

最後に、Google の DORA の調査で示されているように、文化的能力は、組織のパフォーマンスの改善、後戻り作業の削減、燃え尽き症候群の削減につながる大きな要因の一部となるものです。コストの削減も例外ではありません。従業員に自身の支出にアクセスできるようにすると、ビジネスの目標や制約に従業員がより近づくようになります。

ベスト プラクティスの概要

次の表に、このドキュメントで推奨するベスト プラクティスをまとめます。

トピック タスク
GKE のコスト最適化機能とオプション
クラウドネイティブな Kubernetes アプリケーションを準備する
環境をモニタリングし、コスト最適化の構成と手法を適用する
文化

次のステップ