通过 EnvoyFilter 实现数据平面可扩展性
您可以使用 EnvoyFilter API 扩展 Cloud Service Mesh 中的数据平面功能,而这些功能无法通过使用其他 Istio API 来实现。借助 EnvoyFilter API,您可以自定义从应用于工作负载的其他政策生成的 Envoy 配置,例如向 HTTP 过滤链添加过滤条件。
重要注意事项
- 请注意,API 表面与内部实现细节相关联,因此在使用此功能时必须格外小心,因为不正确的配置可能会导致网状网络不稳定。只有在其他 Istio API 无法满足您的需求时,才应使用
EnvoyFilterAPI。 EnvoyFilterAPI 受支持,但对哪些字段和扩展程序可用于可靠性和支持性目的有特定限制。如需查看EnvoyFilterAPI 中支持的功能的完整列表,请参阅使用 Istio API 支持的功能(托管式控制平面)。- Google 提供的支持范围仅限于将用户提供的配置传播到具有 Envoy 边车的工作负载,不包括使用每个扩展程序 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 字段。 您可以在 Envoy 官方文档中找到 API 定义及其语义。
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
| 字段 | 快速 | 常规 | 稳定 |
|---|---|---|---|
| (无字段) |
type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor
| 字段 | 快速 | 常规 | 稳定 |
|---|---|---|---|
compressor_library |
|||
choose_first |
|||
response_direction_config.common_config.min_content_length |
|||
response_direction_config.common_config.content_type |
|||
response_direction_config.common_config.enabled |
|||
response_direction_config.disable_on_etag_header |
|||
response_direction_config.remove_accept_encoding_header |
|||
response_direction_config.uncompressible_response_codes |
|||
request_direction_config.common_config.min_content_length |
|||
request_direction_config.common_config.content_type |
|||
request_direction_config.common_config.enabled |
如需了解如何更新 EnvoyFilter 压缩器配置以实现完全支持,请参阅对 EnvoyFilter 压缩器配置进行现代化改造。
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
| 字段 | 快速 | 常规 | 稳定 |
|---|---|---|---|
stat_prefix |
|||
default_source_code.inline_string† |
† 内嵌 Lua 脚本的重要注意事项和限制:
- 为确保安全性和稳定性,仅允许使用部分 Lua 功能和 Envoy Lua 封装容器。使用不受支持的功能或超出文档中规定的限制会导致 EnvoyFilter 被拒绝。
- 复杂的 Lua 脚本可能会影响性能。全面测试脚本的资源使用情况。
不支持的 Lua 功能:
以下 Lua 功能和 Envoy 提供的 Lua 封装容器不受支持:
- Envoy 封装容器:
httpCallfilterContext
- Lua 标准库:
- 基本软件包:
collectgarbage、dofile、getmetatable、loadfile、rawset、setfenv、setmetatable - 模块:
module - 操作系统软件包:
execute、remove、rename、setlocale - I/O 和调试库:
io、debug
- 基本软件包:
- LuaJIT 扩展:
ffi、jit
脚本大小和数量限制:
- 单个脚本的大小:在
default_source_code.inline_string中提供的单个 Lua 内嵌脚本不得超过 50KB。 - 脚本总大小:单个集群中所有 EnvoyFilter 资源的所有 Lua 脚本的总大小不得超过 100KB。
- 补丁数量:单个集群中所有 EnvoyFilter 资源中的 Lua EnvoyFilter
configPatches总数限制为 10。
用法示例
在本教程中,您将学习如何使用 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
问题排查
请参阅解决数据平面可扩展性问题。