如何在Knative+Istio场景下获取客户端IP 配置后上游连接错误如何解决
故障根因
- 你配置的EnvoyFilter为istio-system下的Istio入口网关所有监听器都开启了Proxy Protocol强制校验,要求所有进入该网关的请求必须携带Proxy协议头
- 你在VirtualService中
/user/路径的路由规则是将请求转发回Istio入口网关的集群内部Service地址,这部分是集群内发起的请求,默认不会携带Proxy协议头,被网关的Proxy Protocol过滤器直接判定为非法请求,主动断开连接,因此抛出连接终止错误 /test/路径的请求直接转发到集群内部普通Service,不经过Istio入口网关的Proxy Protocol校验,因此访问正常
解决方案
方案1(推荐):调整路由规则,避免回环转发
直接将/user/路径的目标指向Knative服务的集群内部地址,无需绕一层Istio入口网关,从根源规避内部请求碰Proxy Protocol校验的问题:
# 修改VirtualService中/user/对应的路由配置 - match: - uri: prefix: /user/ rewrite: uri: / route: - destination: # 直接替换为你的Knative服务对应的集群内Service地址 host: user-api.poker-test.svc.cluster.local port: number: 80
方案2:限定Proxy Protocol仅作用于公网监听器
如果确实需要保留回环转发的逻辑,修改EnvoyFilter配置,仅为对外暴露的公网端口开启Proxy Protocol校验,放过内部访问请求:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: proxy-protocol namespace: istio-system spec: configPatches: - applyTo: LISTENER # 新增匹配规则,仅对80、443等对外端口的监听器生效 match: listener: portNumber: 80 patch: operation: MERGE value: listener_filters: - name: envoy.listener.proxy_protocol - name: envoy.listener.tls_inspector - applyTo: LISTENER match: listener: portNumber: 443 patch: operation: MERGE value: listener_filters: - name: envoy.listener.proxy_protocol - name: envoy.listener.tls_inspector workloadSelector: labels: istio: ingressgateway
补充配置:Knative网关开启Proxy Protocol支持
如果你需要通过Knative自带的入口网关直接对外提供服务并且需要获取真实客户端IP,还需要为Knative的网关单独配置对应的EnvoyFilter:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: knative-proxy-protocol namespace: knative-serving spec: configPatches: - applyTo: LISTENER match: listener: portNumber: 80 patch: operation: MERGE value: listener_filters: - name: envoy.listener.proxy_protocol - name: envoy.listener.tls_inspector - applyTo: LISTENER match: listener: portNumber: 443 patch: operation: MERGE value: listener_filters: - name: envoy.listener.proxy_protocol - name: envoy.listener.tls_inspector workloadSelector: labels: istio: knative-ingress-gateway
验证方法
配置更新后,先在集群内部执行curl http://istio-ingressgateway.istio-system.svc.cluster.local确认无连接错误,再从公网访问对应路径,同时检查请求头中X-Forwarded-For字段是否为真实客户端IP即可。
内容的提问来源于stack exchange,提问作者Adem Çınar
相关产品推荐
相关产品推荐

