Cilium创建pod network源码解析

本文详细解析了Cilium如何创建Pod网络,包括cilium-operator如何根据CNI标准管理IPAM,分配Pod CIDR,以及cilium-agent如何创建veth pair、分配Pod IP并部署BPF程序实现负载均衡和服务发现。Cilium通过BGP协议宣告路由,简化运维,提高可观测性。CNI流程主要包括创建网络资源、分配IP及下发eBPF程序三个步骤,实现了高性能和高效网络管理。
摘要由CSDN通过智能技术生成

01

Overview

我们生产K8s使用容器网络插件 Cilium 来创建 Pod network,下发 eBPF 程序实现 service 负载均衡来替换 kube-proxy,并且使用 BGP 协议来宣告路由给交换机,使得 pod ip 在内网可达。

目前 BGP speaker 使用 bird 软件, 不过随着 Cilium 最近新版本已经集成 MetalLB 库(https://github.com/cilium/metallb),可以使用 MetalLB 自带的 BGP speaker 来宣告路由,后续只需要部署 cilium-operator deployment 和 cilium-agent daemonset 两个组件,无需部署 bird daemonset 组件,运维成本更低,而且可以通过 cilium metrics 来获取 BGP 相关可观测性数据,具体详情可见 #16525 (https://github.com/cilium/cilium/pull/16525/),代码可见 pod_cidr.go(https://github.com/cilium/cilium/blob/master/pkg/bgp/speaker/pod_cidr.go)

Cilium 作为容器网络插件遵循 CNI 标准,部署时主要部署两个组件:cilium-operator deployment 和 cilium-agent daemonset。

cilium-operator 组件会根据选择的 ipam mode 不同选择不同的 ipam 逻辑,一般默认选择 cluster-pool 模式,这样 cilium-operator 会给每一个 v1.Node 对象创建对应的 CiliumNode 对象,且根据 cluster-pool-ipv4-cidr 和 cluster-pool-ipv4-mask-size 两个配置计算出每一个节点的 pod cidr subnet 值,并存储在该 CiliumNode 对象 spec.ipam.podCIDRs 字段中。比如给集群设置两个集群网段 cluster-pool-ipv4-cidr 为 10.20.30.40/24 和 50.60.70.80/24,cluster-pool-ipv4-mask-size 设置为 26,cilium-operator 组件可以支持一个网段消耗完了可以从下一个网段继续分配 pod cidr net,代码见 clusterpool.go#L107-L141(https://github.com/cilium/cilium/blob/master/pkg/ipam/allocator/clusterpool/clusterpool.go#L107-L141 )。根据 cluster-pool ipam 逻辑会依次把 cluster-pool-ipv4-cidr 10.20.30.40/24 分成 2^(26-24)=4 个子网段 pod cidr subnet,如果 10.20.30.40/24 消耗完了,则继续消费 50.60.70.80/24 网段,一个子网段的切分可见代码 cidr_set.go(https://github.com/cilium/cilium/blob/master/vendor/github.com/cilium/ipam/cidrset/cidr_set.go),这个逻辑也是复用的 k8s nodeipam 逻辑 cidr_set.go(https://github.com/kubernetes/kubernetes/blob/v1.22.3/pkg/controller/nodeipam/ipam/cidrset/cidr_set.go)总之,cilium-operator 组件会根据 v1.node 的添加和删除,来添加和删除 CiliumNode 对象,同时使用 IPAM 来管理每一个 node 的子网 allocate/release 操作。

cilium-agent 组件会从其对应的子网段出再去划分出每一个 pod ip,上文已经说过 cilium-agent 或者 bird 会把每一个子网段 pod cidr subnet 通过 BGP 协议宣告给交换机,本机 node ip 作为下一跳,所以使得每一个 pod ip 内网可达。kubelet 在创建 pod sandbox container 时会调用 cilium cni 二进制文件来为当前 pod 创建 network,同时 cilium cni 作为客户端会调用服务端 cilium-agent pod 来分配 pod ip。

那 cilium-agent 做了哪些工作呢?以及默认不像 calico 那样每一个 pod 的宿主机端网卡,都会创建对应的路由,cilium 如何下发哪些 eBPF 程序做到这一点的?这是本文重点讨论的问题。

02

Cilium 工作原理

Cilium CNI 在为 pod 创建网络资源的过程,粗略说起来不复杂,主要分为三步:

  • 为 pod 创建网卡 veth pair,并配置 mac 以及容器侧的路由等等网络资源

  • Cilium IPAM 从该节点的子网段 pod cidr 中分配出一个 ip,并配置到 pod 网卡

  • 为该 pod 创建对应的 CiliumEndpoint/CiliumIdentity 对象,计算并下发 network policy 规则,以及下发 eBPF 程序到 pod 网卡上。

限于篇幅以及为了精简,本文暂不考虑 network policy 逻辑,以及只考虑 create pod 时 cilium 的处理逻辑,不考虑 delete pod 时的逻辑。

01 Cilium 创建网络资源

在创建 pod 时,kubelet 会调用 Cilium 二进制文件,该二进制文件路径在启动 kubelet 时通过参数 --cni-bin-dir 传进来的,一般默认为 /opt/cni/bin/ ,

比如在宿主机该目录下存在 /opt/cni/bin/cilium-cni 二进制文件,kubelet 启动参数 --cni-conf-dir 包含 cni 配置文件路径,一般默认为 /etc/cni/net.d/05-cilium.conf ,如文件内容为:

{
  "cniVersion": "0.3.1",
  "name": "cilium",
  "type": "cilium-cni",
  "enable-debug": false
}

kubelet 和 cni 插件交互的具体内容可以参见之前的文章 《Kubernetes学习笔记之Calico CNI Plugin源码解析(一)》(https://juejin.cn/post/6916326439851655176) 

该文件内容将会被 json 反序列化为 NetConf (https://github.com/cilium/cilium/blob/master/plugins/cilium-cni/types/types.go#L22-L33)对象,cni 代码中 args.StdinData 参数(https://github.com/cilium/cilium/blob/master/plugins/cilium-cni/cilium-cni.go#L278) 即为该文件内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值