AKS集群中服务如何获取真实客户端IP?含Nginx与Linkerd场景
为什么会出现三种不同的节点IP?
这三种IP的差异是由AKS的流量转发机制、Nginx Ingress的配置以及Linkerd边车的代理行为共同导致的:
- 工具节点IP(10.16.232.7):你的Nginx Ingress Controller部署在这个专用工具节点上。当客户端请求直接命中该节点的Ingress服务端口时,Nginx在未配置客户端IP透传的情况下,会将自身所在节点的IP作为源IP转发给后端Asp.Net Core服务,所以服务上报的是这个工具节点IP。
- 应用节点IP(10.16.232.8):当Linkerd边车接管了Ingress到后端服务的流量时,Linkerd默认会对转发的请求做SNAT(源地址转换),将源IP替换为边车所在的应用节点IP,此时服务拿到的就是这个节点的IP。
- 系统节点IP(10.16.232.5):AKS的NodePort/LoadBalancer服务默认会在所有集群节点上监听端口,客户端请求可能命中了这个系统节点的Ingress端口。kube-proxy会将请求转发到Nginx所在的工具节点,但这个过程中会触发SNAT,将源IP替换为接收请求的系统节点IP,最终服务拿到的就是这个系统节点的IP。
如何获取真实客户端IP?
要拿到真实的客户端IP,需要从Ingress、Linkerd、Asp.Net Core三个层面依次配置:
1. 配置Nginx Ingress透传客户端IP
在你的Ingress资源中添加以下annotations,确保Nginx将真实客户端IP写入X-Forwarded-For头:
annotations: nginx.ingress.kubernetes.io/use-forwarded-headers: "true" nginx.ingress.kubernetes.io/forwarded-for-header: "X-Forwarded-For" # 替换为你的客户端IP段,比如公司内网CIDR nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "10.0.0.0/8"
同时,确保Nginx Ingress Controller的Service配置了externalTrafficPolicy: Local,避免kube-proxy的SNAT导致源IP丢失:
apiVersion: v1 kind: Service metadata: name: internal-ingress-ingress-nginx-controller namespace: system-d-internal-ingress spec: externalTrafficPolicy: Local # 其他原有配置...
2. 配置Linkerd保留转发头
Linkerd默认会保留X-Forwarded-For等HTTP头,但需要确保Linkerd正确注入到Nginx Ingress Controller和后端服务中。如果你的Nginx Pod已经被Linkerd注入,无需额外配置;如果没有,需要给Nginx所在的Namespace添加linkerd.io/inject: enabled标签,确保流量经过Linkerd时不会丢失转发头。
3. 配置Asp.Net Core信任代理头
Asp.Net Core默认不会信任代理传递的X-Forwarded-For头,需要在Program.cs中配置ForwardedHeadersMiddleware,指定信任的代理IP段(集群内部CIDR):
var builder = WebApplication.CreateBuilder(args); // 添加ForwardedHeaders配置 builder.Services.AddForwardedHeaders(options => { options.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto; // 添加集群节点CIDR和Linkerd边车的IP段,比如你的集群Pod CIDR是10.254.0.0/16,节点CIDR是10.16.232.0/24 options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.254.0.0"), 16)); options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.16.232.0"), 24)); }); // 其他服务配置... var app = builder.Build(); // 必须在其他中间件之前启用ForwardedHeaders app.UseForwardedHeaders(); // 其他中间件配置... app.Run();
配置完成后,Asp.Net Core会从X-Forwarded-For头中解析出真实客户端IP,上报到App Insights时就会显示正确的IP。
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

