GKE での Cloud Service Mesh のスケーリングのベスト プラクティス
このガイドでは、Google Kubernetes Engine でマネージド Cloud Service Mesh アーキテクチャのスケーリングの問題を解決するためのベスト プラクティスについて説明します。これらの推奨事項の主な目標は、マイクロサービス アプリケーションの成長に伴うパフォーマンス、信頼性、リソース使用率を最適にすることである。
GKE 上の Cloud Service Mesh のスケーラビリティは、2 つの主要コンポーネント(データプレーンとコントロール プレーン)の効率的な運用に依存します。このドキュメントでは、主にデータプレーンのスケーリングについて説明します。
コントロール プレーンとデータプレーンのスケーリングに関する問題の特定
Cloud Service Mesh では、コントロール プレーンまたはデータプレーンでスケーリングの問題が発生する可能性があります。発生しているスケーリングの問題の種類を特定する方法は次のとおりです。
コントロール プレーンのスケーリングに関する問題の症状
サービス ディスカバリの遅延: 新しいサービスまたはエンドポイントが検出され、使用可能になるまでに時間がかかる。
構成の遅延: トラフィック管理ルールまたはセキュリティ ポリシーの変更が伝播されるまでに時間がかかる。
コントロール プレーン オペレーションのレイテンシの増加: Cloud Service Mesh リソースの作成、更新、削除などのオペレーションが遅くなるか、応答しなくなる。
Traffic Director に関連するエラー: Cloud Service Mesh のログまたはコントロール プレーンの指標に、接続、リソースの枯渇、API スロットリングに関する問題を示すエラーが表示されることがあります。
影響範囲: コントロール プレーンの問題は通常、メッシュ全体に影響し、広範囲にわたるパフォーマンスの低下を引き起こします。
データプレーンのスケーリングに関する問題の症状
サービス間通信のレイテンシの増加: メッシュ内のサービスへのリクエストでレイテンシやタイムアウトが増加しますが、サービスのコンテナで CPU/メモリの使用量が増加することはありません。
Envoy プロキシでの CPU またはメモリの使用率が高い: CPU またはメモリの使用率が高い場合、プロキシがトラフィック ロードを処理できないことを示している可能性があります。
ローカライズされた影響: データプレーンの問題は通常、Envoy プロキシのトラフィック パターンとリソース使用率に応じて、特定のサービスまたはワークロードに影響します。
データプレーンのスケーリング
データプレーンをスケーリングするには、次の方法を試してください。
ワークロードの水平 Pod 自動スケーリング(HPA)を構成する
Horizontal Pod Autoscaling(HPA) を使用して、リソース使用率に基づいて追加の Pod を使用してワークロードを動的にスケーリングします。HPA を構成する際は、次の点を考慮してください。
--horizontal-pod-autoscaler-sync-period
パラメータを使用してkube-controller-manager
に設定し、HPA コントローラのポーリング レートを調整します。デフォルトのポーリング レートは 15 秒ですが、トラフィックの急増が予想される場合は、この値を短くすることを検討してください。GKE で HPA を使用するタイミングの詳細については、水平 Pod 自動スケーリングをご覧ください。デフォルトのスケーリング動作では、多数の Pod が一度にデプロイ(または終了)されるため、リソース使用量が急増する可能性があります。スケーリング ポリシーを使用して、Pod のデプロイ速度を制限することを検討してください。
EXIT_ON_ZERO_ACTIVE_CONNECTIONS を使用して、スケールダウン中に接続が切断されないようにします。
HPA の詳細については、Kubernetes ドキュメントの水平 Pod 自動スケーリングをご覧ください。
Envoy プロキシの構成を最適化する
Envoy プロキシ構成を最適化するには、次の推奨事項を検討してください。
リソースの上限
Pod 仕様で Envoy サイドカーのリソース リクエストと上限を定義できます。これにより、リソース競合を防ぎ、一貫したパフォーマンスを実現できます。
リソース アノテーションを使用して、メッシュ内のすべての Envoy プロキシのデフォルトのリソース上限を構成することもできます。
Envoy プロキシに最適なリソースの上限は、トラフィック量、ワークロードの複雑さ、GKE ノードリソースなどの要因によって異なります。サービス メッシュを継続的にモニタリングして微調整し、最適なパフォーマンスを確保します。
重要な考慮事項:
- Quality of Service(QoS): リクエストと上限の両方を設定すると、Envoy プロキシのサービス品質が予測可能になります。
サービスの依存関係をスコープする
Sidecar API を使用してすべての依存関係を宣言して、メッシュの依存関係グラフをトリミングすることを検討してください。これにより、特定のワークロードに送信される構成のサイズと複雑さが制限されます。これは、大規模なメッシュにとって重要です。
たとえば、次の図はオンライン ブティックのサンプル アプリケーションのトラフィック グラフです。
これらのサービスの多くはグラフ内のリーフであるため、メッシュ内の他のサービスの下り(外向き)情報を必要としません。次の例に示すように、これらのリーフサービスのサイドカー構成のスコープを制限するサイドカー リソースを適用できます。
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: leafservices
namespace: default
spec:
workloadSelector:
labels:
app: cartservice
app: shippingservice
app: productcatalogservice
app: paymentservice
app: emailservice
app: currencyservice
egress:
- hosts:
- "~/*"
このサンプル アプリケーションのデプロイ方法については、Online Boutique サンプル アプリケーションをご覧ください。
サイドカー スコープのもう 1 つの利点は、不要な DNS クエリを減らすことにあります。サービス依存関係をスコープすると、Envoy サイドカーは、サービス メッシュ内のすべてのクラスタではなく、実際に通信するサービスの DNS クエリのみを実行します。
サイドカーの構成サイズが大きい問題に直面している大規模なデプロイでは、メッシュのスケーラビリティを確保するために、サービス依存関係のスコープ設定を強くおすすめします。
モニタリングと微調整
初期リソースの上限を設定したら、Envoy プロキシをモニタリングして、最適なパフォーマンスが得られるようにすることが重要です。GKE ダッシュボードを使用して CPU とメモリの使用状況をモニタリングし、必要に応じてリソースの上限を調整します。
Envoy プロキシでリソースの上限を引き上げる必要があるかどうかを判断するには、通常のトラフィックとピーク トラフィックの条件でリソース使用量をモニタリングします。確認すべき点は次のとおりです。
CPU 使用率が高い: Envoy の CPU 使用率が常に上限に近づいているか上限を超えている場合は、リクエストの処理に問題があり、レイテンシの増加やリクエストのドロップにつながる可能性があります。CPU 上限の引き上げを検討してください。
この場合は水平方向のスケーリングを使用してスケーリングする傾向がありますが、サイドカー プロキシがアプリケーション コンテナと同じ速さでリクエストを処理できない場合は、CPU の上限を調整すると最適な結果が得られます。
メモリ使用量が多い: Envoy のメモリ使用量が上限に近づいているか上限を超えている場合、接続がドロップされたり、メモリ不足(OOM)エラーが発生したりする可能性があります。これらの問題を防ぐには、メモリ上限を増やします。
エラーログ: Envoy のログを調べて、リソースの枯渇に関連するエラー(アップストリーム接続エラー、ヘッダーの前に切断またはリセット、開いているファイルが多すぎるなど)を確認します。これらのエラーは、プロキシにリソースが不足していることを示している可能性があります。スケーリングの問題に関連するその他のエラーについては、スケーリングのトラブルシューティングのドキュメントをご覧ください。
パフォーマンス指標: リクエスト レイテンシ、エラー率、スループットなどの主要なパフォーマンス指標をモニタリングします。リソース使用率が高いとパフォーマンスが低下している場合は、上限の引き上げが必要になることがあります。
データプレーン プロキシのリソース上限を積極的に設定してモニタリングすることで、GKE でサービス メッシュを効率的にスケーリングできます。
復元力を組み込む
次の設定を調整して、コントロール プレーンをスケーリングできます。
外れ値検出
外れ値検出は、アップストリーム サービス内のホストをモニタリングし、エラーしきい値に達するとロード バランシング プールからホストを削除します。
- キーの構成:
outlierDetection
: ロード バランシング プールから異常なホストを排除するための設定。
- メリット: ロード バランシング プール内の正常なホストセットを維持します。
詳細については、Istio ドキュメントの外れ値検出をご覧ください。
再試行数
失敗したリクエストを自動的に再試行することで、一時的なエラーを軽減します。
- キーの構成:
attempts
: 再試行回数。perTryTimeout
: 再試行ごとのタイムアウト。全体的なタイムアウトよりも短く設定します。個々の再試行の試行を待機する時間を決定します。retryBudget
: 最大同時再試行回数。
- メリット: リクエストの成功率が向上し、断続的な障害の影響が軽減されます。
考慮すべき要素:
- べき等性: 再試行されるオペレーションがべき等であることを確認します。つまり、意図しない副作用なしに繰り返すことができます。
- Max Retries: 無限ループを回避するために、再試行回数を制限します(最大 3 回など)。
- 回路ブレーカー: 再試行と回路ブレーカーを統合して、サービスが継続的に失敗した場合に再試行を回避します。
詳細については、Istio ドキュメントの再試行をご覧ください。
タイムアウト
タイムアウトを使用して、リクエスト処理に許可される最大時間を定義します。
- キーの構成:
timeout
: 特定のサービスのリクエスト タイムアウト。idleTimeout
: 接続を閉じる前にアイドル状態にできる時間。
- メリット: システムの応答性の向上、リソースリークの防止、悪意のあるトラフィックに対する強化。
考慮すべき要素:
- ネットワーク レイテンシ: サービス間の予想されるラウンドトリップ時間(RTT)を考慮します。予期しない遅延に備えて、余裕を持たせてください。
- サービス依存関係グラフ: 連鎖リクエストの場合、呼び出し元サービスのタイムアウトが依存関係の累積タイムアウトよりも短くなるようにします。これにより、連鎖的な障害を回避できます。
- オペレーションの種類: 長時間実行されるタスクでは、データの取得よりも大幅に長いタイムアウトが必要になる場合があります。
- エラー処理: タイムアウトは、適切なエラー処理ロジック(再試行、フォールバック、回路の切断など)をトリガーする必要があります。
詳細については、Istio ドキュメントのタイムアウトをご覧ください。
モニタリングと微調整
タイムアウト、外れ値検出、再試行のデフォルト設定から始めて、特定のサービス要件と観測されたトラフィック パターンに基づいて徐々に調整することを検討してください。たとえば、サービスが通常応答するまでの時間に関する実際のデータを確認します。次に、各サービスまたはエンドポイントの特定の特性に合わせてタイムアウトを調整します。
テレメトリー
テレメトリーを使用してサービス メッシュを継続的にモニタリングし、構成を調整してパフォーマンスと信頼性を最適化します。
- 指標: 包括的な指標(リクエスト量、レイテンシ、エラー率など)を使用します。可視化とアラートのために Cloud Monitoring と統合します。
- 分散トレース: Cloud Trace との分散トレース統合を有効にして、サービス全体のリクエスト フローに関する詳細な分析情報を取得します。
- ロギング: アクセス ロギングを構成して、リクエストとレスポンスの詳細情報をキャプチャします。
追加情報
- Cloud Service Mesh の詳細については、Cloud Service Mesh の概要をご覧ください。
- スケーラビリティに関する一般的なサイト信頼性エンジニアリング(SRE)ガイダンスについては、Google SRE ブックの過負荷の処理とカスケード障害への対処の章をご覧ください。