Istio集群内.NET Core 3.0 gRPC服务通信异常求助
Istio环境下.NET Core 3.0 gRPC集群内通信问题排查与解决
最近在Istio管理的Kubernetes集群里,我碰到了一个头疼的问题:两个用.NET Core 3.0开发的gRPC服务,集群内调用频繁报错,但跨集群通信却完全正常。具体的错误现象分两种:
- 直接用
user.default.svc.cluster.local作为调用URI时,抛出异常:Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Connection reset by peer") - 加上端口号用
user.default.svc.cluster.local:80调用时,错误变成了:Grpc.Core.RpcException: Status(StatusCode=Unimplemented, Detail="")
先附上涉及到的user服务的K8s和Istio配置供参考:
apiVersion: v1 kind: Service metadata: name: user labels: app: user service: user spec: ports: - port: 80 name: grpc-port protocol: TCP selector: app: user --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: user-v1 labels: app: user version: v1 spec: replicas: 1 template: metadata: labels: app: user version: v1 spec: containers: - name: user image: *** imagePullPolicy: IfNotPresent env: - name: GOOGLE_APPLICATION_CREDENTIALS value: "***" ports: - containerPort: 80 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: user spec: hosts: - user.default.svc.cluster.local http: - route: - destination: port: number: 80 host: user.default.svc.cluster.local subset: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: user spec: host: user.default.svc.cluster.local subsets: - name: v1 labels: version: v1
问题分析
当时我排查了很久,大概理清了两种错误的可能原因:
- Connection reset by peer:Istio的Sidecar代理会拦截集群内所有流量,而.NET Core 3.0原生的gRPC客户端如果不做特殊配置,可能无法正确和Sidecar协商HTTP/2连接,或者因为没有指定端口导致流量路由出现异常。
- Unimplemented:虽然指定了80端口,但Istio的VirtualService配置的是
http路由规则,而gRPC基于HTTP/2协议,Istio可能没有正确识别这是gRPC流量,导致请求被错误路由或处理,最终返回未实现的状态码。
解决方法
折腾了半天后,我通过使用gRPC的.NET Core 3客户端工厂集成彻底解决了这个问题。客户端工厂会自动处理HTTP/2的相关配置,并且能更好地适配Istio的Sidecar代理环境。
具体配置示例(在服务的Startup.cs中):
public void ConfigureServices(IServiceCollection services) { // 注册gRPC客户端到依赖注入容器 services.AddGrpcClient<User.UserClient>(options => { // 这里直接使用服务的Cluster DNS即可,无需手动指定端口 options.Address = new Uri("http://user.default.svc.cluster.local"); }); }
这种方式的好处是:客户端工厂会自动配置符合gRPC要求的HTTP/2传输通道,同时和Istio的Sidecar代理兼容,避免了手动构造客户端时可能出现的协议适配问题。
内容的提问来源于stack exchange,提问作者nkigen
相关产品推荐
相关产品推荐

