Kubernetes环境下Java OkHttp客户端SSL异常问题求助
问题
我正在开发一个Java API客户端类用于调用服务器接口,本地运行时正常,但部署到Kubernetes环境后出现如下错误。请问是否需要指定JVM参数来处理SSL相关问题?我运行的是普通主类,未使用Spring框架。
错误信息:
Caused by: javax.net.ssl.SSLException: Unsupported or unrecognized SSL message at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451) at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1493) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1399) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:446) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:417) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379) at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337) at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74) at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
解答
这个错误大概率不是JVM参数的问题,先优先排查以下核心场景:
1. 接口地址协议不匹配
这是该错误最常见的原因:客户端用HTTPS协议连接了仅提供HTTP服务的端点(或者反过来)。比如本地测试用的是http://xxx,但K8s环境中配置成了https://xxx;或者服务端在K8s里实际暴露的是HTTP端口,但客户端强制启用了SSL连接。
- 解决:核对K8s环境中客户端配置的接口地址,确认协议(HTTP/HTTPS)和服务端实际提供的完全一致。
2. K8s Service端口/协议映射错误
如果客户端调用的是K8s内部Service,检查Service的端口配置:
- 比如Service将80端口(HTTP)映射到后端Pod的443端口(HTTPS),或者反向映射,导致客户端发起SSL握手时收到的是HTTP响应,触发错误。
- 解决:查看Service的
ports字段,确认protocol(TCP/UDP)和端口映射关系是否与后端服务匹配。
3. Ingress或代理层配置异常
如果请求经过K8s Ingress或第三方代理,可能存在以下问题:
- 代理将HTTPS请求转成HTTP发给后端,但客户端仍用HTTPS连接代理,导致握手失败;
- Ingress的TLS配置错误,未正确处理SSL连接,返回非SSL响应。
- 解决:检查Ingress的TLS配置,确认是否开启了正确的SSL终止,或者是否需要客户端直接连接后端服务而非经过Ingress。
何时需要调整JVM参数?
只有当确认协议完全匹配,但存在证书信任问题(比如自签名证书不被JVM信任)时,才需要调整JVM参数:
- 信任自签名证书:添加参数
-Djavax.net.ssl.trustStore=/path/to/your/truststore.jks和-Djavax.net.ssl.trustStorePassword=yourpassword,或者将证书导入到JVM默认信任库。 - 禁用证书校验(仅测试环境使用):
-Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStore=/dev/null -Djavax.net.ssl.trustStorePassword=changeit,生产环境绝对禁止使用。
额外排查步骤
- 在K8s容器内用
curl测试接口:执行curl -v https://your-api-url或curl -v http://your-api-url,观察返回内容,快速判断是否是协议不匹配问题。 - 检查客户端OkHttp配置:确认代码中是否强制启用了SSL,或者是否有环境变量控制接口地址,K8s环境中该变量是否配置错误。
内容的提问来源于stack exchange,提问作者Hard Worker
相关产品推荐
相关产品推荐

