EnvoyとKongの世界を探求し、トラフィック管理、セキュリティ、パフォーマンス最適化の高度なパターンを学びましょう。マルチテナントルーティング、カスタムプラグイン、そして最も慎重なセキュリティ専門家も納得するゼロトラストアーキテクチャの実装方法について学ぶことができます。

トラフィック管理: リクエストの無法地帯を制御する

まずはトラフィック管理から始めましょう。マイクロサービスの世界では、トラフィック管理は猫を集めるようなもので、混沌として予測不可能で、時には面白いこともあります。

ロードバランシング: ジム愛好者だけのものではない

EnvoyとKongは、単純なラウンドロビン戦略を超えた高度なロードバランシング機能を提供します。いくつかの高度な技術を見てみましょう:

  • 最小リクエスト: 最もアクティブなリクエストが少ないインスタンスにリクエストをルーティングします。気まぐれなサービスに最適です。
  • 重み付きラウンドロビン: 異なるインスタンスに異なる重みを割り当てることができます。強力なサーバーが他のサーバーよりも多くの負荷を処理できる場合に便利です。
  • リングハッシュ: キーに基づいてリクエストを同じインスタンスに一貫してマッピングします。キャッシングや同じユーザーからのリクエストを常に同じサーバーに送信したい場合に最適です。

Envoyで重み付きロードバランシングを設定する例を見てみましょう:


clusters:
  - name: my_backend_service
    type: STRICT_DNS
    lb_policy: WEIGHTED_ROUND_ROBIN
    load_assignment:
      cluster_name: my_backend_service
      endpoints:
        - lb_endpoints:
          - endpoint:
              address:
                socket_address:
                  address: backend1.example.com
                  port_value: 8080
            load_balancing_weight: 75
          - endpoint:
              address:
                socket_address:
                  address: backend2.example.com
                  port_value: 8080
            load_balancing_weight: 25

サーキットブレイキング: 時には引き際を知ることも大切

サーキットブレイキングは、サービスのバウンサーのようなものです。失敗しているサービスがシステム全体をダウンさせるのを防ぎます。EnvoyとKongの両方がサーキットブレイキングをサポートしていますが、ここではEnvoyの実装を見てみましょう:


clusters:
  - name: my_backend_service
    type: STRICT_DNS
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 1000
          max_pending_requests: 1000
          max_requests: 1000
          max_retries: 3

この設定は、接続、保留中のリクエスト、アクティブなリクエスト、およびリトライのしきい値を設定します。これらのしきい値を超えると、Envoyはシステムを保護するためにリクエストを拒否し始めます。

マルチテナントルーティング: 他者と仲良くする

マルチテナント環境では、異なるテナントのトラフィックが分離され、適切にルーティングされることを確認する必要があります。Kongは強力なルーティング機能でこの分野で優れています。

幸福へのルート

Kongでマルチテナントルーティングを設定する例を見てみましょう:


# サービスを作成
curl -i -X POST http://localhost:8001/services \
  --data name=myservice \
  --data url='http://myservice.com'

# テナントAのルートを作成
curl -i -X POST http://localhost:8001/services/myservice/routes \
  --data 'hosts[]=tenanta.myapi.com' \
  --data 'paths[]=/v1/tenanta'

# テナントBのルートを作成
curl -i -X POST http://localhost:8001/services/myservice/routes \
  --data 'hosts[]=tenantb.myapi.com' \
  --data 'paths[]=/v1/tenantb'

この設定により、テナントAとテナントBのリクエストがそれぞれのエンドポイントに適切にルーティングされることが保証されます。

リクエスト変換: APIを変形する

時には、バックエンドサービスがクライアントとは異なる方言を話すことがあります。そこでリクエスト変換が役立ちます。Kongのリクエストトランスフォーマープラグインは、APIのための万能翻訳機のようなものです。

翻訳で迷子にならない!

リクエストトランスフォーマープラグインを使用してヘッダーやクエリパラメータを変更する方法を見てみましょう:


curl -X POST http://localhost:8001/routes/{route_id}/plugins \
    --data "name=request-transformer" \
    --data "config.add.headers=x-tenant-id:$(tenant_id)" \
    --data "config.add.querystring=version:v2" \
    --data "config.rename.headers=x-old-header:x-new-header"

この設定は、テナントIDヘッダーを追加し、バージョンクエリパラメータを追加し、既存のヘッダーをリネームします。バックエンドサービスに到達する前にリクエストにメイクオーバーを施すようなものです。

高度なレート制限: パーティーを制御する

レート制限は、APIを悪用から保護し、公平な使用を確保するために重要です。しかし、基本的なレート制限はもう古いです。Kongを使った高度なレート制限技術を見てみましょう。

強化されたレート制限

Kongのレートリミッティングプラグインは、ヘッダー値やコンシューマーグループによる制限などの高度な機能を提供します。設定例を見てみましょう:


curl -X POST http://localhost:8001/plugins \
    --data "name=rate-limiting" \
    --data "config.limit=5" \
    --data "config.window_size=30" \
    --data "config.limit_by=header" \
    --data "config.header_name=x-consumer-group"

この設定は、コンシューマーグループヘッダーに基づいてリクエストを制限し、異なるタイプのユーザーやテナントに対して階層化されたレート制限を実装することができます。

カスタムプラグイン開発: 時には自分で作る必要がある

市販のプラグインは素晴らしいですが、時にはオーダーメイドのものが必要です。EnvoyとKongの両方が、機能を拡張するためのカスタムプラグインの開発を可能にします。

自分だけのKongプラグインを作る

カスタムKongプラグインの一例を見てみましょう:


local CustomPlugin = {
  PRIORITY = 1000,
  VERSION = "1.0.0",
}

function CustomPlugin:access(conf)
  -- カスタムロジックをここに
  kong.log.debug("Hello from CustomPlugin!")
  
  local headers = kong.request.get_headers()
  if not headers["x-api-key"] then
    return kong.response.exit(401, { message = "Missing API key" })
  end
end

return CustomPlugin

このシンプルなプラグインは、APIキーの存在を確認し、欠落している場合は401を返します。可能性は無限大です。カスタム認証、複雑な変換、さらには外部サービスとの統合を実装することもできます。

セキュリティのベストプラクティス: サービスとしてのパラノイア

APIの世界では、セキュリティは重要であるだけでなく、不可欠です。EnvoyとKongで実装できる高度なセキュリティパターンを探ってみましょう。

mTLS: 技術における信頼問題は健全

相互TLS(mTLS)は、クライアントとサーバーの両方が互いの証明書を検証することを保証します。EnvoyでmTLSを設定する方法を見てみましょう:


listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 8443
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: service_backend
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
          require_client_certificate: true
          common_tls_context:
            tls_certificates:
            - certificate_chain:
                filename: "/etc/envoy/certs/server.crt"
              private_key:
                filename: "/etc/envoy/certs/server.key"
            validation_context:
              trusted_ca:
                filename: "/etc/envoy/certs/ca.crt"

JWT検証: 誰がそこにいるのか?

JSON Web Tokens(JWT)は、認証と認可のための一般的な方法です。Kongのjwtプラグインは、JWTの検証を簡単にします:


curl -X POST http://localhost:8001/routes/{route_id}/plugins \
    --data "name=jwt" \
    --data "config.secret_is_base64=false" \
    --data "config.claims_to_verify=exp"

この設定は、特定のルートでJWT検証を有効にし、トークンの有効期限を確認します。

ゼロトラストアーキテクチャ: 誰も信じない、自分さえも

APIゲートウェイでゼロトラストアーキテクチャを実装するには、いくつかのコンポーネントが必要です:

  • アイデンティティベースのアクセス: すべてのリクエストに対して強力な認証を使用します。
  • マイクロセグメンテーション: サービスレベルで細かいアクセス制御を実装します。
  • 継続的な監視: EnvoyとKongのログと監視機能を活用して異常を検出します。

Kongのkey-authプラグインとACLを組み合わせてアイデンティティベースのアクセスを実装する例を見てみましょう:


# キー認証を有効にする
curl -X POST http://localhost:8001/routes/{route_id}/plugins \
    --data "name=key-auth"

# コンシューマーを作成
curl -X POST http://localhost:8001/consumers \
    --data "username=alice"

# コンシューマーのキーを作成
curl -X POST http://localhost:8001/consumers/alice/key-auth \
    --data "key=secret_key_123"

# ACLプラグインを有効にする
curl -X POST http://localhost:8001/routes/{route_id}/plugins \
    --data "name=acl" \
    --data "config.whitelist=group_a"

# コンシューマーをグループに割り当てる
curl -X POST http://localhost:8001/consumers/alice/acls \
    --data "group=group_a"

この設定により、認証されたユーザーのみが正しいグループメンバーシップを持っている場合に保護されたルートにアクセスできるようになります。

デバッグとパフォーマンスチューニング: 物事がうまくいかないとき

最善の計画を立てても、物事がうまくいかないことがあります。APIゲートウェイの設定をデバッグし、調整するための戦略を見てみましょう。

プロのようにログを取る

EnvoyとKongの両方が、広範なログ機能を提供します。Envoyで詳細なアクセスログを設定する方法を見てみましょう:


static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/var/log/envoy/access.log"
              log_format:
                json_format:
                  time: "%START_TIME%"
                  protocol: "%PROTOCOL%"
                  duration: "%DURATION%"
                  request_method: "%REQ(:METHOD)%"
                  request_host: "%REQ(HOST)%"
                  path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
                  response_code: "%RESPONSE_CODE%"
                  response_flags: "%RESPONSE_FLAGS%"
                  bytes_received: "%BYTES_RECEIVED%"
                  bytes_sent: "%BYTES_SENT%"
                  upstream_host: "%UPSTREAM_HOST%"
                  upstream_cluster: "%UPSTREAM_CLUSTER%"
                  upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"

この設定は、詳細なJSON形式のアクセスログを設定し、デバッグやパフォーマンス分析に非常に役立ちます。

パフォーマンスチューニング: 最後の一滴まで絞り出す

パフォーマンスチューニングに関しては、いくつかの領域に焦点を当てる必要があります:

  • 接続プール: リソース使用量とパフォーマンスのバランスを取るために接続プールを適切に設定します。
  • キャッシング: ゲートウェイレベルでキャッシングを実装し、バックエンドサービスの負荷を軽減します。
  • タイムアウトとリトライポリシー: レジリエンスと応答性のバランスを取るためにこれらの設定を微調整します。

Envoyで接続プールを設定する例を見てみましょう:


clusters:
  - name: my_backend_service
    type: STRICT_DNS
    connect_timeout: 0.25s
    lb_policy: ROUND_ROBIN
    http2_protocol_options: {}
    upstream_connection_options:
      tcp_keepalive:
        keepalive_time: 300
    max_requests_per_connection: 1000
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 100
          max_pending_requests: 1000
          max_requests: 1000
    health_checks:
      - timeout: 1s
        interval: 10s
        unhealthy_threshold: 3
        healthy_threshold: 2
        http_health_check:
          path: "/healthz"

この設定は、キープアライブ付きの接続プールを設定し、接続ごとのリクエスト数を制限し、サーキットブレーカーを設定し、バックエンドサービスのヘルスチェックを設定します。

まとめ: APIニルヴァーナへのゲートウェイ

EnvoyとKongを使ったAPIゲートウェイパターンの高度な領域を探求し、洗練されたトラフィック管理から鉄壁のセキュリティプラクティスまでを見てきました。大きな力には大きな責任が伴いますが、同時に本当にクールなAPIセットアップの可能性もあります。

これらのパターンを実装する際には、すべてのシステムがユニークであることを忘れないでください。あるものにとってうまくいくことが、他のものにとってはうまくいかないかもしれません。常にテストし、測定し、反復してください。そして最も重要なのは、楽しむことです!APIインフラストラクチャの構築を楽しんでいないなら、おそらく何かが間違っています。

さあ、APIの宇宙を征服しに行きましょう。高度なゲートウェイパターンの新しい知識を持って、リクエストが迅速で、セキュリティが堅固で、サービスが常に利用可能であることを願っています!

"素晴らしい仕事をする唯一の方法は、それを愛することです。" - スティーブ・ジョブズ

(そして、素晴らしいAPIゲートウェイのセットアップを持つことも、もちろん。)