私のIstioがだんだん遅くなる衝撃的な理由 (feat. Sidecarリソース)

皆さんのサービスメッシュは元気ですか?🤔 マイクロサービス(MSA)アーキテクチャが複雑になり、サービスの数が増えるにつれて、Istioがだんだん重くなり、遅くなるという経験は、皆さん一度はされたことがあるでしょう。サイドカープロキシのメモリ使用量は天井知らずに高騰し、設定が伝播する時間もどんどん長くなります。

「サーバーのスペックを上げるべきか?」と悩んだことがあるなら、ちょっと待ってください!✋ もしかしたら、非常にシンプルな設定を見落としていたのかもしれません。今日は、多くの人が見過ごしがちですが、Istioのパフォーマンス最適化の鍵となるSidecarリソースについて深く掘り下げていきます。


🌍 デフォルト設定の落とし穴:「すべてを教えよう!」

Istioをインストールし、サービスをメッシュに組み込むと、デフォルトで各ワークロードに注入されたサイドカープロキシ(Envoy)は非常に親切かつ勤勉に動作します。あまりにも勤勉すぎるため、メッシュ内に存在するすべてのサービスに関するルーティング情報、エンドポイントなど、すべての設定をコントロールプレーン(Istiod)から受信します。

これがなぜ問題なのでしょうか?🤯

サービスが10個の場合は問題ないかもしれません。しかし、100個、500個に増えると想像してみてください。AサービスがBサービスとだけ通信すればよいのに、全く関係のないC、D、E…Zサービスの情報をすべて受け取り、メモリに蓄積していることになります。

まるでソウルの特定の地域でしか配達しないライダーに、韓国全体の地図と住所録を丸ごと渡すようなものです。🗺️

  • メモリ&CPUの急増:不要な設定情報がサイドカーのリソース使用量を急激に増加させます。
  • 設定伝播の遅延:設定のサイズが大きくなるため、小さな変更一つがメッシュ全体のすべてのプロキシに伝播するのに長い時間がかかります。
  • パフォーマンスの低下:最終的にサービスメッシュ全体のパフォーマンス低下につながります。

🦸‍♂️ 救世主登場!Sidecarリソース

このような非効率を解決するために、Sidecarリソースが存在します。Sidecarリソースは、各サイドカープロキシが「知るべきことだけを知る」ように、設定の範囲を賢く制限する役割を果たします。

つまり、「すべてを教えよう!」モードから「あなたに本当に必要な情報だけを教えよう!」モードに切り替えるスイッチなのです。💡

Sidecarリソースの核となるのはegressフィールドです。このフィールドを通じて、当該ワークロードが外部と通信(アウトバウンド)すべき対象を明示的に指定できます。

🛠️ 実際に確認してみましょう!

例えば、bookinfoの例のreviewsサービスは、ratingsサービスとだけ通信すると仮定してみましょう。

1. Sidecarリソース適用前

Sidecarリソースが何も適用されていない場合、reviewsポッドのサイドカーはメッシュ内のすべてのサービス(productpage、detailsなど)に関する設定を受け取ります。以下のコマンドで確認できます。(結果の行数は環境によって異なります。)

# reviewsポッドの名前を確認
REVIEWS_POD=$(kubectl get pod -l app=reviews -n bookinfo -o jsonpath='{.items[0].metadata.name}')

# reviewsポッドのサイドカーが認識しているクラスター(サービス)リストを確認
istioctl proxy-config clusters $REVIEWS_POD -n bookinfo | wc -l
# 生データ(例)
# かなり大きな数字が表示されるでしょう。例えば...
52

2. Sidecarリソースの適用

それでは、reviewsワークロードのためのSidecarリソースを定義してみましょう。この設定は、reviewsアプリが同じ名前空間(bookinfo)にあるratingsサービスと、istio-system名前空間の必須コンポーネントとのみ通信するように制限します。

# コード
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: reviews-sidecar
  namespace: bookinfo
spec:
  # 'app: reviews'ラベルを持つポッドにこの設定を適用します。
  workloadSelector:
    labels:
      app: reviews
  egress:
    # アウトバウンドトラフィックのターゲットを明示的に指定します。
    - hosts:
        # 1. 現在の名前空間("./")のサービスのみを許可
        - "./ratings.bookinfo.svc.cluster.local"
        # 2. Istiodなどのコントロールプレーン通信のための必須設定
        - "istio-system/*"

上記のYAMLファイルをkubectl apply -fコマンドで適用します。

3. Sidecarリソース適用後

しばらくしてから、再度プロキシ設定を確認してみましょう。

# しばらくしてから設定を再確認
istioctl proxy-config clusters $REVIEWS_POD -n bookinfo | wc -l
# 生データ(例)
# 以前よりもはるかに小さい数字が表示されます。例えば...
15

結果が見えますか?🚀 reviewsサイドカーが管理すべき設定の量が劇的に減少しました。これは直接的にリソース使用量の削減とパフォーマンス向上につながります。


🧐 よくある誤解と間違ったアプローチ

Sidecarリソースを理解する上でよくある誤解があります。間違った方法はかえって問題を悪化させる可能性があるため、必ず確認しておく必要があります。

  • 「単にメモリ/CPUの割り当てを増やせばいいのでは?」 (❌)
  • これは根本的な原因を解決するのではなく、問題を金で覆い隠す一時しのぎに過ぎません。🚚 配達経路が非効率なのに、より大きなトラックを買うようなものです。サイドカーのリソース割り当ては、ポッド定義(Deployment)のresourcesフィールドで行うのが正しいですが、これは設定範囲を最適化した後に必要なだけ割り当てるのが正しい順序です。
  • 「サイドカーの注入をオフにすればいいのでは?」 (❌)
  • 名前空間ラベルやポッドアノテーション(sidecar.istio.io/inject: "false")で注入を制御することは、そのワークロードをサービスメッシュから完全に除外することです。これは「最適化」ではなく「諦め」に近いです。私たちはメッシュの利点を享受しつつパフォーマンスを改善したいのであって、メッシュを離れたいわけではありません。
  • 「設定の更新頻度を調整する機能ですか?」 (❌)
  • Sidecarリソースは更新頻度を制御しません。受信する設定の範囲とサイズを制限するだけです。

✨ 全体的な観点から

個別のSidecarリソースを適用することも重要ですが、全体的な文脈でアプローチすることをお勧めします。

  1. 名前空間の隔離:まず、各名前空間が必要な他の名前空間のサービスのみを参照できるように、名前空間単位のSidecarリソースを基本として設定してください。(./*、istio-system/*、および必要な他の名前空間namespace-b/*など)
  2. ワークロード特化:その後、reviewsサービスのように特に通信範囲が狭いワークロードがある場合は、workloadSelectorを使用してより詳細なSidecarリソースを追加で適用する戦略が効果的です。

このアプローチにより、サービスメッシュはより堅牢で、予測可能になり、何よりも高速になります。もしIstioがなぜか遅くなったと感じたら、今すぐSidecarリソースを確認してみてください!


Comments

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です