EnvoyFilter によるデータプレーンの拡張性

EnvoyFilter API を使用すると、他の Istio API では実現できない Cloud Service Mesh のデータプレーン機能を拡張できます。EnvoyFilter API を使用すると、ワークロードに適用される他のポリシーから生成された Envoy 構成をカスタマイズできます。たとえば、HTTP フィルタチェーンにフィルタを追加できます。

重要な考慮事項

  • API サーフェスは内部実装の詳細に関連付けられているため、この機能を使用する場合は注意が必要です。構成が正しくないと、メッシュが不安定になる可能性があります。EnvoyFilter API は、他の Istio API がニーズに合わない場合にのみ使用してください。
  • EnvoyFilter API は、信頼性とサポートの目的で、使用できるフィールドと拡張機能に特定の制限があります。 EnvoyFilter API でサポートされている機能の完全なリストについては、 Istio API を使用する場合のサポートされている機能(マネージド コントロール プレーン)をご覧ください。
  • Google が提供するサポートの範囲は、ユーザーが指定した構成を Envoy サイドカーを持つワークロードに伝播することに限定されており、拡張機能ごとの API を使用して指定された構成の正確性には及びません。

サポートされている API フィールド

EnvoyFilter API は、TRAFFIC_DIRECTOR コントロール プレーンの実装でのみサポートされており、次のように制限 があります。

  • targetRefs: サポートされていません
  • configPatches[].applyTo : HTTP_FILTER のみがサポートされています
  • configPatches[].patch.operation: ルートフィルタで使用する場合、INSERT_FIRSTINSERT_BEFORE のみがサポートされます。
  • configPatches[].patch.value.type_url: [Supported Extensions]
  • configPatches[].patch.filterClass: サポートされていません
  • configPatches[].match.proxy: サポートされていません
  • configPatches[].match.routeConfiguration: サポートされていません
  • configPatches[].match.cluster: サポートされていません
  • INSERT_BEFORE オペレーションでは、次のフィールドのみがサポートされます。
    • configPatches[].match.listener: filter のみがサポートされています。
    • configPatches[].match.listener.filter.name: envoy.filters.network.http_connection_manager のみがサポートされています。
    • configPatches[].match.listener.filter.subFilter.name: envoy.filters.http.router のみがサポートされています。

サポートされる拡張機能

以下に、サポートされている拡張機能と、さまざまな リリース チャンネルでサポートされている API フィールドのリストを示します。 API の定義とそのセマンティクスについては、 Envoy の公式ドキュメントをご覧ください。

type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit

フィールド Rapid 標準 Stable
stat_prefix
status
token_bucket
filter_enabled
filter_enforced
response_headers_to_add
request_headers_to_add_when_not_enforced
local_rate_limit_per_downstream_connection
enable_x_ratelimit_headers

type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb

フィールド Rapid 標準 Stable
(フィールドなし)

使用例

このチュートリアルでは、Envoy の組み込みローカル レート制限を使用して、EnvoyFilter API を使用してサービスへのトラフィックを動的に制限する方法について説明します。

費用

このチュートリアルでは、課金対象である次の Google Cloudコンポーネントを使用します。

このチュートリアルの終了後に作成したリソースを削除すれば、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

Ingress ゲートウェイをデプロイする

  1. kubectl の現在のコンテキストをクラスタに設定します。

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Ingress ゲートウェイの名前空間を作成します。

    kubectl create namespace asm-ingress
    
  3. インジェクションの名前空間を有効にします。手順は、コントロール プレーンの実装によって異なります。

    デフォルトのインジェクション ラベルを名前空間に適用します。

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    
  4. anthos-service-mesh-samples リポジトリにサンプル ゲートウェイをデプロイします。

    kubectl apply -n asm-ingress \
        -f docs/shared/asm-ingress-gateway
    

    予想される出力:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

Online Boutique サンプル アプリケーションをデプロイする

  1. まだ行っていない場合は、kubectl の現在のコンテキストをクラスタに設定します。

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. サンプル アプリケーションの名前空間を作成します。

    kubectl create namespace onlineboutique
    
  3. onlineboutique 名前空間にラベルを付けて、Envoy プロキシを自動的に挿入します。

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. サンプルアプリ、フロントエンド用の VirtualService、ワークロードのサービス アカウントをデプロイします。このチュートリアルでは、マイクロサービス デモアプリである Online Boutique をデプロイします。

    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/virtual-service.yaml
    
    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/service-accounts
    

サービスを表示する

  1. 名前空間 onlineboutique の Pod を表示します。

    kubectl get pods -n onlineboutique
    

    予想される出力:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    アプリケーションのすべての Pod が稼働状態になり、READY 列に 2/2 が入力されます。これは、Pod に Envoy サイドカー プロキシが正常に挿入されたことを示します。数分経っても 2/2 が表示されない場合は、トラブルシューティング ガイドをご覧ください。

  2. 外部 IP を取得して、変数に設定します。

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    次のような出力が表示されます。

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. ウェブブラウザで EXTERNAL-IP のアドレスにアクセスします。ブラウザに Online Boutique のショップが表示されます。

    オンライン ショップのフロントエンド

レート制限構成を適用する

このセクションでは、EnvoyFilter リソースを適用して、frontend サービスへのすべてのトラフィックを 5 req/分に制限します。

  1. frontend サービスに CR を適用します。

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: frontend-local-ratelimit
      namespace: onlineboutique
    spec:
      workloadSelector:
        labels:
          app: frontend
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.local_ratelimit
              typed_config:
                "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
                value:
                  stat_prefix: http_local_rate_limiter
                  token_bucket:
                    max_tokens: 5
                    tokens_per_fill: 5
                    fill_interval: 60s
                  filter_enabled:
                    runtime_key: local_rate_limit_enabled
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
                  filter_enforced:
                    runtime_key: local_rate_limit_enforced
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
    EOF
    

    予想される出力:

    envoyfilter.networking.istio.io/frontend-local-ratelimit created
    
  2. CR ステータスにエラーが報告されていないことを確認します。

    kubectl get envoyfilter -n onlineboutique frontend-local-ratelimit -o yaml
    

    予想される出力:

    ...
    status:
      conditions:
      - lastTransitionTime: "2025-06-30T14:29:25.467017594Z"
        message: This resource has been accepted. This does not mean it has been propagated
          to all proxies yet
        reason: Accepted
        status: "True"
        type: Accepted
    
  3. loadgenerator デプロイはトークンを消費するため、削除します。

    kubectl delete -n onlineboutique deployment loadgenerator
    

    予想される出力:

    deployment.apps/loadgenerator deleted
    
  4. curl を使用して、60 秒間に許可されるリクエストが 5 件以下であることを確認します。429 コードは、レート制限が適用されていることを示します。

    for i in {1..10}; do curl -s http://${FRONTEND_IP} -o /dev/null -w "%{http_code}\n"; sleep 1; done
    

    予想される出力:

    200
    200
    200
    200
    200
    429
    429
    429
    429
    429
    

クリーンアップ

このチュートリアルで使用したリソースについて、アカウントに課金されないようにするには、プロジェクトを削除するか、個々のリソースを削除します。 Google Cloud

プロジェクトの削除

Cloud Shell で、プロジェクトを削除します。

  gcloud projects delete PROJECT_ID

リソースを削除する

  • クラスタを維持して Online Boutique のサンプルを削除するには:

    1. アプリケーションの名前空間を削除します。

      kubectl delete namespace onlineboutique
      

      予想される出力:

      namespace "onlineboutique" deleted
      
    2. Ingress ゲートウェイの名前空間を削除します。

      kubectl delete namespace asm-ingress
      

      予想される出力:

      namespace "asm-ingress" deleted
      
  • 追加料金の発生を回避するには、クラスタを削除します。

    gcloud container clusters delete CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    

トラブルシューティング

データプレーンの拡張性の問題を解決するをご覧ください。