根据问题现象检索社区问题
社区也有一些同类现象
Traffic shaping with Calico and k8s · Issue #6232 · projectcalico/calico · GitHub
bandwidth and burst limits per pod behavior · Issue #609 · containernetworking/plugins · GitHub
推断该现象和qdisc的burst配置有关
了解到calico的限速插件采用的tc工具,通过了解burst参数主要是用来配置大流量的缓冲区,如果缓冲区太小则会出现丢包的情况。
求证方式
为了验证个问题是否由burst配置造成,设计一个简单的测试场景。 通过配置burst参数的大小,应该能够控制峰值流量,也就能够解决第一秒流量爆发的情况,如果将burst参数配置和limite一样,结果应该不会再出现第一秒流量爆发的情况。
思路一:通过calico配置burst
在calico官方查到对于bandwidth的配置目前支持 limite,而对于burst的配置没有比较明确的样例。
CNI 官网的配置待测试
配置之后可以通过tc qdisc show 查看limit和burst的 的数值是否如预期。
思路2:通过sidecar自己打包tc工具,挂在业务pod上直接配置限速。
测试场景
涉及到修改cni配置,需重启calico,创建新的k8s集群进行测试。
创建相应的pod: iperf-server、iperf-server-02和iperf-client。
使用镜像及方法参考: https://hub.docker.com/r/networkstatic/iperf3
测试一:未做限速情况
测试二:在iperf-server上配置限速10MB的情况,能够复现第一秒流量爆发
所在node的calico容器中查看限速参数,能够看到采用的是tbf队列
测试三:通过CNI修改burst参数测试
通过在cni插件上全局配置burst参数,修改configmap中calico-config的值,增加全局配置,修改完新增的pod会被配置
创建新的iperf pod:iperf3-server-02 ,并通过客户端发送测试数据。 能够看到通过调整burst确实能够有效的控制第一秒流量爆发的情况。但这种全局配置不一定适合真实的场景中。
butst的值是1250000b,看起来比较奇怪。
从官方文档中看到,burst的值的单位是 bytes/cell ,cell默认大小是8,burst的值看起来是10Mbit/8 得到的1250000b 。
通过文档了解了tbf的原理
calico是通过tbf令牌桶排队规则实现的限速。
参考《Linux 流量控制实施指南》
从这篇文章中了解倒了为什么第一秒会有流量的爆发的原理,因为tc的限速本质上是限制令牌桶的产生速率,也就是ingress rate参数,burst是最大的空桶的数量,那么第一秒流量来的时候,所有桶都会在短时间内装满,所以会有流量的爆发。
测试四:手动配置tc的tbf队列进行限速
清除cni的全局限速配置。 在calico node上确认没有限速策略。
查询iperf-server-02对应的网卡,对该网卡手动配置限速
tc qdisc add dev cali7fcb7e5dded root tbf rate 1Mbps burst 1Mb limit 1Mb
配置结果会转换单位:
流量测试:
通过手动配置tbf的参数,基本可以控制流量。