背景&现状:
公司有两个内部微服务A、B,A->B 使用 grpc-go 客户端负载均衡策略,即:consul + round_robin。随着业务的增长,B服务的服务器资源数量一直在增加,有个问题:在一天24小时的时间里,有大概1/3的时间没有业务,就造成了服务资源的浪费。
为了减少资源浪费,决定动态的对B服务扩缩容,最终决定使用K8S管理。
这样的话,就需要在K8S管理的B服务前面增加一个网关,公司采用的是ingress。
问题:
在增加了ingress+K8S之后,A服务请求ingress进行验证时发现:请求ingress服务一直不成功,但是使用grpcurl工具测试却是成功的。
ingress失败显示的日志
"PRI * HTTP/2.0" 400
错误
// Not working...
conn, err = grpc.Dial("test-b.com:443", grpc.WithInsecure())
由于在请求时,没有使用证书,所以在调用Dial() 方法时,使用了 grpc.WithInsecure()。
# working...
./grpcurl -insecure -d '{}' test-b.com:443 b.Servers/GetData
grpcurl 使用 -insecure
标识不使用证书

思考
针对这个问题,抛出几个问题
1.公司A服务、grpcurl都使用的grpc-go进行开发的,并且版本一样。排除grpc-go版本不一致造成的问题
2.在使用grpcurl时也没有使用证书,但是grpcurl却成功,公司A服务却失败。这里面应该就是发生错误的根源所在
基于以上两个问题,追溯了一下grpcurl的源码
解决方案
追查grpcurl的代码,发现
// Working...
var tlsConf tls.Config
tlsConf.InsecureSkipVerify = true
var creds = credentials.NewTLS(&tlsConf)
conn, err = grpc.Dial(host, grpc.WithTransportCredentials(creds))
使用 grpc.WithTransportCredentials(creds)
代替 grpc.WithInsecure()
即可。
至于具体原因,可以追溯 grpc-go 源码
本文链接:https://www.ivansli.com/archives/299/
本文系原创作品,版权所有(禁止转载)