当您通过 SLB 访问应用时,可以通过本文提供的方法在代码中获取客户端 IP。

问题描述

在 EDAS 中创建的应用绑定 SLB ( EDAS 应用基本信息 -> 应用设置页面里面的负载均衡-外网、负载均衡-内网这两种在获取客户端 IP 这个问题上可相同对待)后,客户端通过 SLB 访问时,如何在后端 Java 代码中获取到客户端的真实 IP 哪 ?

解决办法

根据应用部署的集群不同,解决办法也有所区别。

  • 部署在 ECS 集群的应用

    可直接在后端 Java 代码中使用下面的方式获取即可。

    String client_ip = request.getHeader("x-forwarded-for");                

    另外,还可以通过获取 HTTP Header 中的 x-real-ipwl-proxy-client-ip 参数来得到客户端的真实 IP 。

  • 部署在容器服务 Kubernetes 集群的应用

    1. 在容器服务 Kubernetes 控制台的集群列表中找到您创建的 Kubernetes 集群,并在该集群操作列单击控制台
    2. 在该集群的控制台页面,单击服务,然后在服务页面中找到并单击通过 EDAS 控制台部署的应用。
    3. 在应用服务的详情页面右上角单击编辑
    4. 修改 Service对话框找到 externalTrafficPolicy 配置参数,将该参数值由默认的 Cluster 改为 Local ,然后在该对话框右下角单击更新,即会动态更新该服务的配置。修改 Service
    5. 在后端 Java 代码中可通过下面的方式获取到客户端的真实 IP :
          String client_ip = request.getRemoteAddr();              

    结合上面 ECS 集群和容器服务 Kubernetes 集群部署的应用获取客户端 IP 的方法,可通过三元运算符将这两种方式变为一行代码:

        String client_ip = request.getHeader("x-forwarded-for") == null ? request.getRemoteAddr() : request.getHeader("x-forwarded-for");               

    即可适配 EDAS 中不同的集群类型。

    另外,该参数的修改还可以通过 kubectl 命令的方式(前提是已经参见 Kubernetes 集群基本信息页面的通过 kubectl 连接 Kubernetes 集群部分配置好了 KubeConfig):

        kubectl patch svc <service_name> -p '{"spec":{"externalTrafficPolicy":"Local"}}'