Docker Desktop下Nginx Ingress负载均衡gRPC服务失败求助
gRPC服务通过Ingress-Nginx访问失败:HTTP/2握手失败+Endpoint检测异常
问题现象
- 通过Helm部署Ingress-Nginx,gRPC服务以ClusterIP类型暴露,Ingress等所有资源创建成功
- 客户端访问时触发HTTP/2握手失败错误
- Ingress Pod日志提示目标服务无活跃Endpoint,但实际服务和Endpoint均存在
客户端报错信息
Grpc.Core.RpcException HResult=0x80131500 Message=Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake.", DebugException="System.Net.Http.HttpRequestException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake. at System.Net.Http.HttpConnectionPool.ReturnHttp2Connection(Http2Connection connection, Boolean isNewConnection)
Ingress Controller Pod日志
I0109 02:18:30.699832 7 event.go:285] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-6f7bd4bcfb-wchw5", UID:"bc4c59da-f378-421c-a12a-87d46fb6371d", APIVersion:"v1", ResourceVersion:"592645", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configuration W0109 02:18:37.595244 7 controller.go:1112] Service "grpc/grpc-file-service" does not have any active Endpoint. W0109 02:18:40.928869 7 controller.go:1112] Service "grpc/grpc-file-service" does not have any active Endpoint.
服务与Endpoint验证
服务存在:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/grpc-file-service ClusterIP 10.104.122.174 <none> 5288/TCP 13h
Endpoint存在:
NAME ENDPOINTS AGE endpoints/grpc-file-service 10.1.21.65:5288,10.1.21.66:5288 13h
预期结果
gRPC握手正常完成,客户端可正常访问服务
环境信息
- NGINX Ingress Controller版本:v1.5.1,Nginx版本:1.21.6
- Kubernetes版本:客户端v1.25.2,服务端v1.24.0
- 运行环境:Docker Desktop 4.15.0(开启Kubernetes),Windows 11
- Ingress部署方式:Helm默认安装,无自定义配置
排查与解决步骤
1. 检查Ingress资源的gRPC专属配置
确保Ingress资源添加gRPC必需的注解,否则Nginx会以HTTP/1.1转发请求,导致握手失败:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grpc-ingress annotations: nginx.ingress.kubernetes.io/backend-protocol: "GRPC" # 核心注解,指定后端为gRPC协议 nginx.ingress.kubernetes.io/ssl-redirect: "false" # 服务无需证书,关闭HTTPS重定向 spec: rules: - host: grpc.example.com http: paths: - path: / pathType: Prefix backend: service: name: grpc-file-service port: number: 5288
2. 验证Ingress Controller的HTTP/2配置
确认Ingress Controller的ConfigMap开启HTTP/2:
kubectl get configmap ingress-nginx-controller -n ingress-nginx -o yaml
确保包含以下配置,若缺失则添加:
data: http2: "on"
修改后重启Controller Pod:
kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx
3. 检查服务端口的协议类型
gRPC基于TCP协议,需确保Service资源明确指定协议:
apiVersion: v1 kind: Service metadata: name: grpc-file-service spec: ports: - name: grpc port: 5288 targetPort: 5288 protocol: TCP # 明确指定TCP协议 selector: app: grpc-file-service
4. 排查Endpoint健康状态
Ingress Controller提示无活跃Endpoint,通常是Pod健康检查未通过。为gRPC服务Pod配置正确的存活/就绪探针:
apiVersion: v1 kind: Pod metadata: name: grpc-file-service-pod spec: containers: - name: grpc-file-service image: your-grpc-image ports: - containerPort: 5288 readinessProbe: grpc: port: 5288 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: grpc: port: 5288 initialDelaySeconds: 15 periodSeconds: 20
若不支持gRPC探针,可替换为TCP探针:
readinessProbe: tcpSocket: port: 5288 initialDelaySeconds: 5 periodSeconds: 10
确认Pod状态正常:
kubectl get pods -n grpc
5. 本地客户端访问适配
Docker Desktop环境下需注意:
- 本地hosts文件添加
grpc.example.com指向127.0.0.1 - 若未使用HTTPS,客户端需禁用TLS验证(以.NET客户端为例):
var channel = GrpcChannel.ForAddress("http://grpc.example.com:80", new GrpcChannelOptions { HttpHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator } });
内容的提问来源于stack exchange,提问作者Venkatesh
相关产品推荐
相关产品推荐

