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 正确传递额外信息

 

posted @ 2025-09-18 14:24  fengjian1585  阅读(29)  评论(0)    收藏  举报