This page looks best with JavaScript enabled

Using Calico to Limit Pod Bandwidth

1. Testing the Full Bandwidth

  • Start the iperf3 server on the target host
1
2
3
4
5
iperf3 -s

-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
  • Test from the client host
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

This shows that the bandwidth between the two hosts is 1 Gbps.

2. Confirming That Calico Has the Bandwidth Plugin Enabled

  1. The Bandwidth plugin should be visible in Calico’s ConfigMap configuration
1
kubectl -n calico-system get cm cni-config  -o yaml
1
2
3
4
        {
          "type": "bandwidth",
          "capabilities": {"bandwidth": true}
        },
  1. The calico-bandwidth plugin can be seen on the host
1
cat /etc/cni/net.d/10-calico.conflist
1
2
3
4
    {
      "type": "bandwidth",
      "capabilities": {"bandwidth": true}
    },

3. Creating a Pod with a Bandwidth Limit

 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: shaowenchen/demo:iperf3
        ports:
        - containerPort: 80
EOF

Here the M unit is Mbps, so this sets a bandwidth of 1 Mbps.

kubernetes.io/egress-bandwidth is the Pod’s egress bandwidth, that is, the bandwidth at which other applications access this Pod.

kubernetes.io/ingress-bandwidth is the Pod’s ingress bandwidth, that is, the bandwidth at which this Pod accesses other applications.

4. Testing Bandwidth Inside the Pod

  • Start the client inside the container
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
  • Set kubernetes.io/egress-bandwidth to 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

The longer the iperf3 test runs, the more stable the bandwidth value and the closer it gets to the configured limit.

5. Summary

In a cluster, besides CPU and Memory, bandwidth is also a constrained resource within IO. Especially in densely deployed clusters, bandwidth contention frequently increases service latency.

This post has mainly described how to use Calico’s Bandwidth plugin to limit a Pod’s bandwidth, by setting kubernetes.io/egress-bandwidth and kubernetes.io/ingress-bandwidth to limit the Pod’s egress and ingress bandwidth.

It is worth noting that although the Pod’s bandwidth is limited, it does not take effect in real time. When traffic starts, there may be a momentary bandwidth overshoot, but as time goes on the bandwidth gradually stabilizes near the limit value.

During testing I also found that if a Pod uses HostNetwork, the configured bandwidth limit is ineffective. This is because a HostNetwork Pod uses the host’s network resources directly, so it cannot be limited through Calico’s Bandwidth plugin.


微信公众号
WRITTEN BY
微信公众号