Extensibilidad del plano de datos con EnvoyFilter
Puedes usar la API de EnvoyFilter para extender las capacidades del plano de datos en Cloud Service Mesh que, de otro modo, no se pueden lograr con otras APIs de Istio. Con la API de EnvoyFilter, puedes personalizar la configuración de Envoy que se genera a partir de otras políticas aplicadas a las cargas de trabajo, como agregar filtros a la cadena de filtros HTTP.
Consideraciones importantes
- Ten en cuenta que la superficie de la API está vinculada a detalles internos de la implementación, por lo que se debe tener especial cuidado al usar esta función, ya que las configuraciones incorrectas podrían desestabilizar la malla. Solo usa la API de
EnvoyFiltersi otras APIs de Istio no satisfacen tus necesidades. - La API de
EnvoyFilterse admite con restricciones específicas sobre qué campos y extensiones se pueden usar para fines de confiabilidad y asistencia. Para obtener una lista exhaustiva de las funciones compatibles con la API deEnvoyFilter, consulta Funciones compatibles con las APIs de Istio (plano de control administrado). - El alcance de la asistencia que ofrece Google se limita a propagar la configuración proporcionada por el usuario a las cargas de trabajo con sidecars de Envoy y no se extiende a la corrección de la configuración especificada con las APIs por extensión.
Campos de la API compatibles
La API de EnvoyFilter se admite con la implementación del plano de control de TRAFFIC_DIRECTOR solo con compatibilidad limitada de la siguiente manera:
targetRefs: No compatibleconfigPatches[].applyTo: Solo se admiteHTTP_FILTER.configPatches[].patch.operation: Solo se admitenINSERT_FIRSTyINSERT_BEFOREcuando se usan con el filtro de ruta.configPatches[].patch.value.type_url: Consulta Extensiones admitidasconfigPatches[].patch.filterClass: No compatibleconfigPatches[].match.proxy: No compatibleconfigPatches[].match.routeConfiguration: No compatibleconfigPatches[].match.cluster: No compatible- Los siguientes campos solo se admiten para la operación
INSERT_BEFORE:configPatches[].match.listener: Solo se admitefilter.configPatches[].match.listener.filter.name: Solo se admiteenvoy.filters.network.http_connection_manager.configPatches[].match.listener.filter.subFilter.name: Solo se admiteenvoy.filters.http.router.
Extensiones compatibles
A continuación, se incluye la lista de extensiones admitidas junto con sus campos de API compatibles en los distintos canales de lanzamiento. La definición de la API y su semántica se pueden encontrar en la documentación oficial de Envoy.
type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
| Campo | Rápido | Normal | Estable |
|---|---|---|---|
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
| Campo | Rápido | Normal | Estable |
|---|---|---|---|
| (Sin campos) |
type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor
| Campo | Rápido | Normal | Estable |
|---|---|---|---|
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 |
Para obtener información sobre cómo actualizar la configuración del compresor EnvoyFilter para que sea totalmente compatible, consulta Moderniza las configuraciones del compresor EnvoyFilter.
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
| Campo | Rápido | Normal | Estable |
|---|---|---|---|
stat_prefix |
|||
default_source_code.inline_string† |
† Consideraciones y restricciones importantes para los secuencias de comandos Lua intercalados:
- Para garantizar la seguridad y la estabilidad, solo se permite un subconjunto de funciones de Lua y wrappers de Envoy Lua. Si se usan funciones no admitidas o se superan los límites documentados, se rechazará el EnvoyFilter.
- Las secuencias de comandos de Lua complejas pueden afectar el rendimiento. Prueba minuciosamente el uso de recursos de tus secuencias de comandos.
Funciones de Lua no admitidas:
Las siguientes funciones de Lua y los wrappers de Lua proporcionados por Envoy no son compatibles:
- Wrappers de Envoy:
httpCallfilterContext
- Biblioteca estándar de Lua:
- Paquete básico:
collectgarbage,dofile,getmetatable,loadfile,rawset,setfenv,setmetatable - Módulos:
module - Paquete del SO:
execute,remove,rename,setlocale - Bibliotecas de E/S y depuración:
io,debug
- Paquete básico:
- Extensiones de LuaJIT:
ffi,jit
Límites de tamaño y cantidad de secuencias de comandos:
- Tamaño de secuencia de comandos individual: Una sola secuencia de comandos intercalada de Lua proporcionada en
default_source_code.inline_stringno puede superar los 50 KB. - Tamaño total del script: El tamaño total de todos los scripts de Lua en todos los recursos de EnvoyFilter dentro de un solo clúster no puede exceder los 100 KB.
- Cantidad de parches: La cantidad total de
configPatchesde EnvoyFilter de Lua en todos los recursos de EnvoyFilter dentro de un solo clúster se limita a 10.
Ejemplo de uso
En este instructivo, aprenderás a usar el límite de frecuencia local integrado de Envoy para limitar de forma dinámica el tráfico a un servicio con la API de EnvoyFilter.
Costos
En este instructivo, se usan los siguientes componentes facturables de Google Cloud:
Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te sigan cobrando. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
- Asegúrate de que la facturación esté habilitada para tu proyecto.
- Aprovisiona Cloud Service Mesh en un clúster de GKE.
Clona el repositorio:
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples cd anthos-service-mesh-samples
Implementa una puerta de enlace de entrada
Establece el contexto actual para
kubectlen el clúster:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONCrea un espacio de nombres para tu puerta de enlace de entrada:
kubectl create namespace asm-ingressHabilita el espacio de nombres para la inserción. Los pasos dependen de tu implementación del plano de control.
Aplica la etiqueta de inserción predeterminada al espacio de nombres:
kubectl label namespace asm-ingress \ istio.io/rev- istio-injection=enabled --overwriteImplementa la puerta de enlace de ejemplo en el repositorio
anthos-service-mesh-samples:kubectl apply -n asm-ingress \ -f docs/shared/asm-ingress-gatewayResultado esperado:
serviceaccount/asm-ingressgateway configured service/asm-ingressgateway configured deployment.apps/asm-ingressgateway configured gateway.networking.istio.io/asm-ingressgateway configured
Implementa la aplicación de muestra de Online Boutique.
Si no lo hiciste, establece el contexto actual para
kubectlen el clúster:gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATIONCrea el espacio de nombres para la aplicación de ejemplo:
kubectl create namespace onlineboutiqueEtiqueta el espacio de nombres
onlineboutiquepara insertar de forma automática los proxies de Envoy:kubectl label namespace onlineboutique \ istio.io/rev- istio-injection=enabled --overwriteImplementa la app de ejemplo,
VirtualServicepara el frontend y las cuentas de servicio para las cargas de trabajo. En este instructivo, implementarás Online Boutique, una app de demo de microservicios.kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/virtual-service.yamlkubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/service-accounts
Cómo ver tus servicios
Visualiza los Pods en el espacio de nombres
onlineboutique:kubectl get pods -n onlineboutiqueResultado esperado:
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 2m7sTodos los Pods de tu aplicación deben estar en funcionamiento, con un
2/2en la columnaREADY. Esto indica que los Pods tienen un proxy de sidecar de Envoy insertado de forma correcta. Si no aparece2/2después de un par de minutos, consulta la Guía de solución de problemas.Obtén la IP externa y configúrala en una variable:
kubectl get services -n asm-ingress export FRONTEND_IP=$(kubectl --namespace asm-ingress \ get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \ )Verás un resultado similar al siguiente:
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 27mVisita la dirección
EXTERNAL-IPen tu navegador web. Deberías ver la tienda Online Boutique en tu navegador.
Aplica la configuración del límite de frecuencia
En esta sección, se aplica un recurso EnvoyFilter para limitar todo el tráfico al servicio frontend a 5 solicitudes/min.
Aplica el CR al servicio
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 EOFResultado esperado:
envoyfilter.networking.istio.io/frontend-local-ratelimit createdVerifica que el estado del CR no informe ningún error:
kubectl get envoyfilter -n onlineboutique frontend-local-ratelimit -o yamlResultado esperado:
... 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: AcceptedQuita la implementación de
loadgenerator, ya que llama al servicio varias veces, lo que consume tokens:kubectl delete -n onlineboutique deployment loadgeneratorResultado esperado:
deployment.apps/loadgenerator deletedCon
curl, verifica que no se permitan más de 5 solicitudes en 60 s. El código429indica que se está aplicando la límite de frecuencia.for i in {1..10}; do curl -s http://${FRONTEND_IP} -o /dev/null -w "%{http_code}\n"; sleep 1; doneResultado esperado:
200 200 200 200 200 429 429 429 429 429
Realiza una limpieza
Para evitar que se apliquen cargos continuos a tu cuenta de Google Cloud por los recursos que se usaron en este instructivo, puedes borrar el proyecto o borrar los recursos individuales.
Borra el proyecto
En Cloud Shell, borra el proyecto:
gcloud projects delete PROJECT_ID
Borra recursos
Si deseas conservar el clúster y quitar la muestra de Online Retail, realiza la siguiente acción:
Borra los espacios de nombres de la aplicación:
kubectl delete namespace onlineboutiqueResultado esperado:
namespace "onlineboutique" deletedBorra el espacio de nombres de Ingress Gateway:
kubectl delete namespace asm-ingressResultado esperado:
namespace "asm-ingress" deleted
Si deseas evitar cargos adicionales, borra el clúster:
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
Soluciona problemas
Consulta Cómo resolver problemas de extensibilidad del plano de datos.