在访问网站时,会有以下几种方式访问到实际的后端服务,可忽略WAF,本文主要讲解如何把真实IP转发给后端
- DNS > WAF > CLB > Ingress > backend-service
- DNS > WAF > CLB > Nginx > backend-service
- DNS > WAF > CLB > backend-service
Nginx Ingress
在 Kubernetes 中,应用通过 Nginx Ingress 接收请求,有以下两种方式可以获取到客户端的真实 IP
修改 Nginx Ingress 的 ConfigMap
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
data:
use-forwarded-headers: "true" # 启用 use-forwarded-headers
compute-full-forwarded-for: "true" # 启用 compute-full-forwarded-for详解:
use-forwarded-headers
:Nginx Ingress 会信任 X-Forwarded-For 和 X-Forwarded-Proto 头部,将它们传递给后端服务。compute-full-forwarded-for
:Nginx Ingress 会将客户端的真实 IP 信息完整地记录在 X-Forwarded-For 头部中。通过 Service 资源的配置选项保留客户端源 IP
修改Nginx Ingress Controller 的 Servicespec:
externalTrafficPolicy: Local详解
Cluster
:表示隐藏客户端源 IP,LoadBalancer 和 NodePort 类型服务流量可能会被转发到其他节点的 Pods。Local
:表示保留客户端源 IP 并避免 LoadBalancer 和 NodePort 类型的服务流量转发到其他节点的 Pods。
⚠️Local的缺点:会存在潜在的 Pods(Endpoints)流量负载不均衡风险。
https://kubernetes.io/zh/docs/tasks/access-application-cluster/create-external-load-balancer/配置生效后,在后端获取 HTTP Header 中的 X-Forwarded-For 或 X-Real-IP 字段值得到客户端真实源 IP。
Nginx
增加http_realip_module模块,重新编译nginx
cd nginx-1.17.0 |
vi /etc/nginx/nginx.conf
http { |
CLB
使用云平台中的 CLB 直通 Pod 的转发功能(CLB 透传转发,并绕过 Kubernetes Service 流量转发),后端 Pods 收到的请求的源 IP 即为客户端真实源 IP
此方式适用于四层及七层服务的转发场景
废弃方案,使用后不生效
apiVersion: networking.k8s.io/v1 |
踩坑记录:
查看到log_format有启用,access_log 被注释掉了,但仍然有日志输出,日志一直打印不出来真实IP
原因:
Nginx 默认会生成 access.log 文件,即使在配置文件中没有显式指定 access_log 指令。默认情况下,Nginx 会将访问日志写入 logs/access.log 文件。
如果你在配置文件中注释掉了 access_log 指令,但没有完全禁用日志记录,Nginx 仍然会使用默认配置生成日志。
解决方案:
把access.log开启,重新reload即可
参考文档:
https://cloud.tencent.com/document/product/214/3728
https://cloud.tencent.com/document/product/457/48949