使用 EnvoyFilter 擴充資料層

您可以使用 EnvoyFilter API 擴充 Cloud Service Mesh 中的資料層功能,否則無法使用其他 Istio API 達成。透過 EnvoyFilter API,您可以自訂從套用至工作負載的其他政策產生的 Envoy 設定,例如在 HTTP 篩選器鏈中新增篩選器。

重要事項

  • 請注意,API 介面與內部實作詳細資料相關,因此使用這項功能時必須特別謹慎,因為設定錯誤可能會導致網格不穩定。只有在其他 Istio API 無法滿足需求時,才使用 EnvoyFilter API。
  • 為確保可靠性和支援性,EnvoyFilter API 支援特定限制,可使用的欄位和擴充功能有限。如需 EnvoyFilter API 支援功能的完整清單,請參閱「使用 Istio API 支援的功能 (受管理控制層)」。
  • Google 提供的支援範圍僅限於將使用者提供的設定傳播至具有 Envoy Sidecar 的工作負載,不包括使用各擴充功能 API 指定的設定是否正確。

支援的 API 欄位

EnvoyFilter API 僅支援 TRAFFIC_DIRECTOR 控制層實作,且支援有限,如下所示:

  • targetRefs:不支援
  • configPatches[].applyTo:僅支援 HTTP_FILTER
  • configPatches[].patch.operation:與路徑篩選器搭配使用時,僅支援 INSERT_FIRSTINSERT_BEFORE
  • configPatches[].patch.value.type_url:請參閱「支援的擴充功能
  • 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

欄位 快速 一般 穩定
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

欄位 快速 一般 穩定
(沒有任何欄位)

使用範例

在本教學課程中,您將瞭解如何使用 Envoy 內建的本機頻率限制,透過 EnvoyFilter API 動態限制服務流量。

費用

本教學課程使用下列 Google Cloud計費元件:

完成本教學課程後,您可以刪除建立的資源,避免持續產生費用。詳情請參閱「清理」一節。

事前準備

  • 確認專案已啟用計費功能。
  • 在 GKE 叢集上佈建 Cloud Service Mesh
  • 複製存放區:

      git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
      cd anthos-service-mesh-samples
    

部署 Ingress 閘道

  1. kubectl 的目前環境設為叢集:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. 為 Ingress Gateway 建立命名空間:

    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 Proxy:

    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 補充容器 Proxy。如果幾分鐘後仍未顯示 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 資源,將所有流量限制為每分鐘 5 個要求。frontend

  1. 將 CR 套用至 frontend 服務:

    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 Gateway 命名空間:

      kubectl delete namespace asm-ingress
      

      預期輸出內容:

      namespace "asm-ingress" deleted
      
  • 如要避免產生額外費用,請刪除叢集:

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

疑難排解

請參閱「解決資料平面擴充性問題」。