计算驱动下的容器网络及数据包过滤

过去二十多年网络发生了很多的变化。数据中心物理拓扑方面,由接入-汇聚-核心三级网络架构演进到Spine-Leaf两级架构;软件方面,出现了各种各样的网络虚拟化,例如软件实现的虚拟网桥、虚拟机交换机、虚拟路由器、软件overlay网络等。

很多新的概念和模型,例如软件定义网络(SDN)的转发与控制分离思想,实现上可以像Google一样基于OpenFlow,可以是后来用的比较多的BGPEVPN;另外还有Spine-Leaf中的分布式网关概念;还有大二层网络与纯三层路由网络等等概念。

具体一些的话如bare metal集群可能会采用DHCP加扁平二层(flatL2)网络;虚拟机应用比较有代表性的OpenStack平台,采用的是Neutron+OVS大二层网络;Docker内置的典型网络模型是宿主机内的bridge加出宿主机的SNAT,并定义了CNM网络模型;Kubernetes定义了CNI网络规范,符合这个规范的实现有我们现在所熟悉的Flannel、Calico、Cilium等等。

这么多的网络方案,或者说网络架构和解决方案在不断演进。这种不断增长的计算规模来我们如何高效地进行数据的转发、跟踪、安全分析等。

eBPF的应用

Linux 内核一直是实现监控/可观测性、网络和安全功能的理想地方。不过很多情况下这并非易事,因为这些工作需要修改内核源码或加载内核模块, 最终实现形式是在已有的层层抽象之上叠加新的抽象。eBPF 是一项革命性技术,它能在内核中运行沙箱程序(sandbox programs), 而无需修改内核源码或者加载内核模块。

将 Linux 内核变成可编程之后,就能基于现有的(而非增加新的)抽象层来打造更加智能、 功能更加丰富的基础设施软件,而不会增加系统的复杂度,也不会牺牲执行效率和安全性。


eBPF 催生了一种全新的软件开发方式。基于这种方式,我们不仅能对内核行为进行 编程,甚至还能编写跨多个子系统的处理逻辑,而传统上这些子系统是完全独立、 无法用一套逻辑来处理的。

1、安全

观测和理解所有的系统调用的能力,以及在 packet 层和 socket 层次审视所有的网络操作的能力, 这两者相结合,为系统安全提供了革命性的新方法。以前,系统调用过滤、网络层过滤和进程上下文跟踪是在完全独立的系统中完成的;eBPF 的出现统一了可观测性和各层面的控制能力,使我们有更加丰富的上下文和更精细的控制能力, 因而能创建更加安全的系统。

2、网络

eBPF 的两大特色 —— 可编程和高性能 —— 使它能满足所有的网络处理需求。可编程意味着无需离开内核中的包处理上下文,就能添加额外的协议解析器或任何转发逻辑, 以满足不断变化的需求。高性能的 JIT 编译器使 eBPF 程序能达到几乎与原生编译的内核态代码一样的执行性能。

3、跟踪 & 性能分析

eBPF 程序能够加载到 trace points、内核及用户空间应用程序中的 probe points, 这种能力使我们对应用程序的运行时行为(runtime behavior)和系统本身 (system itself)提供了史无前例的可观测性。应用端和系统端的这种观测能力相结合, 能在排查系统性能问题时提供强大的能力和独特的信息。BPF 使用了很多高级数据结构, 因此能非常高效地导出有意义的可观测数据,而不是像很多同类系统一样导出海量的原始采样数据。

4、观测 & 监控

相比于操作系统提供的静态计数器(counters、gauges),eBPF 能在内核中收集和聚合自定义 metric, 并能从不同数据源来生成可观测数据。这既扩展了可观测性的深度,也显著减少了整体系统开销, 因为现在可以选择只收集需要的数据,并且后者是直方图或类似的格式,而非原始采样数据。

容器网络

容器也被称为轻量级虚拟机,所以它的很多 网络需求与虚拟机类似,但部署密度高了一个数量级。典型的容器平台有Mesos、Kubernetes等。

1、二层网络模型

在传统二层模型的基础上,将虚拟机换成容器,如下图所示:


如果没有一些很特殊的业务需求,只是单纯基于已有二层网络实现这样一套容器方案,其技术难度和开发量都不是很大,例如,如果要将Kubernetes接入OpenStackNeutron网络,开发一个针对Neutron+OVS的CNI插件就可以了。

但前面提到,这种globalIPAM+centralgateway方案中,核心交换机需要记录每个实例的IP/MAC信息,再考虑到容器的部署密度,可以预见的是,交换机硬件表项将撑不住。

在实际的应用中,除了硬件交换机表现出瓶颈,在软件上,其实globalIPAM也已经无法在性能上满足容器频繁的漂移、创建、销毁的需求了。所以大二层网络方案在软件和硬件上都已经陷入了困境。

2、避免网络瓶颈

如何在物理网络上支撑几十万以上的容器?显然,最重要的一点就是不能让核心交换机记录所有的容器的信息 IP 信息。


主流的设计方式有:

在每个node内用虚拟路由器(vrouter)替换虚拟交换机(vswitch),将整张大二层网络拆分成众多的小二层网络;

每个node管理一个网段,负责该节点内容器IP的分配和回收,即从原来的globalIPAM变成了localIPAM;

每个节点内是一个二层域,节点内容器之间走交换(bridging/switching);

跨节点就是跨二层域,需要走路由(routing);每个节点内运行一个BGPagent,负责节点之间或节点和数据中心网络之间的路由同步。

核心交换机就只需要记录node本身的IP和它管理的网段,表中重新回到与宿主机数量同一量级,而与容器的数量没有直接关系。IPAM从中心式变成了分散式,性能瓶颈也解决了。

云原生网络

最近两年较为流行的网络方案为:Cilium+BGP。Cilium的核心基于eBPF,这是4.8内核引入的一项革命性技术:它使得内核变得可编程。这里可编程的意思是,以前要改变内核行为,需要修改内核代码、编译调试、重新打镜像、安装运行等等,而且还要维护自己的内核分支,现在可能写几行eBPF代码然后动态加载到内核就能实现同样的效果。


Cilium的组件如上图所示,主要包括:

cilium-agent:每台node上跑一个,同时监听k8sapiserver和ciliumkvstore。

ciliumkvstore:存储cilium的一些全局状态,例如identity。

cilium-operator:每个集群一个,图中没画出来,在公有云上承担IPAM的功能。

eBPF目前主要用在两个方向:动态跟踪(tracing)和网络(networking)。有了eBPF/XDP之后,我们可以看到数据平面处理(dataplaneprocessing)有一个趋势:

早期基于内核协议栈处理,更多地以功能为主;

前些年内核到达性能瓶颈,于是一些团队尝试将部分网络处理放到用户态,预留专门的、独享的网卡、CPU、内存等资源来收发包,例如DPDK;

最近几年开始重新回到内核。比较有代表性的是Facebook的L4LBKatran,用eBPF/XDP重新之后比原来基于IPVS的版本快了10倍,性能已经和DPDK一个量级,,而且还可以复用内核已有的基础设施和生态。而用户态方式最大的问题之一是原有的网络工具几乎都失效了,并且没有通用的L4-L7协议栈支持。

总结

计算模型驱动下的网络发展是复杂的,涉及到很多因素,最终都是业务需求和网络层的反映,在计算规模的角度上如何平衡网络、稳定、安全、效率等。


国内免备案VPS301跳转服务器国内免备案服务器域名被墙跳转301,绕过信息安全中心不放违反法律法规内容!(北京免备案 镇江免备案 江苏免备案 辽宁免备案vps 山东联通免备案
 
在线咨询