Skip to content
Published on

Service Mesh完全ガイド2025: Istio vs Linkerd, mTLS, トラフィック管理, Observability

Authors

はじめに:なぜService Meshが必要なのか?

マイクロサービスアーキテクチャが普及するにつれ、数十から数百のサービスがネットワークを通じて通信する環境が一般的になりました。この複雑なサービス間通信で、以下のような問題が繰り返し発生します。

セキュリティの課題: サービス間通信が暗号化されていないと、内部ネットワークでも盗聴が可能です。各サービスでTLSを個別に実装し、証明書を管理するのは膨大な運用負荷です。

可観測性(Observability)の欠如: リクエストが複数のサービスを経由する際、どこでレイテンシが発生しているか、どのサービスがエラーを返しているかを把握するのが困難です。

トラフィック制御の難しさ: カナリアデプロイ、A/Bテスト、サーキットブレーカーなどの高度なトラフィック管理をアプリケーションコードに直接実装する必要があります。

Service Meshはこれらすべての問題をインフラレイヤーで解決します。アプリケーションコードを一行も変更せずに、セキュリティ/可観測性/トラフィック制御をネットワークレベルで透過的に追加できます。


1. Service Meshアーキテクチャ

Service Meshは大きく2つのプレーン(plane)で構成されます。

1.1 データプレーン(Data Plane)

データプレーンは実際のサービストラフィックを処理するプロキシの集合です。各サービスPodにサイドカーとしてデプロイされ、すべてのインバウンド/アウトバウンドトラフィックをインターセプトします。

┌─────────────────────────────────────────────┐
Pod│  ┌─────────────┐    ┌─────────────────────┐ │
│  │  Application │◄──►│   Sidecar Proxy     │ │
│  │  Container  (Envoy/linkerd2)   │ │
│  └─────────────┘    └─────────────────────┘ │
└─────────────────────────────────────────────┘

サイドカープロキシの主な役割:

  • すべてのトラフィックを透過的にインターセプト(iptablesルールを活用)
  • mTLS暗号化/復号化の実行
  • ロードバランシング(ラウンドロビン、最小接続数など)
  • メトリクス収集と分散トレーシングヘッダーの伝播
  • リトライ、タイムアウト、サーキットブレーキングの適用

1.2 コントロールプレーン(Control Plane)

コントロールプレーンはデータプレーンのプロキシを中央で管理・設定します。

Istioのコントロールプレーン(Istiod):

# Istiodが管理する主な機能
- サービスディスカバリ: Kubernetes APIからサービス一覧を同期
- 設定配布: VirtualService, DestinationRuleをEnvoy設定に変換
- 証明書管理: mTLS用証明書の発行/更新(内蔵CA)
- ポリシー適用: AuthorizationPolicy, PeerAuthenticationの配布

Linkerdのコントロールプレーン:

# Linkerdコントロールプレーンコンポーネント
- destination: サービスディスカバリ + ポリシー配布
- identity: mTLS証明書発行(trust anchor基盤)
- proxy-injector: Pod作成時のサイドカー自動注入
- heartbeat: テレメトリ収集

2. Istio深掘り

2.1 Istioアーキテクチャ概要

Istioは最も機能が豊富なService Meshです。Google、IBM、Lyftが共同開発し、現在CNCFの卒業プロジェクトです。

# Istioインストール(istioctl)
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.24.0
export PATH=$PWD/bin:$PATH

# プロファイルベースのインストール
istioctl install --set profile=demo -y

# ネームスペースにサイドカー自動注入を有効化
kubectl label namespace default istio-injection=enabled

2.2 Envoyサイドカープロキシ

Istioのデータプレーンは Envoy プロキシを使用します。EnvoyはC++で書かれた高性能L4/L7プロキシです。

# Envoyの主要機能
- HTTP/1.1, HTTP/2, gRPCサポート
- 自動リトライとサーキットブレーキング
- 動的設定更新(xDS API)
- 豊富なメトリクスとトレーシング
- WebAssembly(Wasm)拡張サポート
- ホットリスタート(graceful restart)

メモリオーバーヘッドはPod当たり約40-100MBで、CPUオーバーヘッドはリクエストあたり数ミリ秒レベルです。

2.3 VirtualService

VirtualServiceはIstioでトラフィックルーティングルールを定義する中核リソースです。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
    - reviews
  http:
    # カナリアデプロイ: 90% v1, 10% v2
    - route:
        - destination:
            host: reviews
            subset: v1
          weight: 90
        - destination:
            host: reviews
            subset: v2
          weight: 10
      timeout: 5s
      retries:
        attempts: 3
        perTryTimeout: 2s
        retryOn: 5xx,reset,connect-failure

2.4 DestinationRule

DestinationRuleはルーティング決定後のトラフィックに適用するポリシーを定義します。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews-destination
spec:
  host: reviews
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        h2UpgradePolicy: DEFAULT
        http1MaxPendingRequests: 100
        http2MaxRequests: 1000
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
    loadBalancer:
      simple: LEAST_REQUEST
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

2.5 Gateway

Istio Gatewayはメッシュ外部から入ってくるトラフィックを管理します。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: bookinfo-cert
      hosts:
        - "bookinfo.example.com"

2.6 PeerAuthentication

PeerAuthenticationはサービス間のmTLSポリシーを定義します。

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  # メッシュ全体にSTRICT mTLSを適用
  mtls:
    mode: STRICT
---
# 特定のネームスペースにPERMISSIVEモード
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: legacy-compat
  namespace: legacy-apps
spec:
  mtls:
    mode: PERMISSIVE

2.7 AuthorizationPolicy

AuthorizationPolicyはサービス間のアクセス制御を定義します。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: reviews-viewer
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/default/sa/productpage"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/reviews/*"]

3. Linkerd深掘り

3.1 Linkerdアーキテクチャ概要

Linkerdは軽量さとシンプルさを追求するService Meshです。Buoyantが開発し、CNCFの卒業プロジェクトです。

# Linkerd CLIインストール
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$HOME/.linkerd2/bin:$PATH

# 事前チェック
linkerd check --pre

# インストール
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -

# 検証
linkerd check

# Viz拡張(ダッシュボード + メトリクス)
linkerd viz install | kubectl apply -f -

3.2 linkerd2-proxy: Rustで書かれたマイクロプロキシ

Linkerdの主要な差別化要因はデータプレーンプロキシです。linkerd2-proxyはRustで書かれており、以下の利点があります。

パフォーマンス比較(linkerd2-proxy vs Envoy)
========================================
メモリ使用量:   ~20MB vs ~50-100MB
P99レイテンシ:  ~1ms追加 vs ~2-5ms追加
バイナリサイズ: ~13MB vs ~50MB
セキュリティ:   Rustのメモリ安全性保証
機能範囲:       Service Mesh専用 vs 汎用プロキシ

linkerd2-proxyはService Meshに必要な機能のみを実装することで軽量化を実現しています。Envoyのような汎用プロキシではないため、Wasm拡張などの機能はありませんが、コア機能では優れた性能を発揮します。

3.3 ServiceProfile

LinkerdのServiceProfileはサービスごとのルーティングと可観測性設定を定義します。

apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: webapp.default.svc.cluster.local
  namespace: default
spec:
  routes:
    - name: GET /api/users
      condition:
        method: GET
        pathRegex: /api/users
      responseClasses:
        - condition:
            status:
              min: 500
              max: 599
          isFailure: true
    - name: POST /api/orders
      condition:
        method: POST
        pathRegex: /api/orders
      isRetryable: true
      timeout: 10s

3.4 TrafficSplit(SMI)

LinkerdはSMI(Service Mesh Interface)標準を使用してトラフィック分割を実装します。

apiVersion: split.smi-spec.io/v1alpha4
kind: TrafficSplit
metadata:
  name: webapp-split
  namespace: default
spec:
  service: webapp
  backends:
    - service: webapp-v1
      weight: 900
    - service: webapp-v2
      weight: 100

3.5 Linkerdマルチクラスター

Linkerdはマルチクラスター通信をネイティブでサポートしています。

# マルチクラスター拡張のインストール
linkerd multicluster install | kubectl apply -f -

# リモートクラスターの接続
linkerd multicluster link --cluster-name=west \
  --api-server-address="https://west.example.com:6443" | \
  kubectl apply -f -

# サービスミラーリングの確認
linkerd multicluster gateways

4. Istio vs Linkerd 詳細比較

比較項目IstioLinkerd
データプレーンプロキシEnvoy (C++)linkerd2-proxy (Rust)
メモリオーバーヘッド(Pod当たり)50-100MB10-20MB
P99レイテンシ追加2-5ms0.5-1ms
インストール複雑度高い(様々なプロファイル)低い(単一コマンド)
CRD数50以上10以下
学習曲線急峻緩やか
トラフィック管理非常に豊富(VirtualService)基本的(ServiceProfile)
セキュリティポリシー詳細なRBAC(AuthorizationPolicy)基本的なmTLS + Server/Authorization
プロトコルサポートHTTP, gRPC, TCP, WebSocketHTTP, gRPC, TCP
Wasm拡張サポート非サポート
マルチクラスターサポート(複雑)サポート(比較的シンプル)
Ambient Meshサポート(サイドカーなしモード)該当なし
Gateway API完全サポート部分サポート
コミュニティ規模非常に大きい(CNCF卒業)大きい(CNCF卒業)
運用複雑度高い低い
適した環境大規模、複雑なポリシー小中規模、シンプルさ重視

選択基準のまとめ

Istioを選ぶべき場合:

  • 詳細なトラフィック管理が必要(重み付きルーティング、フォールトインジェクション、トラフィックミラーリング)
  • 複雑なセキュリティポリシーが必要(JWT検証、外部認可)
  • Wasmベースの拡張プラグインが必要
  • Ambient Mesh(サイドカーなしモード)を使用したい

Linkerdを選ぶべき場合:

  • リソースオーバーヘッドを最小化したい
  • 迅速な導入とシンプルな運用を望む
  • コア機能(mTLS、メトリクス、リトライ)で十分
  • 運用チームの規模が小さい

5. mTLS(相互TLS)

5.1 mTLSの仕組み

Service MeshにおけるmTLSはサービス間通信を自動的に暗号化します。

サービスA(クライアント)     サービスB(サーバー)
     |                            |
     |-- ClientHello -----------> |
     |<- ServerHello + サーバー証明書 |
     |-- クライアント証明書 -------> |
     |<- 証明書検証完了 ----------- |
     |                            |
     |<=== 暗号化通信 ============>|

通常のTLSとの違い: mTLSでは双方が証明書を提示・検証するため、サーバーもクライアントの身元を確認できます。

5.2 SPIFFE IDフレームワーク

IstioとLinkerdの両方がSPIFFE(Secure Production Identity Framework For Everyone)標準を使用します。

SPIFFE ID形式:
spiffe://cluster.local/ns/NAMESPACE/sa/SERVICE_ACCOUNT

:
spiffe://cluster.local/ns/production/sa/frontend
spiffe://cluster.local/ns/production/sa/backend-api

SPIFFE IDはKubernetesのServiceAccountにマッピングされ、Podの身元をネットワークレベルで証明します。

5.3 証明書の自動ローテーション

# Istio: 証明書有効期間の設定(MeshConfig)
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      # ワークロード証明書のデフォルトは24時間
      # proxyMetadataでカスタマイズ可能
    certificates: []
  values:
    pilot:
      env:
        # 最大証明書有効期間
        MAX_WORKLOAD_CERT_TTL: "48h"
        # デフォルト証明書有効期間
        DEFAULT_WORKLOAD_CERT_TTL: "24h"

Linkerdの証明書管理:

# Trust anchor作成(10年間有効)
step certificate create root.linkerd.cluster.local ca.crt ca.key \
  --profile root-ca --no-password --insecure --not-after=87600h

# Issuer証明書作成(48時間有効、自動更新)
step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \
  --profile intermediate-ca --not-after=48h --no-password --insecure \
  --ca ca.crt --ca-key ca.key

# 証明書でインストール
linkerd install \
  --identity-trust-anchors-file ca.crt \
  --identity-issuer-certificate-file issuer.crt \
  --identity-issuer-key-file issuer.key | kubectl apply -f -

6. トラフィック管理

6.1 カナリアリリース

# Istio - 段階的カナリアデプロイ
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            x-canary-user:
              exact: "true"
      route:
        - destination:
            host: reviews
            subset: v2
    - route:
        - destination:
            host: reviews
            subset: v1
          weight: 95
        - destination:
            host: reviews
            subset: v2
          weight: 5

Flaggerによる自動カナリア:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: reviews
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: reviews
  service:
    port: 9080
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
      - name: request-success-rate
        thresholdRange:
          min: 99
        interval: 1m
      - name: request-duration
        thresholdRange:
          max: 500
        interval: 1m

6.2 トラフィックミラーリング(シャドートラフィック)

本番トラフィックのコピーを新バージョンに送信し、実環境での動作を検証します。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews-mirror
spec:
  hosts:
    - reviews
  http:
    - route:
        - destination:
            host: reviews
            subset: v1
      mirror:
        host: reviews
        subset: v2
      mirrorPercentage:
        value: 100.0

ミラーリングの主な特性:

  • ミラーされたトラフィックのレスポンスは破棄(クライアントに影響なし)
  • Hostヘッダーに-shadowサフィックスが追加
  • 新バージョンのパフォーマンスとエラー率を実トラフィックで検証可能

6.3 フォールトインジェクション

意図的に障害を注入してシステムの復元力をテストします。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings-fault
spec:
  hosts:
    - ratings
  http:
    - fault:
        delay:
          percentage:
            value: 10
          fixedDelay: 5s
        abort:
          percentage:
            value: 5
          httpStatus: 503
      route:
        - destination:
            host: ratings

6.4 サーキットブレーキング

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews-circuit-breaker
spec:
  host: reviews
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 50
      http:
        http1MaxPendingRequests: 100
        http2MaxRequests: 100
        maxRequestsPerConnection: 10
    outlierDetection:
      consecutive5xxErrors: 3
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 30
      minHealthPercent: 70

6.5 リトライとタイムアウト

# Istio
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews-retry
spec:
  hosts:
    - reviews
  http:
    - timeout: 10s
      retries:
        attempts: 3
        perTryTimeout: 3s
        retryOn: 5xx,reset,connect-failure,retriable-4xx
      route:
        - destination:
            host: reviews
# Linkerd ServiceProfile
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: reviews.default.svc.cluster.local
spec:
  routes:
    - name: GET /reviews
      condition:
        method: GET
        pathRegex: /reviews/.*
      isRetryable: true
      timeout: 10s

7. Observability(可観測性)

7.1 メトリクス(Prometheus)

Service Meshは以下のメトリクスを自動収集します。

ゴールデンシグナル(Golden Signals)
================================
1. レイテンシ: リクエスト処理時間
2. トラフィック: 秒あたりリクエスト数
3. エラー率: 失敗したリクエストの割合
4. 飽和度: リソース使用率

Istio主要メトリクス:
- istio_requests_total: 総リクエスト数(ソース、宛先、レスポンスコード別)
- istio_request_duration_milliseconds: リクエスト所要時間
- istio_request_bytes / istio_response_bytes: リクエスト/レスポンスサイズ

Linkerd主要メトリクス:
- request_total: 総リクエスト数
- response_latency_ms: レスポンスレイテンシ
- tcp_open_total: TCP接続数
# Prometheusスクレイプ設定(Istio)
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
data:
  prometheus.yml: |
    scrape_configs:
      - job_name: 'envoy-stats'
        metrics_path: /stats/prometheus
        kubernetes_sd_configs:
          - role: pod
        relabel_configs:
          - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
            action: keep
            regex: true

7.2 分散トレーシング(Jaeger / Zipkin)

Service Meshはトレーシングヘッダーを自動的に伝播し、リクエストの全経路を追跡します。

# Istioテレメトリ設定
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: jaeger
      randomSamplingPercentage: 10
      customTags:
        environment:
          literal:
            value: "production"

重要: アプリケーションは以下のヘッダーを伝播する必要があります(自動生成はされますが、伝播はアプリケーションの責任です)。

伝播すべきトレーシングヘッダー:
- x-request-id
- x-b3-traceid
- x-b3-spanid
- x-b3-parentspanid
- x-b3-sampled
- x-b3-flags
- traceparent (W3C Trace Context)
- tracestate

7.3 Kialiダッシュボード

KialiはIstio専用の可観測性ダッシュボードです。

# Kialiインストール
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/kiali.yaml

# ダッシュボードアクセス
istioctl dashboard kiali

Kialiの主な機能:

  • サービストポロジーグラフの可視化
  • リアルタイムトラフィックフロー監視
  • Istio設定の検証とエラー検出
  • 分散トレーシング統合
  • メトリクスベースのヘルスステータス表示

7.4 Grafanaダッシュボード

# Grafana + 事前構成済みダッシュボードのインストール
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/grafana.yaml

# ダッシュボードアクセス
istioctl dashboard grafana

主なダッシュボード:

  • Mesh Dashboard: メッシュ全体のトラフィック概要
  • Service Dashboard: 個別サービスメトリクス
  • Workload Dashboard: ワークロード別詳細情報
  • Performance Dashboard: P50/P90/P99レイテンシ

8. Kubernetes Gateway API

8.1 Gateway APIとは

Kubernetes Gateway APIは既存のIngressを置き換える次世代トラフィック管理標準です。ロールベースの設計でインフラ/クラスター/アプリケーション管理者の責任を明確に分離します。

# GatewayClass: インフラ管理者が定義
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
# Gateway: クラスター管理者が定義
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  gatewayClassName: istio
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: bookinfo-tls
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              expose: "true"
---
# HTTPRoute: アプリケーション開発者が定義
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: bookinfo-route
spec:
  parentRefs:
    - name: bookinfo-gateway
  hostnames:
    - "bookinfo.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /reviews
      backendRefs:
        - name: reviews
          port: 9080
          weight: 90
        - name: reviews-v2
          port: 9080
          weight: 10

8.2 Istio Gateway vs Kubernetes Gateway API

従来のIstioアプローチ:
  Gateway + VirtualService + DestinationRule

Kubernetes Gateway APIアプローチ:
  GatewayClass + Gateway + HTTPRoute

利点:
  - 標準化されたAPI(実装間の移植性)
  - ロールベースのアクセス制御
  - より良いネームスペース分離
  - Istio, Linkerd, Ciliumなどで同じAPIを使用可能

9. Ambient Mesh

9.1 サイドカーの限界

従来のサイドカーアプローチの問題点:

  • Pod当たり50-100MBの追加メモリ
  • すべてのリクエストにプロキシホップ追加(レイテンシ)
  • サイドカー注入のためのPod再起動が必要
  • リソースのオーバープロビジョニング

9.2 Ambient Meshアーキテクチャ

IstioのAmbient Meshはサイドカーなしでサービスメッシュを実装する新しいモードです。

従来のサイドカーモード:
+--------------+    +--------------+
| App + Envoy  |--->| App + Envoy  |
+--------------+    +--------------+

Ambient Meshモード:
+--------------+    +--------------+
|     App      |    |     App      |
+------+-------+    +-------+------+
       |                    |
+------+--------------------+------+  <-- ztunnel(ノード当たり1つ、L4+------------------+---------------+
                   |
            +------+------+          <-- waypointプロキシ(オプション、L7            |   Waypoint  |
            +-------------+

ztunnel (Zero Trust Tunnel):

  • ノード当たり1つのDaemonSetとして実行
  • L4機能のみを担当: mTLS、基本認証
  • Rustで記述、非常に軽量
  • Pod再起動不要

Waypointプロキシ:

  • L7機能が必要な場合にのみデプロイ
  • ネームスペースまたはサービス単位でデプロイ可能
  • Envoyベース、完全なL7機能を提供
# AmbientモードでIstioインストール
istioctl install --set profile=ambient -y

# ネームスペースをAmbientメッシュに追加
kubectl label namespace default istio.io/dataplane-mode=ambient

# Waypointプロキシのデプロイ(L7機能が必要な場合)
istioctl waypoint apply --namespace default --name reviews-waypoint

9.3 Ambient Meshの利点

リソース削減比較(100 Podクラスター基準):
========================================
               サイドカーモード   Ambientモード
メモリ:        5-10GB追加        200-500MB追加
CPU:           かなりのオーバーヘッド  最小限のオーバーヘッド
運用:          サイドカー管理      ztunnel DaemonSetのみ管理
アップグレード: Pod再起動必要      ztunnelローリングアップデート

10. セキュリティ深掘り

10.1 RBAC(ロールベースのアクセス制御)

# ネームスペースレベルの拒否ポリシー
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  # ルールが空の場合、すべてのリクエストを拒否
  {}
---
# 特定のサービスのみ許可
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: ALLOW
  rules:
    - from:
        - source:
            namespaces: ["production"]
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/*"]
      when:
        - key: request.headers[x-api-version]
          values: ["v1", "v2"]

10.2 JWT検証

# RequestAuthentication: JWT検証の定義
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-auth
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  jwtRules:
    - issuer: "https://auth.example.com"
      jwksUri: "https://auth.example.com/.well-known/jwks.json"
      forwardOriginalToken: true
      outputPayloadToHeader: "x-jwt-payload"
---
# JWTクレームに基づく認可
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: ALLOW
  rules:
    - from:
        - source:
            requestPrincipals: ["https://auth.example.com/*"]
      when:
        - key: request.auth.claims[role]
          values: ["admin", "editor"]

10.3 外部認可(External Authorization)

# 外部認可サービス連携
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ext-authz
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: CUSTOM
  provider:
    name: "opa-ext-authz"
  rules:
    - to:
        - operation:
            paths: ["/admin/*"]
# MeshConfigに外部認可プロバイダーを登録
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    extensionProviders:
      - name: "opa-ext-authz"
        envoyExtAuthzGrpc:
          service: "opa.opa-system.svc.cluster.local"
          port: 9191
          includeRequestBodyInCheck:
            maxRequestBytes: 1024

11. 本番運用ベストプラクティス

11.1 リソース制限の設定

# Istioサイドカーリソース制限
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      concurrency: 2
  values:
    global:
      proxy:
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi

11.2 段階的ロールアウト戦略

# ステップ1: PERMISSIVE mTLS(既存トラフィックを許可)
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: PERMISSIVE
EOF

# ステップ2: メトリクス監視(mTLSトラフィック比率を確認)
# istio_requests_totalメトリクスでconnection_security_policyを確認

# ステップ3: STRICT mTLSへ切り替え
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: STRICT
EOF

11.3 デバッグツール

# Istioプロキシステータス確認
istioctl proxy-status

# Envoy設定ダンプ
istioctl proxy-config all POD_NAME -o json

# ルーティングルール確認
istioctl proxy-config route POD_NAME

# クラスター設定確認
istioctl proxy-config cluster POD_NAME

# 分析ツール(設定エラー検出)
istioctl analyze --all-namespaces

# Linkerd診断
linkerd check
linkerd diagnostics proxy-metrics POD_NAME
linkerd viz stat deploy
linkerd viz top deploy/webapp
linkerd viz tap deploy/webapp

11.4 Horizontal Pod Autoscaler連携

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: reviews-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: reviews
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: istio_requests_per_second
        target:
          type: AverageValue
          averageValue: "100"
    - type: Pods
      pods:
        metric:
          name: istio_request_duration_milliseconds_p99
        target:
          type: AverageValue
          averageValue: "500"

11.5 アップグレード戦略

# Istioカナリアアップグレード
# 1. 新バージョンのコントロールプレーンをインストール(リビジョンベース)
istioctl install --set revision=1-24-0

# 2. ネームスペースラベル変更で段階的に切り替え
kubectl label namespace default istio.io/rev=1-24-0 --overwrite

# 3. Pod再起動で新プロキシを適用
kubectl rollout restart deployment -n default

# 4. 旧バージョンの削除
istioctl uninstall --revision 1-23-0

12. Service Meshを使うべきでない場合

Service Meshは強力ですが、すべての環境に適しているわけではありません。

使うべきでない状況:

  1. サービス数が少ない場合: 5つ以下のサービスなら、Service Meshの複雑性がメリットを上回る可能性があります。

  2. チームがKubernetesに不慣れな場合: Service MeshはKubernetesの上に追加される複雑性レイヤーです。

  3. リソースが極端に制限されている場合: サイドカープロキシのメモリ/CPUオーバーヘッドを許容できない時。

  4. 極端な低レイテンシが求められる場合: マイクロ秒単位のレイテンシが重要な高頻度取引(HFT)のような環境。

代替手段の検討:

シンプルなmTLSのみ: cert-manager + サービス自体のTLS
基本的な可観測性: OpenTelemetryの直接計装
シンプルなロードバランシング: Kubernetes Service (ClusterIP)
イングレスのみ: NGINX Ingress ControllerまたはTraefik
ネットワークポリシー: Kubernetes NetworkPolicyまたはCilium

クイズ

Q1: Service Meshのデータプレーンとコントロールプレーンの役割を説明してください。

データプレーン: サイドカープロキシの集合で、実際のサービストラフィックをインターセプトして処理します。mTLS暗号化、ロードバランシング、メトリクス収集、リトライ/タイムアウトなどを実行します。IstioはEnvoy、Linkerdはlinkerd2-proxyを使用します。

コントロールプレーン: データプレーンのプロキシを中央で管理・設定します。サービスディスカバリ、証明書発行、ポリシー配布を担当します。IstioはIstiod、Linkerdはdestination/identity/proxy-injectorコンポーネントで構成されます。

Q2: mTLSと通常のTLSの主な違いは何ですか?

通常のTLSではクライアントのみがサーバーの証明書を検証します。mTLS(相互TLS)では双方が証明書を提示・検証します。

  • クライアントがサーバーの証明書を検証(通常のTLSと同じ)
  • サーバーもクライアントの証明書を検証(mTLSの追加ステップ)
  • これによりサービス間の双方向身元確認が可能
  • SPIFFE標準を使用してサービスの身元をKubernetes ServiceAccountにマッピング
Q3: IstioのAmbient Meshが解決する問題とアーキテクチャを説明してください。

解決する問題: 従来のサイドカー方式はPod当たり50-100MBのメモリオーバーヘッド、サイドカー注入のためのPod再起動が必要、すべてのリクエストにプロキシホップが追加されるなどの問題があります。

アーキテクチャ:

  • ztunnel: ノード当たり1つのDaemonSetとして実行されるL4プロキシ。Rustで記述され非常に軽量で、mTLSと基本認証のみを担当します。
  • Waypointプロキシ: L7機能が必要な場合にのみ選択的にデプロイ。EnvoyベースでVirtualService、トラフィック管理など完全なL7機能を提供します。

100 Podクラスター基準でメモリ使用量が5-10GB(サイドカー)から200-500MB(Ambient)に大幅削減されます。

Q4: IstioとLinkerdのどちらをどのような状況で選ぶべきですか?

Istioを選ぶべき場合:

  • 詳細なトラフィック管理が必要(重み付きルーティング、フォールトインジェクション、ミラーリング)
  • 複雑なセキュリティポリシー(JWT検証、外部認可、RBAC)
  • Wasm拡張プラグインが必要
  • Ambient Mesh(サイドカーなしモード)使用

Linkerdを選ぶべき場合:

  • リソースオーバーヘッドの最小化(Pod当たり10-20MB)
  • 迅速な導入とシンプルな運用
  • コア機能(mTLS、メトリクス、リトライ)で十分
  • 小規模運用チーム
Q5: Service Meshを導入すべきでない状況はいつですか?
  1. 5つ以下のサービス: 複雑性がメリットを上回ります
  2. チームがKubernetesに不慣れ: Service Meshはさらなる複雑性レイヤーです
  3. 極端なリソース制限: サイドカーのメモリ/CPUオーバーヘッドを許容できない
  4. 極端な低レイテンシ要件: マイクロ秒単位のレイテンシが重要な環境(HFTなど)

代替手段: cert-manager(mTLS)、OpenTelemetry(可観測性)、Kubernetes NetworkPolicy(ネットワークセキュリティ)、NGINX Ingress(イングレス)


参考資料

  1. Istio公式ドキュメント
  2. Linkerd公式ドキュメント
  3. Envoy Proxy公式ドキュメント
  4. CNCFサービスメッシュランドスケープ
  5. Kubernetes Gateway API
  6. SPIFFE標準
  7. Istio Ambient Mesh公式ブログ
  8. Linkerdベンチマーク
  9. Flagger - Progressive Delivery
  10. Kiali公式ドキュメント
  11. SMI (Service Mesh Interface)
  12. Istio in Action (Manning)
  13. NISTゼロトラストアーキテクチャ (SP 800-207)