Please enable Javascript to view the contents

使用 Calico 限制 Pod 的带宽

 ·  ☕ 3 分钟

1. 测试全部带宽

  • 在目标主机上启动 iperf3 服务端
1
2
3
4
5
iperf3 -s

-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
  • 在客户端主机上测试
1
iperf3 -c x.x.x.x -p 5201 -t 10
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Connecting to host x.x.x.x, port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   151 MBytes  1.27 Gbits/sec  3562    164 KBytes
[  5]   1.00-2.00   sec   134 MBytes  1.12 Gbits/sec  230    164 KBytes
[  5]   2.00-3.00   sec   124 MBytes  1.04 Gbits/sec  250    213 KBytes
[  5]   3.00-4.00   sec   122 MBytes  1.03 Gbits/sec  229    195 KBytes
[  5]   4.00-5.00   sec   122 MBytes  1.03 Gbits/sec  342    198 KBytes
[  5]   5.00-6.00   sec   125 MBytes  1.05 Gbits/sec  351    212 KBytes
[  5]   6.00-7.00   sec   124 MBytes  1.04 Gbits/sec  319    220 KBytes
[  5]   7.00-8.00   sec   121 MBytes  1.02 Gbits/sec  286    220 KBytes
[  5]   8.00-9.00   sec   125 MBytes  1.05 Gbits/sec  233    191 KBytes
[  5]   9.00-10.00  sec   122 MBytes  1.03 Gbits/sec  377    192 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  1.24 GBytes  1.07 Gbits/sec  6179             sender
[  5]   0.00-10.00  sec  1.24 GBytes  1.06 Gbits/sec                  receiver

这说明两台主机之间的带宽是 1 Gbps 。

2. 确认 Calico 已经开启 Bandwidth 插件

  1. 在 Calico 的 ConfigMap 配置文件中应该可以看到 Bandwidth 插件
1
kubectl -n calico-system get cm cni-config  -o yaml
1
2
3
4
        {
          "type": "bandwidth",
          "capabilities": {"bandwidth": true}
        },
  1. 在主机上可以看到 calico-bandwidth 的插件
1
cat /etc/cni/net.d/10-calico.conflist
1
2
3
4
    {
      "type": "bandwidth",
      "capabilities": {"bandwidth": true}
    },

3. 创建带宽受限的 Pod

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-rate-limit
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-rate-limit
  template:
    metadata:
      labels:
        app: test-rate-limit
      annotations:
        kubernetes.io/egress-bandwidth: "1M"
        kubernetes.io/ingress-bandwidth: "1M"
    spec:
      containers:
      - name: main
        image: registry.cn-beijing.aliyuncs.com/shaowenchen/demo-iperf3:latest
        ports:
        - containerPort: 80
EOF

这里的 M 单位是 Mbps,所以这里设置的是 1 Mbps 的带宽。

kubernetes.io/egress-bandwidth 表示的是 Pod 的出口带宽,也就是其他应用访问这个 Pod 的带宽。

kubernetes.io/ingress-bandwidth 表示的是 Pod 的入口带宽,也就是这个 Pod 访问其他应用的带宽。

4. 在 Pod 中测试带宽

  • 在容器中启动客户端
1
kubectl exec deployment/test-rate-limit  -- bash -c "iperf3 -c x.x.x.x -p 5201 -t 10"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Connecting to host x.x.x.x, port 5201
[  5] local 10.244.101.19 port 60566 connected to x.x.x.x port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  8.81 MBytes  73.9 Mbits/sec    0    382 KBytes
[  5]   1.00-2.00   sec  0.00 Bytes  0.00 bits/sec    0    388 KBytes
[  5]   2.00-3.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   3.00-4.00   sec   816 KBytes  6.68 Mbits/sec    0    395 KBytes
[  5]   4.00-5.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   5.00-6.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   6.00-7.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   7.00-8.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   8.00-9.00   sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
[  5]   9.00-10.00  sec  0.00 Bytes  0.00 bits/sec    0    395 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  9.61 MBytes  8.06 Mbits/sec    0             sender
[  5]   0.00-10.11  sec  8.03 MBytes  6.67 Mbits/sec                  receiver
  • 将 kubernetes.io/egress-bandwidth 设置为 100M
1
kubectl exec deployment/test-rate-limit  -- bash -c "iperf3 -c x.x.x.x -p 5201 -t 10"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Connecting to host x.x.x.x, port 5201
[  5] local 10.244.101.50 port 34504 connected to x.x.x.x port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   127 MBytes  1.06 Gbits/sec  2262   1.37 KBytes
[  5]   1.00-2.00   sec   124 MBytes  1.04 Gbits/sec  2423    198 KBytes
[  5]   2.00-3.00   sec  25.0 MBytes   210 Mbits/sec   26    177 KBytes
[  5]   3.00-4.00   sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
[  5]   4.00-5.00   sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
[  5]   5.00-6.00   sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
[  5]   6.00-7.00   sec  12.5 MBytes   105 Mbits/sec    0    177 KBytes
[  5]   7.00-8.00   sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
[  5]   8.00-9.00   sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
[  5]   9.00-10.00  sec  11.2 MBytes  94.4 Mbits/sec    0    177 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   355 MBytes   298 Mbits/sec  4711             sender
[  5]   0.00-10.01  sec   352 MBytes   295 Mbits/sec                  receiver

iperf3 测试持续的时间越长,带宽值越稳定,越接近设置的限制值。

5. 总结

在集群除了 CPU、Memory 之外,IO 中的带宽也是受限资源,特别是在高密度部署的集群中,时常会因为带宽抢占,导致服务的延时增加。

本篇主要是介绍了如何使用 Calico 的 Bandwidth 插件来限制 Pod 的带宽,通过设置 kubernetes.io/egress-bandwidth 和 kubernetes.io/ingress-bandwidth 来限制 Pod 的出口和入口带宽。

值得注意的是,虽然对 Pod 的带宽进行了限制,在并不是实时有效,在流量发起时,可能会出现瞬时的带宽超限情况,但是随着时间的推移,带宽会逐渐稳定在限制值附近。

另外在测试过程还发现,如果 Pod 使用了 HostNetwork,那么设置的带宽限制是无效的,这是因为 HostNetwork 的 Pod 是直接使用主机的网络资源,所以无法通过 Calico 的 Bandwidth 插件来限制。


微信公众号
作者
微信公众号