Nginx Ingress配置gRPC多路径时出现404错误求助
Nginx Ingress gRPC多路径配置404问题排查与解决
使用Nginx Ingress部署gRPC服务时,单根路径(/)配置可正常提供服务,但配置带前缀/tenantgrpctest的多路径规则并设置rewrite-target后,C# gRPC客户端调用返回404 未找到错误。
配置对比
单路径正常配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: dev name: txc-dev-ingress-grpc annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: ingressClassName: nginx rules: - host: api-dev.txc.mydomain.net http: paths: - path: / pathType: Prefix backend: service: name: tenant-api-svc port: number: 9000 tls: - secretName: grpctls hosts: - api-dev.txc.mydomain.net
多路径异常配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: dev name: txc-dev-ingress-grpc annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - host: api-dev.txc.mydomain.net http: paths: - path: /tenantgrpctest(/|$)(.*) pathType: Prefix backend: service: name: tenant-api-svc port: number: 9000 tls: - secretName: grpctls hosts: - api-dev.txc.mydomain.net
C#客户端调用代码
using Grpc.Net.Client; using var channel = GrpcChannel.ForAddress("https://api-dev.txc.mydomain.net/tenantgrpctest"); var client = new TXC.Proto.Tenant.TenantConfig.TenantConfigClient(channel); var reply = client.GetTenantConfig(new TXC.Proto.Tenant.GetTenantConfigRequest() { TenantId = 2}); // Check the message Console.WriteLine("Test: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey();
错误原因分析
- 正则匹配未启用:多路径配置中使用了正则表达式路径
/tenantgrpctest(/|$)(.*),但未添加nginx.ingress.kubernetes.io/use-regex: "true"注解,Nginx会将路径作为字面量匹配,无法匹配客户端实际请求路径(如/tenantgrpctest/TXC.Proto.Tenant.TenantConfig/GetTenantConfig),导致404。 - 路径类型冲突:
pathType: Prefix与正则路径不兼容,Prefix类型下Nginx会按前缀匹配逻辑处理,而非正则解析。
解决方案
调整Ingress配置
添加正则匹配注解,修改路径类型为ImplementationSpecific(适配正则匹配场景),并确认rewrite规则正确:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: dev name: txc-dev-ingress-grpc annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" nginx.ingress.kubernetes.io/use-regex: "true" # 开启正则匹配 nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - host: api-dev.txc.mydomain.net http: paths: - path: /tenantgrpctest(/|$)(.*) pathType: ImplementationSpecific # 适配正则路径 backend: service: name: tenant-api-svc port: number: 9000 tls: - secretName: grpctls hosts: - api-dev.txc.mydomain.net
验证逻辑说明
- 开启
use-regex: "true"后,Nginx会解析路径中的正则表达式,匹配客户端请求的/tenantgrpctest/xxx格式路径。 pathType: ImplementationSpecific表示由Ingress控制器(此处为Nginx)决定路径匹配逻辑,兼容正则规则。- 正则分组
(/|$)(.*)将请求路径中/tenantgrpctest后的部分分为两组,rewrite-target: /$2会将路径重写为/xxx,与后端gRPC服务的原生路径匹配。
可选:调整客户端调用地址
若不想修改Ingress正则规则,也可将C#客户端的channel地址改为不带前缀的根地址,通过Ingress的路径匹配实现路由:
using var channel = GrpcChannel.ForAddress("https://api-dev.txc.mydomain.net");
此时客户端请求路径为/TXC.Proto.Tenant.TenantConfig/GetTenantConfig,需确保Ingress路径规则能正确匹配(如调整路径为/tenantgrpctest(/|.*)并rewrite到/$1)。
内容的提问来源于stack exchange,提问作者Water
相关产品推荐
相关产品推荐

