Python代码运行在Kubernetes Pod中如何获取真实客户端IP地址
问题原因
kubectl port-forward本身是调试用的代理工具,所有转发的流量都会被封装为本地请求,源IP默认显示为127.0.0.1,无法用于验证源IP获取能力。- Kubernetes 默认的 LoadBalancer 类型 Service 会对请求做SNAT(源地址转换),将请求源IP替换为集群节点IP,导致应用无法拿到真实客户端IP。
解决步骤
1. 修改Service配置保留源IP
在你的 Service.yaml 中新增 externalTrafficPolicy: Local 配置,关闭SNAT保留原始源IP,修改后的配置如下:
apiVersion: v1 kind: Service metadata: name: sample-deploy spec: type: LoadBalancer externalTrafficPolicy: Local # 新增配置 ports: - port: 80 selector: app: sample-deploy
单节点minikube集群使用该配置无额外副作用,多节点集群下只有运行了对应服务Pod的节点可处理流量。
2. 完善Uvicorn启动配置
你当前配置已放开IP白名单,但还需开启代理头解析,才能正确读取转发的源IP信息,修改启动参数:
if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", forwarded_allow_ips="*", proxy_headers=True)
如果需要兼容多层代理场景,可以在代码中优先读取X-Forwarded-For请求头获取真实IP,示例如下:
@app.get("/items/{item_id}") def read_root(item_id: str, request: Request): # 优先取转发头里的真实IP,没有再取直接连接的IP client_host = request.headers.get("X-Forwarded-For", request.client.host).split(",")[0].strip() f= open("ipadress.txt","a+") f.write(client_host+"\n") f.close() return {"client_host": client_host, "item_id": item_id}
3. 正确验证访问
不要使用kubectl port-forward访问,直接通过LoadBalancer的外部IP访问服务,minikube环境可执行minikube service sample-deploy获取可访问的服务地址,直接访问该地址即可验证真实IP获取效果。
内容的提问来源于stack exchange,提问作者Kavya
相关产品推荐
相关产品推荐

