如何使用 kubernetes 服务从 Google 网络负载均衡器获取客户端 ip

How to get client ip from Google Network Load Balancer with kubernetes service

我使用 type:LoadBalancer 在 GKE 中创建了一个 kubernetes 服务。

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    targetPort: http
  selector:
    app: nginx

这是一个nginx服务,尝试获取原始客户端IP。喜欢

        location / {
            echo $remote_addr;
            echo $http_x_forwarded_for;   
        }

但是结果会得到:

10.140.0.97

$remote_addr 就像在 kubernetes IP 中。

$http_x_forwarded_for 为空。

我不知道为什么这不像文件说的那样。

我读了什么

https://cloud.google.com/load-balancing/docs/network

Network Load Balancing is a pass-through load balancer, which means that your firewall rules must allow traffic from the client source IP addresses.

https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview#ext-lb

If your Service needs to be reachable from outside the cluster and outside your VPC network, you can configure your Service as a LoadBalancer, by setting the Service's type field to LoadBalancer when defining the Service. GKE then provisions a Network Load Balancer in front of the Service. The Network Load Balancer is aware of all nodes in your cluster and configures your VPC network's firewall rules to allow connections to the Service from outside the VPC network, using the Service's external IP address. You can assign a static external IP address to the Service. Visit Configuring Domain Names with Static IP Addresses for more information.

因为网络负载均衡器处理所有传入流量并重定向到您的 GKE 集群。在 k8s 集群内部,虚拟 IP 网络下的所有内容都是 运行,所以你得到 10.140.0.97.

第一个文档说您需要设置防火墙以接受来自客户端源 IP 的流量,否则 GCP 默认情况下您不会获得任何传入流量。但是第二个文件表明 GKE 会自动为您设置。您需要做的就是找出您的外部 IP 并试一试。您应该能够看到您的 nginx 欢迎页面。

P.S。默认的外部 IP 是动态的,如果你想要一个静态 IP,你可以通过控制台或 gcloud CLI 获得一个。

只需添加externalTrafficPolicy: Local

spec:
  externalTrafficPolicy: Local
  type: LoadBalancer

Packets sent to Services with Type=LoadBalancer are source NAT’d by default, because all schedulable Kubernetes nodes in the Ready state are eligible for load-balanced traffic. So if packets arrive at a node without an endpoint, the system proxies it to a node with an endpoint, replacing the source IP on the packet with the IP of the node (as described in the previous section).

参考