K8s集群跨Istio版本(1.8.6→1.14.1)调用API遇TLS证书验证失败
问题场景
K8s集群内部署了Istio 1.8.6和1.14.1两个版本:namespace-1注入1.8.6的Sidecar,namespace-2注入1.14.1的Sidecar,两个命名空间均运行业务工作负载。当从namespace-1的Pod向namespace-2的Pod发起curl请求时,触发以下错误:
"upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED"
问题根源
这个错误本质是跨版本Sidecar的TLS证书验证不通过,核心原因是Istio 1.8和1.14的mTLS机制存在兼容性差异:
- 两个版本默认使用的证书签名算法、证书格式或CA根证书不一致
- Istio 1.8的Sidecar无法识别并验证1.14 Sidecar提供的服务证书,导致握手失败
解决方案
1. 统一根CA信任链
让两个Istio版本共享同一根CA证书,确保跨版本Sidecar能互相验证对方证书:
- 将Istio 1.8和1.14的CA组件配置为使用同一个根证书(可通过手动指定根CA Secret实现)
- 检查两个命名空间的
PeerAuthentication或全局MeshPolicy,确保mTLS模式统一(比如同时设为STRICT或PERMISSIVE)
2. 临时放宽目标命名空间的mTLS策略
把namespace-2的mTLS模式改为PERMISSIVE,允许非加密流量接入,快速验证是否是强制mTLS导致的问题:
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: namespace-2 spec: mtls: mode: PERMISSIVE
执行kubectl apply -f <上述文件路径>后重新测试调用,若问题消失,再推进根CA统一的方案。
3. 升级Istio 1.8到兼容版本
Istio 1.8已停止官方维护,建议将namespace-1的Istio版本升级到1.14.x系列,从根源解决跨版本兼容问题:
- 先升级控制平面,再逐步替换
namespace-1的Sidecar注入版本 - 升级前备份集群配置,准备好回滚预案
4. 检查Sidecar证书信任链
验证namespace-1的Sidecar是否包含Istio 1.14的CA根证书:
kubectl exec -n namespace-1 <你的Pod名称> -c istio-proxy -- cat /etc/certs/root-cert.pem
对比namespace-2中Sidecar的根证书内容,确保两者的信任链完全一致。
内容的提问来源于stack exchange,提问作者saurav

