一文解决Linux Conntrack:为什么它会崩溃,如何避免这个问题

前言

连接跟踪(“conntrack”)是Linux内核网络栈的核心特性。它允许内核跟踪所有的逻辑网络连接或数据包流,从而识别组成每个流的所有数据包,以便能够统一的处理它们。

Conntrack是一个重要的内核特性,它支撑了一些关键的很重要的应用场景:

NAT根据连接跟踪信息,可以以相同的方式转换这个流中的所有数据包。例如,当一个pod访问Kubernetes服务时,kube-proxy的负载平衡使用NAT将连接重定向到一个特定的后端pod。这个连接就是记录到conntrack表中,到服务IP的数据包应该都发送到相同的后端pod,从后端pod返回的数据包应该做反向NAT才能返回到源pod。

有状态防火墙,例如Calico,根据连接跟踪信息来精确地将“响应”流量列入白名单。你可以编写一个网络策略,如“允许我的pod连接到任何远程IP”,而不是编写策略显式地允许响应流量。(如果没有这一点,你就需要添加更不安全的规则如“允许数据包从任何IP进入我的pod”。)

此外,conntrack通常可以提高性能(减少CPU和数据包延迟),因为只有数据流中的第一个数据包需要经过完整的网络堆栈处理,通过第一个包的处理确定后续包怎么处理。请参阅“comparekube-proxy-modes”博客,可以进一步深入理解。

但是,conntrack也是有局限性的。。。

那它会在哪里出问题呢?

conntrack表有一个可配置的最大值,如果conntrack表被添加到了最大值,连接通常会开始被拒绝或丢弃。对于大多数工作负载来说,conntrack表的大小是没问题的,也永远都不是问题。然而,在一些情况下,conntrack表需要多注:

最明显的情况是如果你的服务同时处理大量的活动连接。例如,如果你的conntrack表配置为128k的大小,但您有128k的并发连接,那么肯定会遇到问题!

另外一种不太明显的情况是,如果服务每秒钟处理非常高的连接数。即使是短连接,Linux也会持续跟踪一段时间的(默认为120秒)连接。例如,如果conntrack表被配置为128k大小,并且想每秒处理1100个连接,那么即使是短连接,这也将超过conntrack表的大小(128k/120s=1092个连接/秒)。

有一些小众的工作负载类型就属于这些类别。此外,如果处于一个敌对的环境中,用大量半开的连冲击没你的服务就可以被用作拒绝服务攻击。在这两种情况下,conntrack都可能成为系统中的瓶颈。对于某些场景,通过增加conntrack表大小或减少conntrack超时时间来调优conntrack可能足以满足你的需求(但如果调优错误,可能会带来很多麻烦)。对于其他场景,你要让违规流量绕过conntrack。

一个真实的例子

举一个具体的例子,我们合作过的一个大型SaaS提供商有一组memcached服务运行在裸服务器上(未虚拟化或容器化),每台服务器每秒处理50k+短连接。实际上这远远超出了标准Linux配置所能处理的范围。

他们已经尝试通过调优conntrack配置来增加表的大小和减少超时时间,但是这种场景下这样的调优并不是最佳办法,最大的问题就是增加了内存的使用(大概是GBytes!),而且是短连接的情况下,conntrack没有提供通常的性能优势(减少CPU使用或是包延迟)。

相反,他们使用了Calico。Calico的网络策略允许特定的流量绕开conntrack(使用doNotTrack标志)。这为他们提供了所需的性能,以及Calico带来的额外安全好处。

绕开conntrack有什么好处?

不跟踪网络策略通常必须是对称的。在saas提供者的那个案例中,他们的工作负载是内部的,因此使用网络策略,他们可以小范围地将所有允许访问memcached服务的工作负载的流量列入白名单。

不跟踪网络策略应用于每个包,而正常网络策略只应用于流中的第一个包。这可能会增加每个包的CPU成本,因为每个包都需要由网络策略处理。但是对于短连接,这种额外的处理开销被不使用conntrack的优化所抵消。例如,在SaaS提供商的案例中,每个连接中的数据包数量非常少,因此对每个数据包应用策略的额外开销是合理的。

真实测试

我们测试了单个memcached服务pod和许多运行在远程节点上的客户端pod,因此我们可以每秒发动非常多的连接。memcached服务pod主机是8核的和一个512k配置的conntrack表(主机大小的标准设置)。我们测量了以下几种情况下的性能差异:无网络策略;Calico正常网络策略和Calico不跟踪网络策略。

在第二个测试中,我们推送了尽可能多的客户端连接,并测量了memcached服务器每秒能够处理的最大连接数。正如预期的那样,没有策略和正常策略都达到了conntrack表限制,即略高于每秒4,000个连接(512k/120s=4,369个连接/秒)。在不跟踪政策实施的情况下,我们的客户每秒推送了60,000个连接,而没有遇到任何问题。我们很有信心,我们可以通过增加更多的客户来超越这一点,但感觉数字已经足够说明这篇博客的要点!

结论

Conntrack是一个重要的内核特性。它很擅长自己的工作场景。许多主要的使用场景都依赖于它。然而,对于一些小众场景,conntrack的开销超过了它所带来的正常好处。在这些场景中,可以使用Calico网络策略选择性地绕过conntrack,同时仍可以加强网络安全性。对于所有其他流量,conntrack仍然是你的好朋友!

转载地址:一文解决LinuxConntrack:为什么它会崩溃,如何避免这个问题-圈点-内核技术中文网-构建全国最权威的内核技术交流分享论坛

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐