语境
简而言之,我正在开发一项功能,以提供出站连接计数率和容器网络解决方案中容器的每个目标主机的硬限制(请参阅丝脱模)。vxlan
创建一个由其管理的覆盖网络,其中每个容器都有专用的私有 IP。
我们正在使用CNIiptables
每当生成新容器时,作为放置和配置网络工件(包括规则和链)的触发器。
问题
每当容器在虚拟机上启动时,我们都会iptables
通过以下方式配置其出站流量的规则:
iptables -N netout--container-id
# where the container ip from the overlay network is "1.2.3.4/32"
iptables -A FORWARD -s 1.2.3.4/32 -o underlay-interface -j netout--container-id
iptables -A netout--container-id -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A netout--container-id -p tcp -m state --state INVALID -j DROP
# hard limit rule allowing a maximum of 1000 concurrent connections per dest ip
iptables -A netout--container-id -m conntrack --ctstate NEW -m connlimit --connlimit-above 1000 --connlimit-mask 32 --connlimit-daddr -j REJECT
# rate limit rule allowing 100 new connections per sec with a burst of 999 per dest ip
iptables -A netout--container-id -m conntrack --ctstate NEW -m hashlimit --hashlimit-above 100/sec --hashlimit-burst 999 --hashlimit-mode dstip --hashlimit-name container-id --hashlimit-htable-expire 10000 -j REJECT
# A bunch of accept rules...
# And finally a reject all rule
iptables -A netout--container-id -j REJECT --reject-with icmp-port-unreachable
这效果非常好!限制规则已正确应用,我们通过运行ssh
到一个容器来测试这一点,该容器使用以下命令打开了与单个主机的太多连接:
# monitors the number of open connections to the destip
watch -n 1 'netstat -anp tcp | grep ESTABLISHED | grep -v <dest-port> | grep <proc-name> | wc -l'
每当创建新容器时就会出现此问题。然后iptables
添加新规则,这会导致 netfilter (如果我没有记错的话)重新启动并connlimit
失去对所有打开连接的跟踪。
因此,假设上面代码片段中的示例(最多 1000 个连接),如果在启动新容器(即添加新规则)时容器已经达到其硬限制,则限制将被重置,并且能够再打开 1000 个连接,直到下一个容器启动,依此类推。
该模块不存在这样的问题,hashlimit
因为它在/proc/net/ipt_hashlimit/<container-id>
文件中维护其条目。我想知道是否可以connlimit
使用其他iptables
“持久”模块(如hashlimit
.我正在考虑使用该recent
模块,但想不出任何办法。
这个问题与此类似一但使用不同的用例,因为我需要能够动态修改规则,而不会connlimit
(或其他模块)丢失当前打开的连接的跟踪。
预先感谢您对我们的支持。
PS - 如果您需要更多架构细节,我可以轻松提供,但我相信问题的 RC 就是我上面所说的。