Vertx集群事件总线在Kubernetes滚动部署时未能删除旧节点

5
我可以翻译这段内容。这篇文章涉及到编程和云计算方面的知识。

我有两个运行在集群中的Vertx微服务,它们使用一个无头服务(link)在本地云中相互通信。每当我进行滚动部署时,我都会遇到服务之间的连接问题。当我分析日志时,我发现旧的节点/ 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

当部署开始时,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

新成员已添加,

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)

但是,当向部署的服务发出请求时,即使旧的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

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

never start more than one new pod at once

forbid more than one unavailable pod during the process

我正在使用 vertx 4.0.3 和 hazelcast kubernetes 1.2.2。我的 Verticle 类继承了 AbstractVerticle,并且使用以下方式进行部署:
Vertx.clusteredVertx(options, vertx -> {
                    vertx.result().deployVerticle(verticleName, deploymentOptions);

抱歉发了这么长的帖子,非常感谢您的帮助。


你找到了同样的解决方案吗?我在使用EventBus时遇到了同样的问题,回滚或删除其中一个Pod后会降低吞吐量并增加延迟。 - Shadab Siddiqui
开始使用轻量级成员,出现次数减少了70%。(https://vertx.io/docs/vertx-hazelcast/java/#_using_lite_members) - vel
1个回答

0

可能的原因之一是由于Kubernetes在删除Pod并更新Kube-proxy中的端点时存在竞争条件,详见这篇广泛的文章。这种竞争条件会导致Kubernetes在终止后仍然向被删除的Pod发送流量。

一个TL;DR解决方案是在终止Pod时添加延迟,方法如下:

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

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

这个答案的一个警告是我不熟悉Hazelcast Clustering以及您特定的发现模式设置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接