如何让Lua Envoy Filter在GKE的Istio集群中生效?
Hey there, I’ve run into this exact issue before with Istio Envoy Filters on GKE—let’s break down what’s likely going wrong and how to fix it step by step:
1. Fix Workload Label Mismatch
Your EnvoyFilter is targeting pods with app: httpbin-gateway, but look at your Gateway configuration: it selects pods labeled istio: ingressgateway (the default Istio ingress gateway pod label). That’s the first mismatch! Update your EnvoyFilter’s workloadLabels to match the actual gateway pod labels:
spec: workloadLabels: istio: ingressgateway
If you’re using a custom gateway, double-check the pod labels with kubectl get pods -n istio-system -l istio=ingressgateway --show-labels (swap istio-system for your gateway’s namespace if needed) to ensure a full match.
2. Align Namespaces
Your Gateway lives in the foo namespace, but Istio’s default ingress gateway runs in istio-system. Either deploy your EnvoyFilter to istio-system, or add namespace: istio-system to the EnvoyFilter spec (if it’s in another namespace) so it can target the gateway pods correctly.
3. Specify Filter Insert Position
Envoy filter ordering matters a lot—if you don’t define where to insert the Lua filter, it might end up in a position where it doesn’t process requests/responses. Add an insertPosition to place it before the Envoy router (the standard spot for request/response modifiers):
filters: - listenerMatch: listenerType: GATEWAY listenerProtocol: HTTP filterName: envoy.lua filterType: HTTP insertPosition: relativeTo: envoy.router position: BEFORE filterConfig: # Your Lua code here
4. Narrow Down Listener Match
To avoid targeting unintended listeners, add a port match to your listenerMatch—this ensures the filter only applies to the 80-port HTTP listener from your Gateway:
listenerMatch: listenerType: GATEWAY listenerProtocol: HTTP portNumber: 80
5. Verify the Configuration
After making changes:
- Check if the filter is loaded by running
istioctl pc filters <gateway-pod-name> -n istio-system(replace with your pod name/namespace) — look forenvoy.luain the output. - Test with
curl http://<your-gateway-ip>and inspect the headers: use the-vflag to confirm you seefoo: barin request headers andresponse-body-sizein the response headers.
Here’s the full corrected EnvoyFilter for reference:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: edge-lua-filter namespace: istio-system # Deploy to the gateway's namespace spec: workloadLabels: istio: ingressgateway # Match gateway pod labels filters: - listenerMatch: listenerType: GATEWAY listenerProtocol: HTTP portNumber: 80 filterName: envoy.lua filterType: HTTP insertPosition: relativeTo: envoy.router position: BEFORE filterConfig: inlineCode: | -- Called on the request path. function envoy_on_request(request_handle) request_handle:headers():add("foo", "bar") end -- Called on the response path. function envoy_on_response(response_handle) body_size = response_handle:body():length() response_handle:headers():add("response-body-size", tostring(body_size)) end
If it’s still not working, check your Istio version (some older versions have syntax differences for EnvoyFilter) or look at the gateway pod logs with kubectl logs <gateway-pod-name> -n istio-system for any filter loading errors.
内容的提问来源于stack exchange,提问作者Rodrigo Valladares

