返回

Springboot在Kubernetes中遭遇IP获取难题:问题的始末与终结

后端

Kubernetes 下 SpringBoot 获取客户端 IP 的终极指南

问题根源:代理转发

在 Kubernetes 平台中,NodePort 和 LoadBalancer 类型的 Service 充当代理服务器,将流量转发到应用程序。不幸的是,这会阻碍 SpringBoot 直接获取客户端的真实 IP 地址。

解决方案:Kubernetes 平台识别

Spring Cloud Platform(SCP)2.5.7 版本及更高版本引入了 Kubernetes 平台识别功能。当应用部署在 Kubernetes 中时,SCP 会启用 Remote Ip Valve,从而在 Kubernetes 环境中获取客户端 IP。

Remote Ip Valve 解析

Remote Ip Valve 是一个用于解析客户端 IP 的过滤器。它检查请求头中的 X-Forwarded-For 和 X-Real-IP 信息,并返回第一个有效的 IP 地址。

如何在 Kubernetes 中启用 Remote Ip Valve

  1. 确保 SpringBoot 版本为 2.5.7 或更高。
  2. 在应用启动类中添加以下代码:
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        System.setProperty("spring.cloud.kubernetes.platform", "true");
    }
}
  1. 将应用部署到 Kubernetes 平台。

代码示例

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080
@RestController
public class MyController {

    @RequestMapping("/")
    public String hello(@RequestHeader("X-Forwarded-For") String ip) {
        return "Hello from IP: " + ip;
    }
}

常见问题解答

Q:为什么需要设置 spring.cloud.kubernetes.platform 属性?
A:该属性指示 Spring Cloud Platform 应用部署在 Kubernetes 平台中,从而启用 Remote Ip Valve。

Q:除了 NodePort 和 LoadBalancer 外,Remote Ip Valve 是否支持其他 Service 类型?
A:Remote Ip Valve 不支持 Ingress 或 ClusterIP Service 类型。

Q:Remote Ip Valve 解析 X-Forwarded-For 和 X-Real-IP 的顺序是什么?
A:Remote Ip Valve 优先解析 X-Forwarded-For,如果该字段不存在或无效,则解析 X-Real-IP。

Q:在 Kubernetes 中,如何验证客户端 IP 是否正确获取?
A:可以使用 cURL 命令来验证客户端 IP,例如:curl -H "X-Forwarded-For: 10.0.0.1" http://localhost:8080/

Q:Remote Ip Valve 是否会影响应用性能?
A:在大多数情况下,Remote Ip Valve 的影响微乎其微。但是,对于流量较高的应用,它可能会对性能产生轻微的影响。