k8s linux性能要求,k8s网络解决方案性能PK
引言Kubernetes要求集群中的每一个pod都具备惟一的,可路由的IP,Kubernetes自己不会分配IP,而是将任务留给第三方解决方案。node本次课题的目标是找到具备最低延迟,最高吞吐量和最低安装成本的解决方案。 因为个人负载对延迟敏感,所以个人目的是在相对较高的网络利用率下测量较高的百分比延迟,特别是最大负载的30%到50%之间的性能,由于我认为这是最能表明非过载系统的最多见用例。gi
引言
Kubernetes要求集群中的每一个pod都具备惟一的,可路由的IP,Kubernetes自己不会分配IP,而是将任务留给第三方解决方案。node
本次课题的目标是找到具备最低延迟,最高吞吐量和最低安装成本的解决方案。 因为个人负载对延迟敏感,所以个人目的是在相对较高的网络利用率下测量较高的百分比延迟,特别是最大负载的30%到50%之间的性能,由于我认为这是最能表明非过载系统的最多见用例。git
竞争对手们
Docker with --net=host
这是咱们的一个参考设置,全部其余竞争对手都会与此设置进行比较。--net=host选项表示容器继承其主机的IP,即不涉及容器网络。github
根据先验原则,没有任何容器网络方案比其余的会有更好的表现,这就是为何使用此设置做为参考的缘由。docker
Flannel
Flannel是一个虚拟网络解决方案,由CoreOS维护,它是通过充分验证可当即投入生产的解决方案,所以安装成本最低。将带有Flannel的worker节点添加到k8s群集时,Flannel会作三件事:后端
使用etcd为新worker节点分配一个子网
在机器上建立虚拟网桥接口(称为docker0网桥)
设置数据包转发后端:
aws-vpc
在Amazon AWS实例表中注册机器子网,此表的记录数限制为50,即若是将Flannel布与aws-vpc一块儿使 用,则集群的节点数量不能超过50,此外,此后端仅适用于Amazon的AWS。
host-gw
经过远程主机IP建立到子网的IP路由。 须要运行Flannel的主机之间2层直连。
vxlan
建立一个虚拟VXLAN接口
因为Flannel使用网桥接口转发数据包,所以流量从一个容器到另外一个容器的过程当中,每一个数据包都会通过两个网络栈。服务器
IPvlan
IPvlan是Linux内核中的驱动程序,可以建立具备惟一IP的虚拟接口,而没必要使用网桥接口。网络
要将IP分配给具备IPvlan的容器,你必须:tcp
建立一个彻底没有网络接口的容器
在默认网络名称空间中建立ipvlan接口
将此接口移动到容器的网络命名空间中
IPvlan是一个相对较新的解决方案,所以没有现成的工具能够自动执行此过程。 这使得很难在许多服务器和容器中部署IPvlan,即部署成本很高。
可是,IPvlan不须要桥接接口,而是直接将数据包从NIC转发到虚拟接口,所以指望它的性能优于Flannel。工具
负载测试方案
对于每一个竞争对手,执行如下步骤:性能
在两台物理机上设置网络
在一台机器上的容器中运行tcpkali,让其以恒定速率发送请求
在另外一台计算机上的容器中运行Nginx,让它以固定大小的文件响应
捕获系统指标和tcpkali结果
咱们以每秒50,000至450,000个请求(RPS)的请求速率运行基准。
在每次请求时,Nginx都会响应一个固定大小的静态文件:350 B(内容为100 B,标题为250 B)或4 KB。
测试结果
结果显示IPvlan有着最低的延迟和最高的最大吞吐量,host-gw和aws-vpc的Flannel紧随其后,可是host-gw在最大负载下显示的结果更好。
使用vxlan的Flannel在全部测试中均显示最差的结果,可是,我怀疑99.999%ile测试结果的异常是由一个bug引发的。
4 KB响应的结果相似于350 B响应的结果,但有两个明显的区别:最大的RPS要低得多,由于在4 KB响应下仅需约270kRPS便可彻底加载10 Gbps NIC。
吞吐量测试中IPvlan无限接近--net=host。
咱们当前的选择是使用host-gw模式的Flannel,它没有太多的依赖关系(例如,不须要AWS或新的Linux版本),与IPvlan相比,它易于部署,而且具备足够的性能特性,IPvlan是备选方案,若是某个时候Flannel添加了IPvlan支持,咱们将会切换到它。
尽管aws-vpc的性能比host-gw稍好,但其50台计算机节点的局限性以及将其硬连线到Amazon的AWS的事实对咱们来讲都是一个障碍。
50,000 RPS, 350 B
在每秒50,000个的请求速度下,全部候选者都表现出使人满意的性能,主要趋势是:IPVlan表现最佳,host-gw和aws-vpc紧随其后,vxlan表现最差。
150,000 RPS, 350 B
IPvlan略优于host-gw和aws-vpc,可是在99.99 %ile这个指标上是最差的,host-gw的性能略优于aws-vpc。
250,000 RPS, 350 B
这种负载在生产中也很常见,所以这些结果尤其重要。
IPvlan再次显示出最佳性能,可是在99.99和99.999 %ile这两个指标上aws-vpc更胜一筹,host-gw在95和99% %ile上优于aws-vpc。
350,000 RPS, 350 B
在大多数状况下,延迟接近250,000 RPS(350 B状况),但在99.5 %ile以后迅速增加,这意味着咱们已经接近最大RPS。
450,000 RPS, 350 B
这是理论上能产生合理结果的最大RPS,IPvlan再次领先,延迟比--net-host差30%左右:
有趣的是,host-gw的性能比aws-vpc更好:
500,000 RPS, 350 B
在500,000 RPS下,只有IPvlan仍然有效,表现甚至优于--net=host,可是延迟是如此之高,以致于咱们认为这对延迟敏感的程序毫无用处。
50k RPS, 4 KB
较大的响应会形成较高的网络使用率,但测试结果看起来与较小的响应几乎相同:
150k RPS, 4 KB
Host-gw具备使人惊讶的99.999%ile,对于较低的百分位数也显示出良好的结果。
250k RPS, 4 KB
这是在大的请求响应下的最大RPS,与小的请求响应测试用例不一样,aws-vpc的性能比host-gw好得多,Vxlan再次从图中排除。
测试环境
背景
为了理解本文并重现咱们的测试环境,你应该熟悉有关高性能的基础知识。
这些文章提供了有关该主题的有用看法:
如何每秒接收一百万个数据包 by CloudFlare
扩展Linux网络堆栈 from the Linux kernel documentation
服务器规格清单
须要2台Amazon AWS EC2实例,系统版本为CentOS 7,实例规格为c4.8xlarge,两个实例均开启了加强联网功能。
每一个实例都有2个处理器的NUMA,每一个处理器有9个核心,每一个核心有2个超线程,这实际上容许在每一个实例上运行36个线程。
每一个实例都有一个10Gbps网络接口卡(NIC)和60 GB内存。
为了支持加强联网功能和IPvlan,已经安装了带有Intel ixgbevf驱动程序的Linux内核4.3.0版本。
安装部署
现代NIC经过多个中断请求(IRQ)线提供接收方扩展(RSS),EC2在虚拟化环境中仅提供两条中断线,所以咱们测试了几种RSS和接收数据包导向(RPS)接收数据包导向(RPS)配置,最终获得如下配置,部分由Linux内核文档提供:
IRQ
两个NUMA节点中的每一个节点上的第一个核都配置为接收来自NIC的中断。
使用lscpu将CPU与NUMA节点匹配:$ lscpu | grep NUMA
NUMA node(s): 2
NUMA node0 CPU(s): 0-8,18-26
NUMA node1 CPU(s): 9-17,27-35
这是经过将0和9写入/proc/irq//smp_affinity_list来实现的,其中IRQ编号是经过grep eth0 /proc/interrupts得到的:$ echo 0 > /proc/irq/265/smp_affinity_list
$ echo 9 > /proc/irq/266/smp_affinity_list
RPS
已测试了RPS的几种组合,为了提升延迟,咱们仅使用CPU 1–8和10–17减轻了IRQ处理处理器的负担。与IRQ的smp_affinity不一样,rps_cpus sysfs文件条目没有_list对应项,所以咱们使用位掩码列出RPS能够将流量转发到的CPU:$ echo "00000000,0003fdfe" > /sys/class/net/eth0/queues/rx-0/rps_cpus
$ echo "00000000,0003fdfe" > /sys/class/net/eth0/queues/rx-1/rps_cpus
Transmit Packet Steering (XPS)
将全部NUMA 0处理器(包括HyperThreading,即CPU 0-八、18-26)设置为tx-0,将NUMA 1(CPU 9-1七、27-37)设置为tx-12:$ echo "00000000,07fc01ff" > /sys/class/net/eth0/queues/tx-0/xps_cpus
$ echo "0000000f,f803fe00" > /sys/class/net/eth0/queues/tx-1/xps_cpus
Receive Flow Steering (RFS)
咱们计划使用60k常驻链接,官方文档建议将其四舍五入为最接近的2的幂:$ echo 65536 > /proc/sys/net/core/rps_sock_flow_entries
$ echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
$ echo 32768 > /sys/class/net/eth0/queues/rx-1/rps_flow_cnt
Nginx
Nginx使用18个worker,每一个worker都有本身的CPU(0-17),经过worker_cpu_affinity选项设置:**workers** 18;
**worker_cpu_affinity** 1 10 100 1000 10000 ...;
Tcpkali没有内置的CPU亲和性支持,为了利用RFS,咱们在任务集中运行tcpkali并调整调度程序,防止线程迁移的发生:$ echo 10000000 > /proc/sys/kernel/sched_migration_cost_ns
$ taskset -ac 0-17 tcpkali --threads 18 ...
与咱们尝试过的其余设置相比,此设置可以更均匀地在CPU内核之间分配中断负载,并以相同的延迟实现更好的吞吐量。
CPU 0和9专门处理NIC中断,不处理数据包,但它们还是最繁忙的:
RedHat的调整也与网络延迟配置文件一块儿使用,为了最大程度地减小nf_conntrack的影响,添加了NOTRACK规则,内核参数已调整为支持大量tcp链接:fs.file-max = 1024000
net.ipv4.ip_local_port_range = "2000 65535"
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_low_latency = 1
脚注
更多推荐
所有评论(0)