You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python-Flask应用的K8s Pod中获取客户端公网IP?

解决Flask应用通过K8s Ingress获取用户公网IP的问题

我太懂你现在的困扰了——明明想拿到访问用户的真实公网IP,结果日志里清一色显示的都是Ingress控制器的IP。这其实是反向代理场景下的典型问题,咱们一步步拆解解决:

问题根源

当请求经Ingress控制器转发到你的Flask Pod时,控制器默认会作为中间代理,Flask收到的请求源IP自然就是控制器的IP,而非原始用户的公网IP。要拿到真实IP,得让Ingress主动传递客户端IP的头信息,同时Flask也要学会正确读取这些头。

解决方案步骤

1. 配置Ingress传递真实IP头

修改你的Ingress YAML,添加Nginx Ingress专属的注解,让控制器把真实客户端IP塞进X-Forwarded-For头里:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: your-ingress-name
  annotations:
    nginx.ingress.kubernetes.io/real-ip-header: "X-Forwarded-For"
    nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"  # 若知道Ingress控制器IP段,填进去更安全
spec:
  # 你的Ingress规则配置...
  • real-ip-header:告诉Ingress控制器从哪个HTTP头提取真实客户端IP
  • proxy-real-ip-cidr:指定哪些IP属于可信代理范围,控制器会仅信任这些IP传递的头信息

2. 确认Service的externalTrafficPolicy设置

如果你的Ingress控制器用的是LoadBalancer类型Service,把externalTrafficPolicy设为Local能减少SNAT(源地址转换),最大程度保留原始客户端IP:

apiVersion: v1
kind: Service
metadata:
  name: your-ingress-service
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  # 其他Service配置...

这个设置会让请求直接路由到运行Ingress控制器Pod的节点,避免节点间转发时替换源IP。

3. 在Flask应用中读取真实IP

Flask默认的request.remote_addr拿到的是代理(Ingress控制器)的IP,所以得从X-Forwarded-For头里提取真实IP。可以写个简单工具函数处理:

from flask import Flask, request

app = Flask(__name__)

def get_real_client_ip():
    # X-Forwarded-For格式通常是 "客户端IP, 代理1IP, 代理2IP..."
    forwarded_for = request.headers.get('X-Forwarded-For')
    if forwarded_for:
        # 取第一个IP就是原始客户端的公网IP
        return forwarded_for.split(',')[0].strip()
    # 如果没有转发头, fallback到remote_addr
    return request.remote_addr

@app.route('/')
def index():
    real_ip = get_real_client_ip()
    app.logger.info(f"Request from real IP: {real_ip}")
    return f"Your public IP is: {real_ip}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

4. 验证Ingress控制器的配置

有些Nginx Ingress Controller默认没开启转发头支持,得检查它的ConfigMap:

kubectl get configmap nginx-ingress-controller -n <你的Ingress命名空间> -o yaml

确保里面有use-forwarded-headers: "true"配置,要是没有就加上,然后重启Ingress控制器Pod生效:

kubectl rollout restart deployment nginx-ingress-controller -n <你的Ingress命名空间>

额外注意事项

如果你的Ingress前面还有一层负载均衡(比如云厂商LB、Cloudflare),X-Forwarded-For头里会包含多个IP,这时候要把上层负载均衡的IP段加到proxy-real-ip-cidr里,这样Ingress控制器才会把最外层的IP当作真实客户端IP。

内容的提问来源于stack exchange,提问作者Farkhod Sadykov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:09:46