【问题标题】:Notifications between Pods in KubernetesKubernetes 中 Pod 之间的通知
【发布时间】:2021-10-26 15:48:03
【问题描述】:

问题:

WebsocketsSocket.io 允许在客户端和网络服务器之间提供丰富的双向异步通知。

Socket.io 在 HTML/javascript 客户端和入口“cookie”路由之间创建了 Deployment 中的 Pod(我们称之为 Deployment A 的这些 pod)和 HTML/javascript 客户端之间的状态关联。其他 Deployment 中的其他 Pod(我们称之为 Deployment B 和 Deployment C 的这些 Pod)可能希望将特定于 Pod A 显示的事件通知 Deployment A 中的特定 Pod。

是否有 Kubernetes 机制允许在 pod 之间进行这种注册和通信?

通用设置:

部署 A、B、C 各有多个副本。

来自 A、B 和 C 的 pod 可以读取和更新哑分布式存储中的记录。

来自 A 的每个 pod 将负责一组页面(即网络服务器)。特定 pod A 负责的页面集可以动态更改(即,用户决定编辑哪个页面)。 pod A 不是无状态的,因为“cookie”控制入口路由,并且 pod A 维护一个socket.io 到用户 html/javascript 页面。

B 或 C 中的 Pod 更新页面上的组件。如果一个页面组件被 B/C 更新,而当前 A 中的 pod 正在编辑,则 B/C pod 必须将更新通知特定的 pod A。

多个 pod A 可能正在编辑同一页面。

更多详情:

部署 A 是一个 nodejs express 服务器,托管来自 html/javascript 客户端的 socket.io。流量使用nginx.ingress.kubernetes.io/affinity: "cookie" 从入口路由,因此托管特定客户端的 pod 可以向客户端发送未经请求的流量。即异步双向流量。

部署 B 是部署 A 的后端。一个简单的socket.AF_INET 从部署 A 中的 pod 打开到用于部署 B 的服务。来自 B 的响应到达 A,然后到达客户端。到目前为止,一切顺利,一切正常,但仅在 1 个节点配置上进行了测试。

部署 C 是部署 B 的后端。从 B 向 C 的服务打开一个套接字。从 C 到 B 到 A 到 WebClient 的响应工作正常(再次在 1 节点配置上)

问题:

部署 B 和 C 可能会从其他来源获取处理信息的请求,这些信息会更改向用户显示的内容。我想将部署 A 上托管 socket.io 的任何 pod 更新到显示此页面的客户端。

到目前为止的描述/实现不会异步更新 pod A,除非用户进行整页刷新。

多个用户可能显示相同的页面,但通过入口 cookie 关联到不同的部署 A pod。

就目前而言,用户 1 只能看到用户 1 发起的更新,而用户 2 只能看到用户 2 的更新。除非每个用户都进行页面刷新。

我希望 B 和 C 向 A 中显示正在更新的页面的所有 pod 发送更新。

感觉 Kubernetes 不干净的解决方案:

想要通知页面上组件更改的 pod 将创建一条记录,表明它对此页面感兴趣,其中包含其 pod 的 IP 地址和一个有效的时间戳。

当客户端显示页面时,托管 A pod 将更新分布式数据存储中的记录,以表明它想要更新此页面上的组件。每隔一段时间,Pod A 会更新此记录中的保持活动时间。当用户离开此页面时,关联的 Pod A 将删除此记录。

页面的任何 pod 更新记录都会检查此记录并打开一个到另一个 pod 的套接字以通知它更改。

审核将删除任何因 pod 异常终止而未正确清理的过期记录,因为该 pod 在注册其有兴趣收到更改通知后。

问题重述:

这是一个干净的 Kubernetes 解决方案还是 Kubernetes 中有什么东西可以让这个更干净?

Kubernetes 新手:我是否在我的问题的任何地方弄乱了 Kubernetes 命名法?

【问题讨论】:

    标签: kubernetes kubernetes-ingress kubernetes-pod


    【解决方案1】:

    没有本地方法可以在不同 Deployment 的 pod 之间进行可靠通信。在所有 pod 都具有已知且稳定的名称的 StatefulSet 的情况下,这是可能的。

    在您的情况下,假设我正确理解您的要求,我建议您使用队列消息传递软件,例如 RabbitMQKafka

    【讨论】:

    • 如果我理解正确,分配给 pod 的 ip 地址可以路由到所有其他 pod。你知道这是否正确吗?当一个 pod 被杀死或死亡时,它与 html/javascript 客户端之间的 socket.io 连接也是如此。如果上述 2 项正确,则 pod 可以与其他 pod 通信,就像 pod 可以托管到客户端 html/javascript 页面的 socket.io 连接一样可靠。我是 Kubernetes 新手,如果我弄错了,请多多指正。
    • kubernetes.io/docs/concepts/cluster-administration/networking 说“一个节点上的 Pod 可以在没有 NAT 的情况下与所有节点上的所有 Pod 通信”。
    • 使用 microk8s Kubernetes,看起来 pods 呆了很久。仅当 pod 崩溃或网络更改或系统更新时才会关闭。所以 Pod 和客户端 html/javascript 之间的 socket.io 是相当稳定的。 google Kubernetes 是不是也熬夜了,还是经常被系统重置?换句话说,对于使用 WebSockets 的应用程序来说,谷歌 Kubernetes 是否足够稳定以提供良好的用户体验?我假设答案是肯定的。
    • RabbitMQ 或 Kafka 的快速阅读:看起来它可以完成这项工作,但还有很多。对于使用 WebSockets / Socket.io 在 Kubernetes 上托管的 nodejs/express 等应用程序,我看不到这些通过简单的 INET TCP 套接字和更新集中存储以标记对通信的兴趣给我带来了什么。我对 Kubernetes 的评价是否过高?
    • Pod 是有生命的,无论出于何种原因,它们都可能消失,并且在 Deployment 下创建的替换 pod 对其前身的状态一无所知。 Pod 不会保存它们的 IP 或名称和服务对象,这些对象会平衡与 Pod 的连接,并作为 Pod 应用程序的服务发现,随机(或均匀)转发连接到一组 Pod。另一方面,StatefulSets 为它们的 pod 提供可预测的名称,而 Headless Service 可以帮助连接到特定的 pod。它通常用于 HA 有状态应用程序或数据库 Pod。
    猜你喜欢
    • 1970-01-01
    • 2018-02-12
    • 2018-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    相关资源
    最近更新 更多