K8S中应用无法获取用户真实ip问题排查过程

 更新时间:2025年07月10日 08:39:35   作者:bruce128  
这篇文章主要介绍了K8S中应用无法获取用户真实ip问题排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

现象

领导反馈生产环境的用户ip有问题。登陆到这个页面,发现是所有的用户ip都是*.*.94.97,这是个内部网络ip.

排查过程

1 登陆到应用前端nginx, 查看nginx的请求日志

*.*.94.97 - - [17/Jul/2024:02:02:54 +0000] "POST /***/notify/my-page HTTP/1.1" 200 182 "/report/home?type=2&id=2612&lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" "*.*.44.200"
*.*.94.97 - - [17/Jul/2024:02:02:54 +0000] "POST /***/notify/my-page HTTP/1.1" 200 182 "/home?lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" "*.*.140.102"
*.*.94.97 - - [17/Jul/2024:02:02:56 +0000] "POST /***/msg/notify/my-page HTTP/1.1" 200 59 "/user/message/info?lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "*.*.52.192"

发现第一列展示的ip正好是我们的Java应用代码拿到的iP,而真实的ip展示在最后一列

2 查看nginx的日志输出格式。第一列取的是remote_addr变量,说明这个变量是有问题的 。我们要取的是最后一列http_x_forwarded_for变量

log_format  main   '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

3 查看Java代码获取客户ip的逻辑。Java代码从6个Header变量中依次找可以用的ip。

    public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) {
        String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
        if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
            headers = (String[])ArrayUtil.addAll(new String[][]{headers, otherHeaderNames});
        }

        return getClientIPByHeader(request, headers);
    } 

4 查看nginx传递过来了哪些Header变量。nginx传递过来了X-Real-IP和X-Forwarded-For,其中X-Real-IP取的是有问题的remote_addr,正好我们Java代码取到的是这个变量。X-Forwarded-For没有值。

location ~ ^/(admin-api|rpc-api)/ {
    client_max_body_size 32m;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://***:30001;
}


5 根据第二步的分析,将remote_addr修改为http_x_forwarded_for

6 重启nginx,问题解决

K8S网络拓扑

所有的外部流量一定会通过一个ingress controller进入到K8S的内部。

ingress controller的一个常见实现是Nginx,正好我们的k8s选择的就是Nginx。

也就是说我们的业务前端nginx前面还有一个nginx。所以我们的前端nginx的remote_addr拿到的是k8s入口ingress的内部ip地址。

总结

用户请求经过两层nginx转发才到达后端java业务应用。remote_addr仅存储上一个转发节点的ip,所以我们的业务应用一直拿的是ingress的ip。http_x_forwarded_for存储的是原始用户的请求ip。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一篇文章搞懂K8S高级特性

    一篇文章搞懂K8S高级特性

    这篇文章主要给大家介绍了关于K8S高级特性的相关资料,文中通过时实例代码以及图文介绍的非常详细,对大家学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-11-11
  • K8S中五种控制器的介绍以及使用

    K8S中五种控制器的介绍以及使用

    这篇文章主要给大家介绍了关于K8S中五种控制器及使用的相关资料,控制器 又称之为工作负载,本文通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • RFO SIG之openEuler AWS AMI 制作详解

    RFO SIG之openEuler AWS AMI 制作详解

    这篇文章主要为大家介绍了RFO SIG之openEuler AWS AMI 制作详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • k8s 常见面试题集锦

    k8s 常见面试题集锦

    这篇文章主要为大家介绍了k8s 常见面试题集锦,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Containerd容器运行yum安装与二进制安装

    Containerd容器运行yum安装与二进制安装

    这篇文章主要为大家介绍了Containerd容器运行yum安装与二进制安装,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • k8s查看pod日志的几种实用方法汇总

    k8s查看pod日志的几种实用方法汇总

    Pod是Kubernetes中能够创建和部署的最小单元,是Kubernetes集群中的一个应用实例,总是部署在同一个节点Node上,下面这篇文章主要给大家介绍了k8s查看pod日志的几种实用方法,需要的朋友可以参考下
    2022-07-07
  • Kubernetes Worker Node组件使用及说明

    Kubernetes Worker Node组件使用及说明

    这篇文章主要介绍了Kubernetes Worker Node组件使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-01-01
  • k8s进入容器实现方式

    k8s进入容器实现方式

    文章介绍了在Kubernetes(k8s)中进入容器的步骤,包括使用`kubectl get pod`命令获取容器名称,然后使用`kubectl exec -it <podname> /bin/bash`或`kubectl exec -it <podname> bash`命令进入容器,如果容器中没有`/bin/bash`,可以尝试使用`sh`
    2026-02-02
  • Kubernetes集群模拟删除k8s重装详解

    Kubernetes集群模拟删除k8s重装详解

    这篇文章主要为大家介绍了Kubernetes集群模拟删除k8s重装详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Kubernetes控制器中DaemonSet与Job的使用教程

    Kubernetes控制器中DaemonSet与Job的使用教程

    这篇文章主要介绍了Kubernetes控制器中DaemonSet与Job的使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08

最新评论