You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在GKE中使用Istio按客户端IP分流应用版本的问题求助

基于Istio的按客户端IP分流方案修复

核心问题排查

  1. 真实客户端IP获取
    Istio IngressGateway本身支持获取真实客户端IP,但需注意:
  • 若使用云厂商LoadBalancer,必须开启客户端IP透传(如AWS NLB开启preserve_client_ip,阿里云SLB开启“获取真实IP”)
  • x-forwarded-for头部可能包含多层代理IP,格式为客户端IP, 代理1IP, 代理2IP,需提取第一个值作为真实IP
  1. Lua脚本缺陷
    原脚本存在两个关键问题:
  • 未处理x-forwarded-for的多IP场景,直接取值可能拿到错误的IP
  • 使用add方法会重复添加x-destination-version头部,导致匹配异常

修正后的配置

EnvoyFilter(修复IP识别与Header设置)

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-by-ip
  namespace: sn-backend
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.lua
          typed_config:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
            inlineCode: |
              function envoy_on_request(request_handle)
                -- 优先从x-forwarded-for取真实IP,处理多代理场景
                local xff = request_handle:headers():get("x-forwarded-for")
                local client_ip = xff and xff:match("^[^,%s]+") or request_handle:connection():remoteAddress():ip()
                
                request_handle:logInfo("Processing request from IP: " .. client_ip)
                
                -- 白名单IP集合,可添加多个测试IP
                local whitelist = { "<REDUCTED_IP>" }
                for _, allowed_ip in ipairs(whitelist) do
                  if client_ip == allowed_ip then
                    request_handle:headers():replace("x-destination-version", "v2")
                    request_handle:logInfo("Matched whitelist, routing to v2")
                    return
                  end
                end
                
                -- 默认设置为v1,确保header存在
                request_handle:headers():replace("x-destination-version", "v1")
              end

VirtualService(保持原有逻辑,优化权重配置)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-router
  namespace: sn-backend
spec:
  hosts:
    - "domain.example.com"
  gateways:
    - httpbin-gateway
  http:
    - match:
        - headers:
            x-destination-version:
              exact: "v2"
      route:
        - destination:
            host: httpbin1.sn-backend.svc.cluster.local
            port:
              number: 8000
            weight: 100
    - route:
        - destination:
            host: httpbin.sn-backend.svc.cluster.local
            port:
              number: 8000
            weight: 100

Gateway(无需修改,保持原配置)

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
  namespace: sn-backend
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "domain.example.com"

验证步骤

  • 查看IngressGateway日志确认IP识别:
    kubectl logs -n istio-system $(kubectl get pods -n istio-system -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -c istio-proxy | grep "Processing request from IP"
    
  • 用非白名单IP测试:curl -H "Host: domain.example.com" <你的LoadBalancerIP>,确认路由到V1
  • 用白名单IP测试:curl -H "Host: domain.example.com" <你的LoadBalancerIP>,确认路由到V2

内容的提问来源于stack exchange,提问作者Semen Kolesnikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:55:58