使用grpcurl检查gRPC服务状态时遇SSL及PROTOCOL_ERROR问题求助
问题排查:gRPC调用SSL握手失败(WRONG_VERSION_NUMBER)及PROTOCOL_ERROR
核心错误分析
从日志和OpenSSL验证结果来看,几个关键异常点需要重点关注:
- gRPC服务端日志:
SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER - grpcurl返回:
stream terminated by RST_STREAM with error code: PROTOCOL_ERROR - OpenSSL输出显示:
No ALPN negotiated,但TLSv1.3握手成功且证书验证通过
可能原因及排查步骤
1. ALPN协商失败导致协议不匹配
gRPC基于HTTP/2协议,要求TLS握手阶段通过ALPN协商出h2协议,这是当前最可能的核心问题:
- 检查Ingress资源的annotations,确保启用HTTP/2和gRPC支持:
nginx.ingress.kubernetes.io/ssl-alpn: "h2" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" - 确认NGINX Ingress控制器版本支持HTTP/2与gRPC,部分旧版本默认关闭ALPN或h2协议支持
2. 端口/协议混淆(HTTP vs HTTPS)
WRONG_VERSION_NUMBER错误常见于协议端口不匹配场景:
- 检查是否用grpcurl的默认TLS模式连接了未启用TLS的gRPC服务端口
- 确认NGINX Ingress是否将HTTPS请求转发到了后端gRPC的HTTP端口
- 核对Ingress关联的Service配置,确保后端端口对应gRPC服务的正确协议端口
3. TLS版本兼容性问题
尽管OpenSSL显示TLSv1.3握手成功,但gRPC服务端可能不支持该版本:
- 强制grpcurl使用TLSv1.2测试兼容性:
grpcurl -tls-min-version=TLS1_2 -tls-max-version=TLS1_2 <你的服务地址> <目标服务方法> - 检查gRPC服务端的TLS配置,确认是否限制了TLS版本范围
4. NGINX Ingress的gRPC配置缺失
确保Ingress资源正确配置gRPC规则,示例配置如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grpc-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" nginx.ingress.kubernetes.io/ssl-alpn: "h2" spec: tls: - hosts: - <你的域名> secretName: <证书Secret名称> rules: - host: <你的域名> http: paths: - path: /<gRPC服务包名>.<服务名> pathType: Prefix backend: service: name: <gRPC服务Service名称> port: number: <服务端口>
5. 后端gRPC服务的TLS配置问题
如果后端gRPC服务自身启用了TLS:
- 检查NGINX Ingress是否配置了后端TLS验证(测试阶段可临时关闭验证):
nginx.ingress.kubernetes.io/grpc-ssl-verify: "false" - 确认后端服务证书是否被NGINX信任,或是否存在证书链不完整问题
验证步骤
- 用grpcurl的-v参数查看详细握手过程:
grpcurl -v <你的服务地址> list - 查看NGINX的access/error日志,获取请求转发的具体细节
- 跳过Ingress,直接在集群内部测试gRPC服务可用性:
kubectl exec -it <测试Pod名称> -- grpcurl <服务Service名称>:<端口> list
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

