美文网首页微服务 DevOps
Istio 常见问题 - 获取客户端真实 IP

Istio 常见问题 - 获取客户端真实 IP

作者: CatchZeng | 来源:发表于2021-07-22 15:47 被阅读0次

    原文:https://makeoptim.com/istio-faq/get-client-ip

    问题现象

    在带有 istio-injection: enabled 标签的命名空间中部署服务,服务无法通过 X-Forwarded-For 获取客户端真实 IP

    解决方法

    升级 Istio

    检查并升级 Istio 版本到 1.7 以上。

    设置 externalTrafficPolicy

    设置 externalTrafficPolicyLocal

    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      namespace: istio-system
      name: istiocontrolplane
    spec:
      profile: default
      components:
        ingressGateways:
          - name: istio-ingressgateway
            enabled: true
            k8s:
              service:
                externalTrafficPolicy: Local
    

    等待 ingressgateway 重新部署完成。

    下面,部署 httpbin 服务作为验证。

    # httpbin.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
        - "httpbin.makeoptim.com"
      gateways:
        - gateway/makeoptim-gateway
      http:
        - route:
            - destination:
                port:
                  number: 8000
                host: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
    spec:
      ports:
        - name: http
          port: 8000
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          containers:
            - image: docker.io/citizenstig/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
                - containerPort: 8000
    

    部署完 httpbin 后,直接访问并查看 Headers,可以看到多了一项 X-Envoy-External-Address Header,并且指向客户端真实 IP。

    ❯ curl httpbin.makeoptim.com/get
    {
      "args": {},
      "headers": {
        "Accept": "*/*",
        "Content-Length": "0",
        "Host": "httpbin.makeoptim.com",
        "User-Agent": "curl/7.64.1",
        "X-B3-Parentspanid": "50419cd0b3ae983a",
        "X-B3-Sampled": "0",
        "X-B3-Spanid": "5a0bbd2e611fa59e",
        "X-B3-Traceid": "33c8c481a13746c050419cd0b3ae983a",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-External-Address": "38.75.137.213",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/default;Hash=abb1a2a76a04fe7476cd38738e98a228b39dbf6a88936fd249ee23839ec98234;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account",
        "X-Request-Id": "2fe85688-cf60-4f61-b9bb-25e354625124"
      },
      "origin": "38.75.137.213",
      "url": "http://httpbin.makeoptim.com/get"
    }
    

    在自己的服务中,即可通过 X-Envoy-External-Address 来获取客户端真实 IP,下面以 Golang 代码为例:

    package http
    
    import "net/http"
    
    var clientIPHeaders = []string{"X-Envoy-External-Address", "X-Forwarded-For", "X-Real-Ip", "X-Appengine-Remote-Addr"}
    
    // ClientIP get client IP with possible headers.
    func ClientIP(request *http.Request) string {
        for _, v := range clientIPHeaders {
            ip := request.Header.Get(v)
            if ip != "" {
                return ip
            }
        }
        return ""
    }
    

    参考链接

    延伸阅读

    相关文章

      网友评论

        本文标题:Istio 常见问题 - 获取客户端真实 IP

        本文链接:https://www.haomeiwen.com/subject/qdtymltx.html