使用 UDP 服务器套接字滚动更新后端

使用 UDP 服务器套接字滚动更新后端

我有一个用于物联网设备的后端系统,该系统使用 UDP 协议进行通信。同一后端还提供了某些基于 TCP(HTTP2)的移动应用 API。

我正在尝试构建一个滚动更新功能,以实现后端服务的 0 停机修补。

我的设置是这样的。

我没有直接将套接字暴露给应用程序,而是尝试对我的进程进行透明代理。我使用防火墙将 2 个套接字(1 个 udp 和 1 个 tcp)暴露给公共互联网。

我的生产服务器正在为 udp 和 tcp 打开不同的端口集(可以通过环境变量进行更改,而无需更改底层二进制文件)。

步骤1:

在此处输入图片描述

我正在尝试在同一台机器上从 udp 端口​​ 16002 到 17002 创建透明代理。对于 udp,我的服务器还将与野外的设备发起一些通信。服务器应该能够看到源 IP/端口,并与可能处于某些 NAT 之下的设备进行通信(通常是 WiFi 路由器)通过尊重 NAT 的同源策略。

tcp 也一样。从端口 16012 到端口 17012。这是通过外部化真实端口进行的典型部署。

我无法完成这个工作。

第2步:

每当有新代码需要修补时,我都希望在两组不同的端口上启动新代码,如下图所示(P2 - 进程 2)。

当进程 2 启动并运行时,我将更改映射到新进程 (P2) 的 IP 地址。在给 P1 一定的时间来完成任何待处理的 IO 操作后,我们将关闭进程 P1。

对于下一个补丁,我们将提出 P1' 和过程逆。

在此处输入图片描述

这个设计有什么缺陷吗?从技术上来说,可以使用 iptables 和 tproxy 或任何其他 Linux 工具来实现吗?

我曾考虑过构建一个 L7 路由器,并通过定义高级对象来来回回地中继数据包。但我很好奇这是否可以使用低级路由 L3/L4 来实现,因为它可能更高效且经过实战测试。当然,这些 nft、iptables 工具存在可用性问题,而且对于开发人员来说不太直观,尤其是 nft。

答案1

您可以使用 iptables 执行此操作。要创建从 17X 到 16X 的端口转发:

iptables -A PREROUTING -t nat -p tcp -m tcp --dport 16012 -j DNAT --to-destination :17012
iptables -A PREROUTING -t nat -p udp -m udp --dport 16002 -j DNAT --to-destination :17002

然后,当您启动应用程序的更新版本后想要切换它指向哪个端口时:

iptables -D PREROUTING -t nat -p tcp -m tcp --dport 16012 -j DNAT --to-destination :17012
iptables -D PREROUTING -t nat -p udp -m udp --dport 16002 -j DNAT --to-destination :17002
iptables -A PREROUTING -t nat -p tcp -m tcp --dport 16012 -j DNAT --to-destination :18012
iptables -A PREROUTING -t nat -p udp -m udp --dport 16002 -j DNAT --to-destination :18002

如果您使用的是使用 的发行版,iptables.service并且希望这些更改是永久的,则可以将 -A 行添加到/etc/sysconfig/iptables或配置文件所在的任何位置。如果您使用的发行版使用 ,firewalld.service那么您可以通过以下方式实现相同的目标,并使其在重新启动后永久生效:

第一行只需要一次就可以启用伪装

firewall-cmd --permanent --add-masquerade

然后创建您的初始转发:

firewall-cmd --permanent --add-forward-port=port=16002:proto=udp:toport=17002
firewall-cmd --permanent --add-forward-port=port=16012:proto=tcp:toport=17012

当你想将应用程序更改为监听不同的端口时,只需运行:

firewall-cmd --permanent --remove-forward-port=port=16002:proto=udp:toport=17002
firewall-cmd --permanent --remove-forward-port=port=16012:proto=tcp:toport=17012
firewall-cmd --permanent --add-forward-port=port=16002:proto=udp:toport=18002
firewall-cmd --permanent --add-forward-port=port=16012:proto=tcp:toport=18012

相关内容