nginx代理两套k8s ingress 不同域名
两套 Kubernetes 集群的 Ingress 配置了不同的域名,当 Nginx 固定设置一个 Host 头时,另一套集群的 Ingress 无法识别这个域名,因此返回 404。
http { # 原有项目的配置 split_clients "${remote_addr}${http_user_agent}" $cluster_selector { 40% "cluster1"; 30% "cluster2"; 20% "cluster3"; 10% "cluster4"; } map $cluster_selector $target_host { "cluster1" "a1.abc.com"; "cluster2" "a2.abc.com"; "cluster3" "a3.abc.com"; "cluster4" "a4.abc.com"; default "a1.abc.com"; } map $cluster_selector $target_upstream { "cluster1" "cluster1-backend"; "cluster2" "cluster2-backend"; "cluster3" "cluster3-backend"; "cluster4" "cluster4-backend"; default "cluster1-backend"; } upstream cluster1-backend { server a1.abc.com:80; } upstream cluster2-backend { server a2.abc.com:80; } upstream cluster3-backend { server a3.abc.com:80; } upstream cluster4-backend { server a4.abc.com:80; } # 新项目的独立配置 split_clients "${remote_addr}${http_user_agent}" $b_cluster_selector { 50% "b-cluster1"; 50% "b-cluster2"; } map $b_cluster_selector $b_target_host { "b-cluster1" "b1.abc.com"; "b-cluster2" "b2.abc.com"; default "b1.abc.com"; } map $b_cluster_selector $b_target_upstream { "b-cluster1" "b-cluster1-backend"; "b-cluster2" "b-cluster2-backend"; default "b-cluster1-backend"; } upstream b-cluster1-backend { server b1.abc.com:80; } upstream b-cluster2-backend { server b2.abc.com:80; } # 原有项目的server块 server { listen 80; server_name a1.abc.com a2.abc.com a3.abc.com a4.abc.com; # 原有项目的location配置 location /abc { # 关键修正:使用计算出的目标Host头,而不是原始Host头 proxy_set_header Host $target_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Original-Host $host; # 保存原始Host头用于调试
# 添加特定的头信息
proxy_set_header X-ABC-Request "true";
proxy_set_header X-Request-Path "/abc";
proxy_pass http://$target_upstream; add_header X-Project "original" always; add_header X-Selected-Cluster $cluster_selector always; add_header X-Target-Host $target_host always; } } # 新项目的server块 server { listen 80; server_name b1.abc.com b2.abc.com; # 新项目的location配置 location / { # 关键修正:使用计算出的目标Host头 proxy_set_header Host $b_target_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Original-Host $host; proxy_set_header X-Project "new-project" always; proxy_pass http://$b_target_upstream; add_header X-B-Project "new" always; add_header X-B-Selected-Cluster $b_cluster_selector always; add_header X-B-Target-Host $b_target_host always; } # 新项目的健康检查 location /b-health { access_log off; return 200 "b-project-healthy\n"; add_header Content-Type text/plain; } } # 默认server块(处理其他域名或IP直接访问) server { listen 80 default_server; server_name _; # 根据Host头决定路由,并设置正确的目标Host头 if ($host ~* ^(a1|a2|a3|a4)\.abc\.com$) { # 对于原有项目,使用负载均衡策略 proxy_set_header Host $target_host; proxy_set_header X-Original-Host $host; proxy_pass http://$target_upstream; } if ($host ~* ^(b1|b2)\.abc\.com$) { # 对于新项目,使用负载均衡策略 proxy_set_header Host $b_target_host; proxy_set_header X-Original-Host $host; proxy_pass http://$b_target_upstream; } # 默认返回404 return 404 "Unknown domain: $host\n"; # 添加调试头 add_header X-Default-Server "true" always; add_header X-Original-Host $host always; } }
关键点说明
$target_upstream 是一个变量,表示上游服务器组的名称(如 "cluster1-backend"),不能直接与路径拼接:
$target_upstream 是上游服务器组名称
路径 /abc 会完整传递给上游服务器
proxy_pass http://$target_upstream/stdabc; ❌ 错误
$target_upstream 不是URL,不能直接拼接路径
会导致代理目标错误
路径处理:应该让上游服务器(Ingress)处理具体的路径路由
头信息传递:使用 proxy_set_header 正确传递额外信息
浙公网安备 33010602011771号