解决springboot项目部署k8s,java后台获取不到真实的客户端ip问题

最近是忙的不可开交,改需求改bug,但是都不是我的bug也不是我的代码,惨不,而且同事写的代码及其乱,及其糊弄,及其不负责,最后同事拍拍屁股说自己忙,我在后面擦屁股!甚至甚至,管管领导都忘了最开始的代码不是你写的了,一个坑又一个坑,我就不应该这么实在让自己难受,那么今天要说的这个(问题)坑也是不负责任的同事留下的(这个同事没离职),最后交到我手里了,为什么我说坑呢,或者这么生气呢,因为登录啊还有记录日志啊都是需要ip的,开发半年了,部署到k8s里以后,登录和记录日志这个功能ip永远返回10.24.1这个不知道么,哎,行吧行吧,那我想办法解决把!

首先网上搜索说是因为k8s有一个属性,externalTrafficPolicy改成local就好了,我试了下是好的,能打印出正常的日志,网上说这样以后就不能集群了,我想公司的是单节点的,然后试试把,结果不只是能不能集群这个坑啊,我们用kuboard方式啊,就会出现更新完了以后又把这个属性externalTrafficPolicy变回原来的了,再说了就算你这样做了,集群不了还是个问题

来说说我想的解决方案,我想的是nginx代理k8s里的地址,前端调用nginx,nginx获取客户端ip,然后再将ip设置一个变量存入请求头部,然后请求到后端以后,后端获取nginx里存储的用户真实ip,这样想就动手操作把,结果试了下真的可以啊,当然我的nginx没有部署到k8s里,nginx部署到linux下了。所以不知道nginx部署到k8s里做代理能否解决获取真实ip的问题。

nginx配置如下:

location / {

          proxy_pass   http://你的ip:30081;
          #不允许重定向
          proxy_redirect off;
          proxy_set_header Host $host;
          #获取客户端真实ip
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

后台就这样获取,获取nginx传入头部的变量X-Real-IP

 public static String getIPAddress(HttpServletRequest request) {


        String ip = null;
        // X-Real-IP:nginx服务代理
        String ipAddresses = request.getHeader("X-Real-IP");
        System.out.println("获取nginx的ip:" + ipAddresses);
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP:apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP:weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP:有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Forwarded-For:Squid 服务代理
            ipAddresses = request.getHeader("X-FORWARDED-FOR");
        }

        //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }
        //还是不能获取到,最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

然后修改完打包将后台程序部署到k8s中,用登录测试一下能否正确返回用户ip地址

咱们先来访问不被nginx代理的登录接口,看看获取到的ip是什么?对了,不能返回真实的ip了,只能返回集群里的ip

再看一下nginx代理k8s部署以后接口获取ip情况。

好像还有一种解决方案k8s中部署 ingress-nginx,应该是跟我刚才的猜想一致,也是部署k8s中代理k8s中的地址,因为我自己想的这个解决思路是可以的,所以就没有试下其他方案,大家可以自行开创其他解决方式。

希望能够帮助你!

猜你喜欢

转载自blog.csdn.net/dfBeautifulLive/article/details/105580340