k8s实践:Cilium集群IPAM实现
背景
通过前面遇到的Cilium集群下线节点导致某个在线节点容器网络不通问题排查结果,可以确定集群中因为k8s Node资源spec.podCIDRs与CiliumNode资源的spec.ipam.podCIDRs字段不一致,而节点上Pod网段实际以CiliumNode资源的spec.ipam.podCIDRs为准,但是Cilium上报网络设备的BGP路由信息以k8s Node资源spec.podCIDRs为准,这就导致了网络设备上收到的路由信息与节点实际的Pod网段不一致,当下线一个节点时可能会影响另一个节点Pod网络连通性。环境信息如下所示:
# kubectl get node -o custom-columns=NAME:.metadata.name,PodCIDR:.spec.podCIDRs
NAME PodCIDR
master1 [10.5.112.0/24]
master2 [10.5.114.0/24]
master3 [10.5.113.0/24]
node01 [10.5.115.0/24]
# kubectl get ciliumnode -o custom-columns=NAME:.metadata.name,PodCIDR:.spec.ipam.podCIDRs
NAME PodCIDR
master1 [10.5.113.0/24]
master2 [10.5.115.0/24]
master3 [10.5.114.0/24]
node01 [10.5.112.0/24]但是这个问题难道就是个Cilium项目的Bug么?还是我们配置不恰当导致的?带着问题我们再深入分析一波
问题分析
环境信息
当前集群的Cilium配置(这里省略掉一些无关的配置)
这里配置的IPAM模式为cluster-pool。
Cilium IPAM Mode
查看Cilium文档我们知道常见IPAM Mode支持以下类型:Cluster Scope (Default)、Kubernetes Host Scope。
Kubernetes Host Scope
开启Kubernetes host-scope IPAM模式需要设置ipam: kubernetes,这种模式下Cilium直接使用k8s Node的podCIDRs作为当前节点Pod网段并用于分配Pod IP。
架构

注意:该模式下需要依赖
kube-controller-manager组件开启--allocate-node-cidrs参数来自动为每一个节点分配podCIDRs
Cluster Scope (Default)
cluster-scope IPAM模式原理类似于Kubernetes Host Scope模式,它也是每个节点分配一个独立的PodCIDRs。不同之处是它通过Cilium Operator来管理每个节点的PodCIDRs,这些信息维护在CRD Cilium资源里面。这个模式的优点是不依赖于k8s为每个节点分配的PodCIDRs。
架构

BGP功能源码分析
Cilium 1.11.9
这里我们发现Cilium bgpSpeaker宣告的podCIDRs只支持从k8s Node的podCIDRs获取,更详细的源码分析请参考源码追踪
Cilium 1.14.2
这里发现Cilium bgpSpeaker宣告的podCIDRs获取方式支持k8s Node和CiliumNode两种方式:
收到k8s Node事件以后两种不IPAM模式下的处理方法实现,这里只以Add事件为例
两种获取podCIDRs的方式实现
查看Cilium bgpSpeaker宣告的podCIDRs支持k8s Node和CiliumNode两种方式的commit链接,可以看到1.12以上所有版本都已经包含了该commit。
结论
通过以上分析我们有两个结论
Cilium 1.12以下版本bgpSpeaker只支持从k8s Node中获取podCIDRs,所以这些版本需要开启BGP路由宣告的话,IPAM模式只能使用
Kubernetes Host Scope。Cilium 1.12以上的版本bgpSpeaker支持从k8s Node和CiliumNode中获取podCIDRs,所以这些版本需要开启BGP路由宣告的话,IPAM模式
Cluster Scope (Default)和Kubernetes Host Scope都可以选择。
Last updated