EKS集群从1.14迁移至1.18后Deployment出现too old resource version错误的解决方法咨询
too old resource version错误 兄弟,这个问题我熟——你在从EKS 1.14迁到1.18时遇到的too old resource version错误,是Kubernetes集群跨版本升级时很典型的客户端与API Server兼容性问题,我帮你拆解下原因和解决办法:
错误原因解析
这个错误来自fabric8 Kubernetes客户端,本质是:
Kubernetes API Server会保留有限的资源版本历史记录(默认保留数小时或一定数量的版本,EKS 1.14到1.18之间这个保留策略有调整),当客户端通过watch机制监听资源变化时,如果重连时使用的
resourceVersion太旧,超出了API Server保留的范围,就会触发这个报错。
你提供的错误日志也验证了这一点:
2021年5月19日 10:56:30.297 io.fabric8.kubernetes.client.KubernetesClientException: too old resource version: 13899376 (13911551)
at io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$1.onMessage(WatchConnectionManager.java:259)
at okhttp3.internal.ws.RealWebSocket.onReadMessage(RealWebSocket.java:323)
at okhttp3.internal.ws.WebSocketReader.readMessageFrame(WebSocketReader.java:219)
at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:105)
at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:274)
at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:214)
具体解决办法
1. 升级fabric8 Kubernetes客户端版本
这是最核心的解决方法:EKS 1.18对应的Kubernetes API版本和1.14有不少差异,旧版本的fabric8客户端(适配1.14的)和1.18的API Server兼容性不足。建议升级到适配Kubernetes 1.18的fabric8版本(比如v5.0+系列,fabric8 5.x版本基本覆盖K8s 1.17-1.20版本)。
升级后,客户端会自动处理watch重连时的旧版本问题,比如遇到错误时自动回退到resourceVersion=0重新全量同步资源,再继续监听后续变化。
2. 优化自定义watch逻辑(如果是自研服务)
如果你的服务是自己用fabric8客户端编写的watch逻辑,要避免硬编码或缓存旧的resourceVersion用于重连:
- 捕获
KubernetesClientException,检测错误信息中是否包含too old resource version - 一旦触发该错误,重新发起watch请求时不要指定
resourceVersion(或者显式设置resourceVersion=0),让API Server返回当前所有资源的最新状态,再继续监听后续变更。
3. 临时缓解:重启异常Deployment
如果需要快速恢复服务,可以先重启出现错误的Deployment:
kubectl rollout restart deployment <你的Deployment名称> -n <命名空间>
这会让Pod重新初始化watch连接,使用最新的resourceVersion,暂时消除错误,但这只是临时方案,还是要通过前两个方法彻底解决。
4. 确认API Server版本保留策略(EKS托管场景可选)
由于EKS是托管集群,API Server的配置由AWS管理,不过可以确认是否升级后集群的资源版本保留时间变短。如果是自定义集群,可以调整kube-apiserver的相关历史版本保留参数,但EKS中用户无法修改,所以优先考虑前三个方法。
内容的提问来源于stack exchange,提问作者user6826691

