Kubernetes太旧的资源版本

时间:2020-04-24 13:31:31

标签: java kubernetes kubernetes-pod fabric8

我正在与一个运营商合作,为不同的k8s资源创建手表。我不时地在日志和应用程序中看到以下异常,只是停止了。是什么引起此问题,我该如何解决?

io.fabric8.kubernetes.client.KubernetesClientException: too old resource version: 29309228 (33284573)
    at kubernetes.client@4.6.4/io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$1.onMessage(WatchConnectionManager.java:263)
    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)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

2 个答案:

答案 0 :(得分:1)

我来自Fabric8 Kubernetes客户团队。我认为Kubernetes的标准行为是在观看一段时间后给出410。通常,处理此事是客户的责任。在手表的上下文中,当您要求查看过旧的HTTP_GONE的更改时,它将返回resourceVersion-即当它不再能够告诉您自该版本以来发生了什么更改时,许多事情已经改变。在这种情况下,您需要通过不指定resourceVersion来重新开始,在这种情况下,手表将向您发送您正在观看的事物的当前状态,然后从该点发送更新。

Fabric8无法用普通手表处理它。但是它正在SharedInformer API中处理它,请参见ReflectorWatcher。我建议在编写运算符时使用提示器API,因为它比普通列表和监视更好。这是使用SharedInformer API的简单示例:

try (KubernetesClient client = new DefaultKubernetesClient()) {
  SharedInformerFactory sharedInformerFactory = client.informers();
  SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor(Pod.class, PodList.class, 30 * 1000L);
  podInformer.addEventHandler(new ResourceEventHandler<Pod>() {
    @Override
    public void onAdd(Pod pod) {
      // Handle Creation
    }

    @Override
    public void onUpdate(Pod oldPod, Pod newPod) {
      // Handle update
    }

    @Override
    public void onDelete(Pod pod, boolean deletedFinalStateUnknown) {
      // Handle deletion
    }
  });
  sharedInformerFactory.startAllRegisteredInformers();
}

您可以在以下位置找到使用Fabric8 SharedInformer API的简单操作员的完整演示:PodSet Operator In Java

答案 1 :(得分:0)

此替代方法对我有用,我希望它能对其他人有所帮助 每当我的pod收到此“资源太旧”错误时,它就会停止并重新启动。 我发现如果我手动创建资源(如果是CRD –甚至是虚拟的) 几乎没有“资源太旧”的异常,因此操作员可以启动并运行并收听。 所以,我做了什么:

  1. 此特定错误正在发生: 一种。系统错误(将重新启动Pod) b。文本“资源版本太旧”的例外
  2. 在平台上创建了新的虚拟CRD对象(重新启动Pod之前) 一种。以编程方式(fabric8),检查是否存在虚拟CRD。如果是这样,请将其删除。 b。以编程方式(fabric8),使用
  3. 再次创建虚拟CRD
  4. 然后,pod会自动重启(这种重启也发生在我的代码更改之前,不是因为我的代码)
  5. 吊舱启动时,它会从虚拟CRD中创建秘密。

从那时起,几乎没有重新启动,并且操作员已经启动并且正在运行并正在收听。 只是不要忘记将权限授予运营商的服务帐户,以创建和删除这些资源。