1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

数百万の同時接続を支える:STCLab がいかにして Istio で大規模トラフィックを管理しているか

Posted at

By Ihyeok Song, STCLab SRE Team

STCLab では、トラフィック制御ソリューションである「NetFUNNEL」や、ボット対策プラットフォームの「BotManager」を SaaS として提供しています。数百万件の同時接続をリアルタイムで処理し、悪意のあるボットを瞬時に特定するためには、インフラに極めて高い安定性と柔軟性が求められます。私たちはその基盤として Istio を採用しています。

Istio には膨大な機能がありますが、本記事では実際のプロダクション環境で特に不可欠だった 5 つの機能に絞ってご紹介します。現在 Istio の導入を検討されている方や、具体的なユースケースを探している方のガイドになれば幸いです。


なぜ Istio なのか?

Istio は、コンテナと共にデプロイされた Envoy Proxy を管理するコントロールプレーンとして機能します。VirtualService、DestinationRule、AuthorizationPolicy といったすべての設定は、最終的に Envoy ネイティブの設定へと変換されます。

これが重要な理由は2つあります。

抽象化のメリット:Istio の抽象化された設定だけで、ほとんどのユースケースをエレガントに解決できる

柔軟な拡張性:標準機能で不十分な場合、EnvoyFilter を通じて Envoy の強力な機能に直接アクセスできる

私たちはインフラ全体で、この「シンプルさ」と「深さ」の両方を駆使しています。


1. Proxy Protocol による実クライアント IP の保持

課題
BotManager にとって、正確なクライアント IP は何よりも重要です。IP が正しくなければ、ボット検知の精度が著しく低下してしまうからです。

トラフィックが AWS の NLB (Network Load Balancer) を経由すると、元のクライアント IP が失われてしまう問題がありました。

解決策
私たちは EnvoyFilter を使い、Proxy Protocol でこの問題を解決しました。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: botmanager-proxy-protocol
  namespace: istio-ingress
spec:
  workloadSelector:
    labels:
      scp: botmanager
  configPatches:
  - applyTo: LISTENER
    patch:
      operation: MERGE
      value:
        listener_filters:
        - name: envoy.filters.listener.proxy_protocol
        - name: envoy.filters.listener.tls_inspector

Tips
ソース IP の保持やネットワークトポロジ設定の詳細については、Istio 公式ブログの Configuring Gateway Network Topology を参照することを強くお勧めします。

また、セキュリティが重要な操作では X-Forwarded-For よりも X-Envoy-External-Address を優先しています。XFF とは異なり、このヘッダーは Envoy 自身によって設定され、外部クライアントによる偽装が不可能です。


2. IP ベースのアクセス制御(ホワイトリスト)

Swagger ドキュメントなどの内部 API を保護するため、AuthorizationPolicy を使用してアクセスをオフィス IP のみに制限しています。

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: stclab-internal
spec:
  action: DENY
  selector:
    matchLabels:
      scp: netfunnel
  rules:
  - from:
    - source:
        notRemoteIpBlocks:
        - 180.224.xxx.xxx/32 # Office IP
    to:
    - operation:
        paths:
        - /swagger/index.html

DENY アクションと notRemoteIpBlocks を組み合わせることで、「明示的に許可された IP 以外をすべて遮断する」というホワイトリスト形式のポリシーを、シンプルかつ効果的に構築できます。

3. クエリパラメータベースのルーティング

背景
NetFUNNEL は、待機列の状態をインメモリで管理しています。データの一貫性を保つため、各テナントのリクエストは常に同じバックエンドインスタンスに到達しなければなりません。

そこで、クエリパラメータを用いた明示的なルーティングを実装しました。

apiVersion: networking.istio.io/v1
kind: VirtualService
spec:
  http:
  - match:
    - queryParams:
        sticky:
          exact: nf1
    route:
    - destination:
        host: netfunnel-0 # First instance
  - match:
    - queryParams:
        sticky:
          exact: nf2
    route:
    - destination:
        host: netfunnel-1 # Second instance

自動ハッシュではなく、このアプローチを採用した理由
アプリケーションチームと連携し、クライアントが sticky パラメータでターゲットインスタンスを直接指定するようにしました。これにより以下のメリットが得られます。

決定論的ルーティング:クライアントはどのインスタンスがリクエストを処理するかを正確に把握できる

デバッグの分離:問題のあるテナントを特定のインスタンスにルーティングして調査できる

スムーズな移行: メンテナンス中にテナントをインスタンス間で移動させやすい

代替案:Consistent Hash
厳密な一貫性を必要としないサービスには Consistent Hash を使用し、tenant_id に基づいて自動的に同じバックエンドへ振り分けています。

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: netfunnel-consistent-hash
spec:
  host: netfunnel
  trafficPolicy:
    loadBalancer:
      consistentHash:
        httpQueryParameterName: tenant_id

コアサービスには「明示的ルーティング」、周辺サーっビスには「Consistent Hash」という使い分けが肝要です。


4. Outlier Detection による自動障害隔離

課題
大規模環境では、一つの不健全な Pod サービス全体の品質を低下させます。

解決策
私たちは Outlier Detection を使用して、異常なインスタンスを自動的に切り離しています。

outlierDetection:
      consecutive5xxErrors: 5
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
      minHealthPercent: 30

動作の仕組み

検知:5 回連続で 5xx レスポンスを返した Pod を排出

隔離:排出された Pod は最低 30 秒間隔離

保護:可用性を守るため、Pod 全体の 50% 以上は同時に排出しない

実際の効果
先日、デプロイ時に一つの Pod がクラッシュループに陥りましたが、Outlier Detection が 50 秒以内にその Pod をローテーションから外しました。手動介入なしでトラフィックは健全な Pod にシフトし、サービスへの影響はゼロでした。

5. 長時間接続(Long-Lived Connections)のための Graceful Shutdown

課題
当社のゲートウェイは、10 分以上続くコネクションを処理します。デプロイ時にこれらを突然切断すると、テストが失敗します。

重要な設定ルール
terminationGracePeriodSeconds を terminationDrainDuration よりも長く設定する

apiVersion: apps/v1
kind: Deployment
metadata:
  name: istio-ingress-loader
spec:
  template:
    metadata:
      annotations:
        proxy.istio.io/config: |
          # Envoy drains connections for up to 10 minutes
          terminationDrainDuration: 600s
          proxyMetadata:
            # Exit immediately when all connections are closed
            EXIT_ON_ZERO_ACTIVE_CONNECTIONS: 'true'
    spec:
      # Kubernetes waits 11 minutes before force-killing
      terminationGracePeriodSeconds: 660
info    Checking for active connections...
info    There are still 1316 active connections

info    There are still 1308 active connections

info    There are still 1300 active connections
info    There are still 1292 active connections
info    There are still 1279 active connections
info    There are still 1276 active connections
warn    Envoy proxy is NOT ready: server is terminated: received signal: terminated
info    There are still 1269 active connections
info    There are still 1257 active connections
info    There are still 1252 active connections
info    There are still 1247 active connections
info    There are still 1242 active connections
info    There are still 1235 active connections
info    There are still 1229 active connections
info    There are still 1228 active connections
info    There are still 1223 active connections
info    There are still 1220 active connections
info    Checking for active connections...
info    There are no more active connections. terminating proxy...
warn    Aborting proxy
info    Envoy aborted normally
warn    Aborted proxy instance
info    Agent has successfully terminated

シャットダウンシーケンス

  1. Pod が終了シグナルを受信

  2. Envoy が新規接続の受け入れを停止し、ヘルスチェックで失敗を返し始める

  3. 既存接続は terminationDrainDuration (600 秒) の間、維持される

  4. EXIT_ON_ZERO_ACTIVE_CONNECTIONS により、接続が早く切れれば Pod も早期終了する

  5. 最終的に 660 秒後、Kubernetes が SIGKILL を送信

結果

デプロイ中のコネクションドロップがゼロ

ローリングアップデート中の負荷テストも正常に完了


プロダクション運用での知見

Istio をスケールさせる際のアドバイスをいくつか共有します。

1. シンプルに始める
初日からすべての機能を有効にしないでください。mTLS や Tracing のような複雑な機能は、ビジネス上の必要性が技術的コストを上回った時に導入すべきです。

2. メトリクスのカーディナリティに注意
Envoy は膨大なテレメトリデータを生成し、Prometheus をパンクさせることがあります。本当に必要なメトリクスだけを収集するようにフィルタリングしましょう。

3. EnvoyFilter は慎重に
強力ですが、Istio のアップグレード時に壊れやすい部分です。徹底したドキュメント化と互換性テストは不可欠です。

結論

Istio には学習曲線がありますが、NetFUNNEL や BotManager のような高トラフィックプラットフォームにおいて、それが提供する制御能力は投資に見合う価値があります。

本記事で紹介した5つの機能:

  1. Proxy Protocol - 実クライアント IP の保持

  2. AuthorizationPolicy - IP ベースのアクセス制御

  3. 柔軟なルーティング - クエリパラメータと Consistent Hash

  4. Outlier Detection - 自動障害隔離

  5. Graceful Shutdown - 長時間接続の安全な処理

これらは今や私のインフラの不可欠な要素です。トラフィック管理、セキュリティ、信頼性が重要なサービスを運用しているなら、Istio を検討する価値は十分にあります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?