Cilium’s Bandwidth Manager can enforce bandwidth limits on individual pods, preventing noisy neighbors from consuming all available network resources and impacting your application’s performance.
Here’s how it works and how you can use it:
The Problem: Noisy Neighbors
Imagine you have a Kubernetes cluster where multiple pods share the same network interface. If one pod suddenly starts sending or receiving a massive amount of data (e.g., a database backup, a large file transfer, or a runaway process), it can saturate the network link. This "noisy neighbor" effect can lead to increased latency, packet loss, and ultimately, degraded performance for all other pods on that same interface, even if they are using minimal bandwidth themselves.
Cilium Bandwidth Manager to the Rescue
Cilium’s Bandwidth Manager (CBM) leverages the Linux Traffic Control (tc) subsystem to set granular bandwidth limits on a per-pod basis. It operates by creating tc classes and rules that intercept and throttle traffic originating from or destined for specific pods. This ensures that no single pod can monopolize the network resources, guaranteeing a more predictable and stable network environment for all your applications.
How it Works Under the Hood
CBM works by integrating with Cilium’s CNI (Container Network Interface) plugin. When CBM is enabled, Cilium will:
- Identify Pod Traffic: It determines which traffic belongs to which pod.
- Apply
tcRules: For pods with defined bandwidth limits, Cilium adds specifictc(traffic control) rules to the network interfaces. These rules are configured to queue and drop or delay packets exceeding the specified rates. - Rate Limiting: The
tcrules effectively enforce both ingress (incoming) and egress (outgoing) bandwidth limits for each pod.
Setting Up Bandwidth Management
To use CBM, you need to enable it in your Cilium configuration and then define CiliumBandwidthLimit Custom Resources (CRs) for the pods you want to manage.
1. Enable CBM in Cilium Configuration:
You can enable CBM by adding the following to your Cilium agent configuration (e.g., in a cilium-config ConfigMap or via Helm values):
# Example: In a ConfigMap or Helm values
config:
enable-bandwidth-manager: "true"
After updating the Cilium configuration, you’ll need to restart the Cilium agents on your nodes.
2. Define CiliumBandwidthLimit Resources:
You create CiliumBandwidthLimit CRs to specify the desired bandwidth for your pods. These resources can be applied to individual pods, pods matching a label selector, or all pods in a namespace.
Here’s an example of a CiliumBandwidthLimit resource that limits a specific pod to 100 Megabits per second (Mbps) for both ingress and egress:
apiVersion: cilium.io/v2alpha1
kind: CiliumBandwidthLimit
metadata:
name: my-app-bandwidth-limit
namespace: default
spec:
# This applies to a specific pod by name.
podName: my-critical-app
# You can also use label selectors to apply to multiple pods.
# podSelector:
# matchLabels:
# app: my-app
# Or apply to all pods in the namespace.
# namespaceSelector: {}
# Or apply to all pods in the cluster.
# clusterSelector: {}
# Egress limit (outgoing traffic from the pod)
maxEgress_Bps: "100M" # 100 Megabits per second
# Ingress limit (incoming traffic to the pod)
maxIngress_Bps: "100M" # 100 Megabits per second
Key Fields in CiliumBandwidthLimit:
podName: The name of the specific pod to apply the limit to.podSelector: A label selector to target multiple pods.namespaceSelector: A label selector to target namespaces.clusterSelector: A label selector to target clusters (if using multi-cluster).maxEgress_Bps: The maximum egress bandwidth. Accepts suffixes likeK,M,Gfor Kilobits, Megabits, Gigabits per second, respectively.maxIngress_Bps: The maximum ingress bandwidth.
Applying the Limit:
Once you’ve defined your CiliumBandwidthLimit CR, apply it to your cluster:
kubectl apply -f my-bandwidth-limit.yaml
Cilium will detect this CR and start applying the specified bandwidth limits to the target pod(s) using tc rules.
Verifying Bandwidth Limits
You can verify that the limits are being applied by checking the tc rules on the node where the pod is running.
-
Find the Node:
kubectl get pod my-critical-app -n default -o wideNote the
NODEwhere the pod is running. -
SSH into the Node: Access the node via SSH.
-
Inspect
tcRules: Use thetccommand to inspect the traffic control rules. You’ll typically look at thecilium_hostorcilium_netinterfaces, depending on your Cilium network configuration. The exact interface name might vary. You can often find the relevant interface by looking at the output ofip aand identifying the one associated with the pod’s network namespace.A common approach is to look at the root qdisc for the node’s main interface (e.g.,
eth0) and then traverse down:# Example: Inspecting the root qdisc on the node's primary interface NODE_IP=$(kubectl get node <NODE_NAME> -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}') ssh $NODE_IP "sudo tc qdisc show dev eth0" # You might need to dive deeper into the qdiscs to find the pod-specific ones. # Look for class identifiers that correspond to your pod's IP or network namespace. # The exact command to pinpoint the pod's traffic can be complex and depend on your network setup. # A simpler, though less direct, method is to monitor network traffic from the pod itself using tools like `iperf3`.Simpler Verification with
iperf3:A more practical way to verify is to run a bandwidth test from the limited pod to a target that can sustain high bandwidth.
- On the limited pod:
# Install iperf3 if not present apt update && apt install -y iperf3 # Start as a client, connecting to a server iperf3 -c <IPERF_SERVER_IP> -t 30 -i 1 - On an iperf3 server (e.g., another pod with high bandwidth capacity):
# Install iperf3 if not present apt update && apt install -y iperf3 # Start as a server iperf3 -s
Observe the reported bandwidth from the
iperf3client. It should not exceed the configuredmaxEgress_Bps(for traffic originating from the pod) ormaxIngress_Bps(for traffic destined to the pod). - On the limited pod:
The Nuance of Bandwidth Units
It’s crucial to understand that M in 100M refers to Megabits per second (Mbps), not Megabytes per second (MBps). This is a common point of confusion. 100 Mbps is approximately 12.5 MBps (100 / 8). Cilium uses the standard tc unit which is typically in bits per second.
When to Use It
- Preventing "Noisy Neighbors": The primary use case is to ensure that a single misbehaving or resource-intensive pod doesn’t degrade network performance for others.
- Guaranteed Bandwidth for Critical Apps: You can reserve a certain amount of bandwidth for your most critical applications by limiting the bandwidth of less important ones.
- Testing and Development: Useful for simulating network constraints during testing to ensure your application behaves gracefully under limited bandwidth.
By implementing Cilium Bandwidth Manager, you gain fine-grained control over your cluster’s network traffic, leading to a more stable, predictable, and performant environment for all your Kubernetes workloads.
The next logical step after managing bandwidth is to consider how to prioritize different types of traffic.