Vertx 集群事件总线不会删除 kubernetes 滚动部署上的旧节点

vel*_*vel 5 hazelcast vert.x vertx-verticle vertx-eventbus

我有两个在集群中运行的 vertx 微服务,并使用内部云中的无头服务(链接)相互通信。每当我进行滚动部署时,我都会面临服务内的连接问题。当我分析日志时,我可以看到旧节点/pod 正在从集群列表中删除,但事件总线没有删除它并在循环的基础上使用它。

以下是部署前的成员组信息

    Member [192.168.4.54]:5701 - ace32cef-8cb2-4a3b-b15a-2728db068b80        //pod 1
    Member [192.168.4.54]:5705 - f0c39a6d-4834-4b1d-a179-1f0d74cabbce this
    Member [192.168.101.79]:5701 - ac0dcea9-898a-4818-b7e2-e9f8aaefb447      //pod 2
Run Code Online (Sandbox Code Playgroud)

当部署开始时,pod 2 从成员列表中删除,

[192.168.4.54]:5701 [dev] [4.0.2] Could not connect to: /192.168.101.79:5701. Reason: SocketException[Connection refused to address /192.168.101.79:5701]
    Removing connection to endpoint [192.168.101.79]:5701 Cause => java.net.SocketException {Connection refused to address /192.168.101.79:5701}, Error-Count: 5
    Removing Member [192.168.101.79]:5701 - ac0dcea9-898a-4818-b7e2-e9f8aaefb447
Run Code Online (Sandbox Code Playgroud)

并添加了新成员,

Member [192.168.4.54]:5701 - ace32cef-8cb2-4a3b-b15a-2728db068b80
    Member [192.168.4.54]:5705 - f0c39a6d-4834-4b1d-a179-1f0d74cabbce this
    Member [192.168.94.85]:5701 - 1347e755-1b55-45a3-bb9c-70e07a29d55b  //new pod
All migration tasks have been completed. (repartitionTime=Mon May 10 08:54:19 MST 2021, plannedMigrations=358, completedMigrations=358, remainingMigrations=0, totalCompletedMigrations=3348, elapsedMigrationTime=1948ms, totalElapsedMigrationTime=27796ms)
Run Code Online (Sandbox Code Playgroud)

但是当对已部署的服务发出请求时,尽管旧 pod 从成员组中删除,但事件总线正在使用旧 pod/服务引用(ac0dcea9-898a-4818-b7e2-e9f8aaefb447),

[vert.x-eventloop-thread-1] DEBUG io.vertx.core.eventbus.impl.clustered.ConnectionHolder - tx.id=f9f5cfc9-8ad8-4eb1-b12c-322feb0d1acd Not connected to server ac0dcea9-898a-4818-b7e2-e9f8aaefb447 - starting queuing
Run Code Online (Sandbox Code Playgroud)

我查看了滚动部署的官方文档,我的部署似乎遵循文档中提到的两个关键事项,只删除了一个 pod,然后添加了新的 pod。

never start more than one new pod at once

forbid more than one unavailable pod during the process
Run Code Online (Sandbox Code Playgroud)

我正在使用 vertx 4.0.3 和 hazelcast kubernetes 1.2.2。我的 Verticle 类正在扩展 AbstractVerticle 并使用以下方法进行部署,

Vertx.clusteredVertx(options, vertx -> {
                    vertx.result().deployVerticle(verticleName, deploymentOptions);
Run Code Online (Sandbox Code Playgroud)

对不起,很长的帖子,非常感谢任何帮助。

jen*_*ert 0

一个可能的原因可能是由于Kubernetes 删除 Pod 并更新端点的竞争条件Kube-proxy,如这篇广泛的文章中详细介绍的。这种竞争条件将导致 Kubernetes 在终止后继续向被删除的 Pod 发送流量。

一个TL;DR解决方案是通过以下任一方式在终止 pod 时添加延迟:

  1. 当服务收到 a 时SIGTERM(例如 15 秒)延迟,以便在该延迟期间像平常一样继续响应请求。
  2. 使用 Kubernetes hook在容器上preStop执行命令。sleep 15这允许服务在 Kubernetes 更新其端点的同时继续响应 15 秒内的请求。SIGTERMKubernetes 将在挂钩完成时发送preStop

这两种解决方案都会给 Kubernetes 一些时间来传播对其内部组件的更改,以便流量停止路由到被删除的 Pod。

对此答案的一个警告是,我不熟悉 Hazelcast 集群以及如何设置特定的发现模式。