java - Kubernetes 资源版本太旧

标签 java kubernetes kubernetes-pod fabric8

我正在开发一个为不同 k8s 资源创建监视的运算符(operator)。我时不时地可以在日志中看到以下异常,并且应用程序停止。是什么原因导致此问题以及如何解决此问题?

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)

最佳答案

我来自 Fabric8 Kubernetes 客户端团队。我认为 Kubernetes 在观察一段时间后给出 410 是标准行为。通常由客户负责处理。在 watch 的上下文中,当您要求查看太旧的 resourceVersion 的更改时,即当它无法再告诉您发生了什么更改时,它将返回 HTTP_GONE自从那个版本以来,有太多的事情发生了变化。在这种情况下,您需要重新开始,不指定 resourceVersion 在这种情况下, watch 将向您发送您正在观看的内容的当前状态,然后从该点发送更新。

Fabric8 无法用普通 watch 处理它。但它是在 SharedInformer API 中处理它,请参阅 ReflectorWatcher 。我建议在编写运算符时使用 informer 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

关于java - Kubernetes 资源版本太旧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61409596/

相关文章:

kubernetes - 更改配置后如何部署发布?

apache-spark - Spark 上的 Kubernetes 执行器清理

java - 如何在react中从服务器获取文件

尝试查找在 context.xml 中声明的资源时出现 javax.naming.NameNotFoundException

kubernetes - 为什么我需要kubernetes Ingress作为自定义域?

kubernetes - 在其他 namespace 中运行的kubernetes环境中的Ping API

amazon-web-services - 等待 K8S 作业完成

docker - Kubernetes命名空间迁移到另一个集群

java - 在 adobe cq6 实例中使用放心框架运行单元测试用例

java - 仅当某些标签可用时才解析 XML 响应