LESSON 30分

ストーリー

佐藤CTO
サービスメッシュの全体像は掴めたかな
あなた
データプレーンとコントロールプレーンの2層構造、サイドカーパターン…概念は理解できました
佐藤CTO
よし。では実際のプロダクトを見ていこう。最も広く使われているのがIstioだ。データプレーンにEnvoyプロキシを採用し、強力なトラフィック制御とセキュリティ機能を提供する。YAMLの設定だけでカナリアリリースやmTLSが実現できるんだ
あなた
設定の具体例を見ながら学びたいです
佐藤CTO
もちろんだ。実際の設定ファイルを書きながら進めよう

Istioのアーキテクチャ

Istioはistiod(コントロールプレーン)とEnvoyプロキシ(データプレーン)で構成されます。

graph TD
    subgraph Istio["Istio Architecture"]
        subgraph CP["istiod(コントロールプレーン)"]
            PILOT["Pilot<br/>(設定配信)"]
            CITADEL["Citadel<br/>(証明書管理)"]
            GALLEY["Galley<br/>(設定検証・変換)"]
        end
        subgraph PodA["Pod A"]
            SA["Service A"]
            EA["Envoy Proxy"]
            SA --> EA
        end
        subgraph PodB["Pod B"]
            SB["Service B"]
            EB["Envoy Proxy"]
            SB --> EB
        end
    end

    PILOT -->|xDS API| EA
    PILOT -->|xDS API| EB
    CITADEL -->|証明書配信| EA
    CITADEL -->|証明書配信| EB
    EA <-->|mTLS| EB

    classDef cp fill:#e8f4fd,stroke:#2196f3,color:#333
    classDef pod fill:#d4edda,stroke:#28a745,color:#333
    classDef proxy fill:#fff3cd,stroke:#f0ad4e,color:#333
    class PILOT,CITADEL,GALLEY cp
    class SA,SB pod
    class EA,EB proxy

istiodの3つの機能

コンポーネント旧名称役割
PilotPilotサービスディスカバリ、Envoyへの設定配信(xDS API)
CitadelCitadel証明書の発行・管理、mTLSの自動設定
GalleyGalleyIstio設定の検証・変換・配信

現在のIstioでは、これら3つの機能がistiodという単一バイナリに統合されています。


Envoyプロキシの主要機能

Envoyは高性能なL4/L7プロキシで、Istioのデータプレーンの中核を担います。

Envoyの特徴

特徴説明
L7プロトコル対応HTTP/1.1, HTTP/2, gRPC, WebSocket
動的設定APIによるホットリロード(再起動不要)
豊富なフィルタルーティング、レート制限、認証など
ヘルスチェックアクティブ/パッシブの両方に対応
統計情報詳細なメトリクスをPrometheus形式で出力
分散トレーシングZipkin, Jaeger, OpenTelemetry対応

Envoyのフィルタチェーン

graph TD
    Req["リクエスト"] --> Listener["Listener\nポートでリクエストを受信"]
    Listener --> HTTP["HTTP ConnMgr\nHTTP接続管理"]
    HTTP --> Router["Router\nルーティング判定"]
    Router --> Rate["Rate Limit\nレート制限"]
    Rate --> Auth["Auth\n認証・認可"]
    Auth --> Cluster["Cluster\n宛先クラスタへ転送"]
    Cluster --> Dest["宛先サービス"]

    style Req fill:#dbeafe,stroke:#2563eb,color:#1e40af
    style Listener fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
    style HTTP fill:#fef3c7,stroke:#d97706,color:#92400e
    style Router fill:#fef3c7,stroke:#d97706,color:#92400e
    style Rate fill:#fef3c7,stroke:#d97706,color:#92400e
    style Auth fill:#fef3c7,stroke:#d97706,color:#92400e
    style Cluster fill:#d1fae5,stroke:#059669,color:#065f46
    style Dest fill:#d1fae5,stroke:#059669,color:#065f46

VirtualServiceとDestinationRule

Istioのトラフィック管理は、主にVirtualServiceDestinationRuleの2つのリソースで設定します。

VirtualService

VirtualServiceは、リクエストをどこにルーティングするかを定義します。

# VirtualService: トラフィックルーティングの定義
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
    - order-service  # 対象サービス名
  http:
    # ルール1: ヘッダーベースのルーティング
    - match:
        - headers:
            x-canary:
              exact: "true"
      route:
        - destination:
            host: order-service
            subset: canary  # カナリア版に転送
      timeout: 10s

    # ルール2: 重み付きルーティング(デフォルト)
    - route:
        - destination:
            host: order-service
            subset: stable
          weight: 90  # 90%のトラフィック
        - destination:
            host: order-service
            subset: canary
          weight: 10  # 10%のトラフィック
      retries:
        attempts: 3
        perTryTimeout: 5s
        retryOn: 5xx,reset,connect-failure

DestinationRule

DestinationRuleは、ルーティング先のサブセットとトラフィックポリシーを定義します。

# DestinationRule: 宛先のサブセットとポリシー
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        h2UpgradePolicy: DEFAULT
        http1MaxPendingRequests: 100
        http2MaxRequests: 1000
    loadBalancer:
      simple: ROUND_ROBIN
    outlierDetection:  # 異常検知(サーキットブレーカー)
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50

  subsets:
    - name: stable
      labels:
        version: v1  # v1ラベルのPodを対象
    - name: canary
      labels:
        version: v2  # v2ラベルのPodを対象
      trafficPolicy:
        connectionPool:
          http:
            http2MaxRequests: 100  # カナリアは控えめに

VirtualServiceとDestinationRuleの関係

graph TD
    Client["クライアント\nGET /api/orders"] --> VS["VirtualService\nどこに送るか を判定\n90%→stable, 10%→canary"]
    VS --> DR["DestinationRule\nどうやって送るか を定義\nLB方式 / 接続プール / 異常検知"]
    DR --> Stable["stable\nv1"]
    DR --> Canary["canary\nv2"]

    style Client fill:#dbeafe,stroke:#2563eb,color:#1e40af
    style VS fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px,color:#5b21b6
    style DR fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e
    style Stable fill:#d1fae5,stroke:#059669,color:#065f46
    style Canary fill:#fee2e2,stroke:#dc2626,color:#991b1b

mTLS(相互TLS認証)

Istioはサービス間通信の自動暗号化をmTLSで実現します。

PeerAuthentication

# メッシュ全体にmTLSを強制
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system  # メッシュ全体に適用
spec:
  mtls:
    mode: STRICT  # mTLS必須

---
# 特定のNamespaceだけPERMISSIVE(移行期間中)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: legacy-namespace
  namespace: legacy-services
spec:
  mtls:
    mode: PERMISSIVE  # mTLSと平文の両方を受け入れ

AuthorizationPolicy

# サービス間のアクセス制御
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: order-service-policy
  namespace: production
spec:
  selector:
    matchLabels:
      app: order-service
  rules:
    # API Gatewayからのリクエストのみ許可
    - from:
        - source:
            principals:
              - "cluster.local/ns/production/sa/api-gateway"
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/orders/*"]

    # 在庫サービスからの内部APIは許可
    - from:
        - source:
            principals:
              - "cluster.local/ns/production/sa/inventory-service"
      to:
        - operation:
            methods: ["POST"]
            paths: ["/internal/reserve"]

サーキットブレーカーとレート制限

Envoyによるサーキットブレーカー

# DestinationRuleで設定するサーキットブレーカー
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: payment-service
spec:
  host: payment-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 50       # 最大TCP接続数
      http:
        http1MaxPendingRequests: 100  # 保留中リクエスト上限
        http2MaxRequests: 500         # 最大同時リクエスト数
        maxRequestsPerConnection: 10  # 接続あたり最大リクエスト
        maxRetries: 3                 # 最大リトライ数
    outlierDetection:
      consecutive5xxErrors: 3   # 3回連続5xxでエジェクト
      interval: 10s             # 検知間隔
      baseEjectionTime: 30s     # エジェクト基本時間
      maxEjectionPercent: 30    # 最大エジェクト割合

レート制限

# EnvoyFilterによるレート制限設定
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: rate-limit-filter
  namespace: production
spec:
  workloadSelector:
    labels:
      app: api-gateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
            stat_prefix: http_local_rate_limiter
            token_bucket:
              max_tokens: 100      # バケット最大トークン
              tokens_per_fill: 100 # 補充トークン数
              fill_interval: 60s   # 補充間隔(1分あたり100リクエスト)

デプロイ戦略とIstio

カナリアデプロイ

# Step 1: カナリア版をデプロイ(10%のトラフィック)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
    - order-service
  http:
    - route:
        - destination:
            host: order-service
            subset: stable
          weight: 90
        - destination:
            host: order-service
            subset: canary
          weight: 10

---
# Step 2: 問題なければ50%に増加
# weight: stable=50, canary=50

---
# Step 3: 完全移行
# weight: stable=0, canary=100

---
# Step 4: stableをv2に更新し、canaryサブセットを削除

ブルーグリーンデプロイ

# Blue環境(現行バージョン)が動作中
# Green環境(新バージョン)をデプロイ済み

# 切り替え: 100%のトラフィックをGreenに向ける
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
    - order-service
  http:
    - route:
        - destination:
            host: order-service
            subset: green  # 全トラフィックをGreenへ
          weight: 100

---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  subsets:
    - name: blue
      labels:
        deployment: blue
    - name: green
      labels:
        deployment: green

ヘッダーベースルーティング(テスト用)

# QAチームだけ新バージョンにアクセスできるようにする
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
    - order-service
  http:
    # QAチーム用ヘッダーがある場合→v2にルーティング
    - match:
        - headers:
            x-qa-team:
              exact: "true"
      route:
        - destination:
            host: order-service
            subset: v2-testing

    # その他→現行v1
    - route:
        - destination:
            host: order-service
            subset: v1-stable

Istio導入のベストプラクティス

段階的導入ステップ

graph TD
    P1["Phase 1: 可観測性のみ"] --> P2["Phase 2: セキュリティ強化"]
    P2 --> P3["Phase 3: トラフィック管理"]
    P3 --> P4["Phase 4: 高度な機能"]

    P1 -.- P1a["サイドカー注入を有効化\nmTLS = PERMISSIVE\nメトリクス・トレーシング収集開始"]
    P2 -.- P2a["mTLS = STRICT\nAuthorizationPolicy導入\nセキュリティ監査"]
    P3 -.- P3a["VirtualService/DestinationRule活用\nカナリアデプロイ導入\nサーキットブレーカー設定"]
    P4 -.- P4a["フォールトインジェクション\nレート制限\nマルチクラスタメッシュ"]

    style P1 fill:#dbeafe,stroke:#2563eb,color:#1e40af
    style P2 fill:#fef3c7,stroke:#d97706,color:#92400e
    style P3 fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
    style P4 fill:#d1fae5,stroke:#059669,color:#065f46
    style P1a fill:#f3f4f6,stroke:#9ca3af,color:#374151
    style P2a fill:#f3f4f6,stroke:#9ca3af,color:#374151
    style P3a fill:#f3f4f6,stroke:#9ca3af,color:#374151
    style P4a fill:#f3f4f6,stroke:#9ca3af,color:#374151

リソース見積もり

コンポーネントCPU(リクエスト)メモリ(リクエスト)備考
istiod500m2Giコントロールプレーン
Envoyサイドカー100m128MiPod数分必要
Kiali250m512Miダッシュボード
Prometheus500m4Giメトリクス保存量に依存
Jaeger500m2Giトレーシング

まとめ

ポイント内容
Istioアーキテクチャistiod(コントロールプレーン)+ Envoy(データプレーン)
VirtualServiceリクエストのルーティングルールを定義
DestinationRuleルーティング先のポリシー(LB、サーキットブレーカー)を定義
mTLSPeerAuthenticationとAuthorizationPolicyで通信を保護
サーキットブレーカーoutlierDetectionで異常なエンドポイントを自動除外
デプロイ戦略重み付きルーティングでカナリア/ブルーグリーンを実現

チェックリスト

  • Istioのアーキテクチャ(istiod + Envoy)を説明できる
  • VirtualServiceとDestinationRuleの役割の違いを説明できる
  • mTLSの設定方法(PeerAuthentication)を理解した
  • サーキットブレーカーの設定方法を理解した
  • カナリアデプロイのYAML設定を書ける
  • Istio導入の段階的ステップを理解した

次のステップへ

Istio/Envoyの基礎を理解したところで、次はサービスメッシュが提供する「トラフィック管理とオブザーバビリティ」を詳しく学びます。分散トレーシングやメトリクス収集の具体的な方法を見ていきましょう。


推定読了時間: 30分