使用 EnvoyFilter 实现数据平面可扩展性
您可以使用 EnvoyFilter API 扩展 Cloud Service Mesh 中的数据平面功能,而这些功能无法通过使用其他 Istio API 实现。借助
EnvoyFilter API,您可以自定义从应用于工作负载的其他政策生成的 Envoy 配置,例如向 HTTP 过滤条件链添加过滤条件。
重要注意事项
- 请注意,API 表面与内部实现细节相关联,因此在使用此功能时必须格外小心,因为配置不正确可能会导致网格不稳定。只有在其他 Istio API 不符合您的需求时,才使用
EnvoyFilterAPI。 EnvoyFilterAPI 受支持,但对哪些字段和扩展程序可用于可靠性和可支持性目的有特定限制。如需查看EnvoyFilterAPI 中支持的功能的 完整列表,请参阅 使用 Istio API 支持的功能(托管式控制平面)。- Google 提供的支持范围仅限于将用户提供的配置传播到具有 Envoy Sidecar 的工作负载,不包括使用每个扩展程序 API 指定的配置的正确性。
支持的 API 字段
EnvoyFilter API 仅在 TRAFFIC_DIRECTOR 控制平面实现中受支持,并且仅提供有限 支持,如下所示:
targetRefs:不支持configPatches[].applyTo:仅支持HTTP_FILTERconfigPatches[].patch.operation:仅在使用路由过滤条件时支持INSERT_FIRST和INSERT_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
部署入站流量网关
将
kubectl的当前上下文设置为相应集群:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION为入站流量网关创建命名空间:
kubectl create namespace asm-ingress启用用于注入的命名空间。具体步骤取决于您的控制平面实现。
将默认注入标签应用于命名空间:
kubectl label namespace asm-ingress \ istio.io/rev- istio-injection=enabled --overwrite在
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 示例应用
将
kubectl的当前上下文设置为相应集群(如果尚未设置):gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION为示例应用创建命名空间:
kubectl create namespace onlineboutique为
onlineboutique命名空间添加标签以自动注入 Envoy 代理:kubectl label namespace onlineboutique \ istio.io/rev- istio-injection=enabled --overwrite部署示例应用、前端的
VirtualService以及工作负载的服务账号。在本教程中,您将部署 Online Boutique,这是一个微服务演示版应用。kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/virtual-service.yamlkubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/service-accounts
查看服务
查看
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,请查看问题排查指南。获取外部 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在网络浏览器中访问
EXTERNAL-IP地址。您应该会在浏览器中看到 Online Boutique 商店。
应用速率限制配置
本部分应用 EnvoyFilter 资源,将对 frontend 服务的所有流量限制为 5 个请求/分钟。
将 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验证 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移除
loadgenerator部署,因为它会多次调用服务,从而消耗令牌:kubectl delete -n onlineboutique deployment loadgenerator预期输出:
deployment.apps/loadgenerator deleted使用
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 示例,请执行以下操作:
删除应用命名空间:
kubectl delete namespace onlineboutique预期输出:
namespace "onlineboutique" deleted删除入站流量网关命名空间:
kubectl delete namespace asm-ingress预期输出:
namespace "asm-ingress" deleted
如果您想防止产生额外费用,请删除集群:
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
问题排查
请参阅解决数据平面可扩展性问题。