计算机系统应用教程网站

网站首页 > 技术文章 正文

Cilium eBPF 带宽管理器 带宽管理软件

btikc 2024-10-19 03:21:18 技术文章 10 ℃ 0 评论

本文介绍了如何配置Cilium的带宽管理器,以优化TCP和UDP工作负载,并在需要时通过EDT(Earliest Departure Time )算法和eBPF有效地限制单个Pod的速率。Cilium的带宽管理器也是为Pods启用BBR拥塞控制算法的前置条件,如下所述。

带宽管理器不依赖于CNI链,而是原生集成到Cilium中。因此,它不必依赖 bandwidth CNI 插件。在多队列网络接口场景下TBF(Token Bucket Filter)算法存在扩展性问题,建议不要使用基于TBF算法的CNI带宽插件。

Cilium的带宽管理器支持kubernetes.io/egress-bandwidthPod注解,在本机主机网络设备的出口强制设置带宽限制规则。Cilium带宽管理支持直接路由和隧道模式。

Cilium不支持kubernetes.io/ingress-bandwidth,也不建议使用。限制带宽发生在网络设备的egress处,以减少网络带宽的使用加快网络速度。而在ingress限制带宽需要在节点的关键快速路径上通过ifb设备添加二外一层缓冲区队列,ingress流量首先需要重定向到ifb的egress点,以便在流量上升到堆栈之前执行整形。此时,通信量其实已经占用了线路上的带宽使用量,节点已经在处理数据包上花费了资源。因此,Cilium的带宽管理器忽略了kubernetes.io/ingress-bandwidth注解。

带宽管理器需要v5.1x或更新的内核

设置Helm仓库

helm repo add cilium https://helm.cilium.io/

默认情况下,Cilium的带宽管理器处于禁用状态。要在启用带宽管理器的情况下安装Cilium,请运行

helm install cilium cilium/cilium --version 1.12.2 \
  --namespace kube-system \
  --set bandwidthManager.enabled=true

在已安装Cilium的集群中启用带宽管理器请使用

helm upgrade cilium cilium/cilium --version 1.12.2 \
  --namespace kube-system \
  --reuse-values \
  --set bandwidthManager.enabled=true
kubectl -n kube-system rollout restart ds/cilium

本机主机网络设备自动发现的机制是主机上具有默认路由或已分配Kubernetes InternalIP或ExternalIP关联的本机设备。如果两者都存在,则首选InternalIP而不是ExternalIP。要更改和手动指定设备,请在Helm选项中设置设备名称(例如,devices='{eth0,eth1,eth2}')。在所有Cilium管理的节点上,列出的设备必须命名相同。

验证Cilium Pods是否正确启动:

$ kubectl -n kube-system get pods -l k8s-app=cilium
NAME                READY     STATUS    RESTARTS   AGE
cilium-crf7f        1/1       Running   0          10m
cilium-db21a        1/1       Running   0          10m

cilium status CLI命令可以验证Cilium中是否已启用带宽管理器功能,它通过BandwidthManager的信息行提供可见性。它还转储实施egress带宽限制的设备列表:

$ kubectl -n kube-system exec ds/cilium -- cilium status | grep BandwidthManager
BandwidthManager:       EDT with BPF [BBR] [eth0]

为了验证出口带宽限制是否确实得到了实施,可以在不同的节点上部署两个netperf Pod,一个充当服务器,另一个充当客户端:

---
apiVersion: v1
kind: Pod
metadata:
  annotations:
    # Limits egress bandwidth to 10Mbit/s.
    kubernetes.io/egress-bandwidth: "10M"
  labels:
    # This pod will act as server.
    app.kubernetes.io/name: netperf-server
  name: netperf-server
spec:
  containers:
  - name: netperf
    image: cilium/netperf
    ports:
    - containerPort: 12865
---
apiVersion: v1
kind: Pod
metadata:
  # This Pod will act as client.
  name: netperf-client
spec:
  affinity:
    # Prevents the client from being scheduled to the
    # same node as the server.
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - netperf-server
        topologyKey: kubernetes.io/hostname
  containers:
  - name: netperf
    args:
    - sleep
    - infinity
    image: cilium/netperf

一旦Pod启动并运行,netperf客户端Pod就可以测试netperf服务器Pod上的egress带宽限制。由于测试流方向是从netperf服务器Pod到客户端,我们需要检查TCP_MAERTS:

$ NETPERF_SERVER_IP=$(kubectl get pod netperf-server -o jsonpath='{.status.podIP}')
$ kubectl exec netperf-client -- \
    netperf -t TCP_MAERTS -H "${NETPERF_SERVER_IP}"
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.217.0.254 () port 0 AF_INET
Recv   Send    Send
Socket Socket  Message  Elapsed
Size   Size    Size     Time     Throughput
bytes  bytes   bytes    secs.    10^6bits/sec

 87380  16384  16384    10.00       9.56

可以看出,netperf服务器Pod的出口流量限制为每秒10Mbit。

为了从BPF检查当前端点带宽设置,可以运行以下命令(将cilium-xxxxx替换为与netperf服务器Pod位于同一节点的cilium Pod的名称):

$ kubectl exec -it -n kube-system cilium-xxxxxx -- cilium bpf bandwidth list
IDENTITY   EGRESS BANDWIDTH (BitsPerSec)
491        10M

每个Pod在Cilium中表示为具有标识的Endpoint。上述标识与cilium endpoint list命令相关联。

带宽限制工作于每个Pod范围。在我们的示例中,如果创建了Pod的多个副本,那么每个Pod实例都会收到10M带宽限制。

BBR for Pods

Cilium的带宽管理器提供基础设置的MQ/FQ设置,并对Pods使用TCP BBR拥塞控制。

BBR特别适合Pod在Kubernetes Services后面,用户来自外部互联网的场景。BBR能提供更高的带宽和更低延迟。已经证明BBR的吞吐量可以达到目前最好的基于丢包的拥塞控制的2700倍,排队延迟可以降低25倍。

BBR for Pods需要v5.18.x或更高版本的Linux内核。

要启用带宽管理器的BBR拥塞控制,请使用以下配置进行部署:

helm upgrade cilium cilium/cilium --version 1.12.2 \
  --namespace kube-system \
  --reuse-values \
  --set bandwidthManager.enabled=true \
  --set bandwidthManager.bbr=true
kubectl -n kube-system rollout restart ds/cilium

为了使BBR能够可靠地为Pods工作,它需要5.18或更高版本的内核。正如Linux Plumbers 2021 talk演讲中所说。较旧的内核在数据包从Pod切换到主机网络名称空间时不会保留时间戳,内核的速率基础设施不能正常工作(不是Cilium的问题)。

Cilium的研发人员帮助解决了新版内核中的这个问题,保留时间戳,从而使Pods的BBR工作。在新内核之前,BBR只适用于初始网络名称空间(主机)中的套接字。BBR还需要eBPF Host-Routing,以便始终保持网络数据包的套接字关联,直到数据包在主机名称空间中的物理设备上达到FQ排队规则。(如果没有eBPF Host-Routing,数据包的套接字关联将在主机堆栈forwarding/routing内孤立。)

cilium status通过BandwidthManager提供了是否启用带有BBR的带宽管理器信息的可见性:

$ kubectl -n kube-system exec ds/cilium -- cilium status | grep BandwidthManager
BandwidthManager:       EDT with BPF [BBR] [eth0]

启用此设置后,cilium将以BBR作为所有新生成的Pod的默认值。理想情况下,在创建集群时,在初始Cilium安装时选择BBR,这样集群中的所有节点和Pod都会统一使用BBR,否则仍在使用CUBIC的其他连接可能会存在潜在的不公平问题。还请注意,由于BBR探测的性质,与CUBIC相比,您可能会发现TCP重传的速率更高。

我们建议在pod作为公开服务的后端所在的集群使用BBR,提升网络性能。

限制

  • 带宽强制目前无法与L7 Cilium网络策略结合使用。如果策略在egress选择了Pod,那么这些Pod的带宽控制将被禁用。
  • 带宽强制不适用于Kind之类的嵌套网络命名空间的环境。因为这些环境通常无法访问/proc/sys/net/core下的全局sysctl,带宽控制依赖于sysctl。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表