想象一座快速扩张的智慧城市。市政规划局(Kubernetes)把城市分成若干片区(Node),每栋公寓里的每家住户(Pod)入住时,都会拿到一个全市唯一的门牌号(IP地址)。市政定了一条铁规矩:任何两家住户,无论住在哪个片区,都必须能直接互相寄信,不需要总机转接。但“能寄信”只是目标,谁来送、怎么送,需要一套完整的投递系统。 K8s的答案是:先定一个标准接口(CNI),再让各家快递公司按标准接入。于是有了两套风格迥异的投递方案:Calico像是传统邮政系统——每个邮局(节点)通过BGP广播“我这栋楼能送到哪些门牌号”,邮差按全局地图一步步投递;Cilium则像配备了智能管家机器人的新型物业——机器人(eBPF)直接住在内核里,能秒懂住户的“意图”,绕过层层分拣,一步把信送到对方门口。 本文就用这座城市的快递故事,带你拆解CNI、Calico与Cilium的来龙去脉、数据面原理、性能差异,以及如何为你的集群选一套合适的投递系统。

岗位关联

学透K8s网络是云原生架构师的必修课:掌握CNI机制与Calico/Cilium的取舍,才能在集群扩容、故障排查和安全策略设计中游刃有余,这是从“会用K8s”迈向“能造K8s”的关键一步。

目录
  1. 可视化演示
  2. 网络基础模型
  3. CNI插件机制
  4. Calico数据面
  5. Cilium数据面
  6. 网络策略对比
  7. 性能与选型
  8. 部署与排障
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示CNI插件工作流程、Calico(BGP/iptables)与Cilium(eBPF)数据面对比及大规模集群性能差异。

本节配有交互动效(进入视口后自动加载,约 3KB)。

CNI插件工作流程 Pod创建触发CNI ADD操作 veth pair配置+IP分配 POD→CNI(ADD)→veth+IP→Route→Net CNI插件完成网络配置使Pod可通信

网络基础模型

市政规划局(Kubernetes)在发门牌号之前,先定了一套全市统一的地名规则:每个片区(Node)领取一段连续的门牌号,比如10.244.1.x到10.244.3.x;每户住户(Pod)入住时,从所在片区段里领走一个唯一号码(IP)。规则写明:任意两户之间,不管是隔壁邻居(同节点)还是城市两端(跨节点),都必须能直通互通,不许经过话务员人工转接。这条规则,就是K8s的“扁平网络模型”。

扁平网络模型是K8s对Pod网络的核心承诺:每个Pod的IP全局唯一;任意两个Pod可以直接通信,不经过NAT。这个承诺本身不含实现细节——K8s把“如何兑现”交给了CNI插件。就像市政只规定“能直通”,但光纤怎么铺、交换机怎么配,由通信公司(插件)负责。

在实现层面,每个节点都有一块PodCIDR网段预留给Pod。kube-controller-manager负责给节点分配网段,Pod的IP由容器运行时从该网段中分配。同节点Pod通过veth网卡对和cni0网桥直接互通;跨节点则依赖CNI插件提供的路由或隧道。此外,Service是K8s额外提供的一个“前台总机”:它给一组Pod一个稳定的虚拟IP(ClusterIP),接收外部访问并转发给背后的Pod,解决了Pod IP会随重建而变化的问题。理解Pod网络和Service网络的分工,是排障的第一步——前者归CNI管,后者归kube-proxy管。

门牌号规则定完,住户们安顿下来。但真正的挑战在“送信”环节——谁来送、走什么路线?这就轮到快递协会(CNI)登场了。

PodIP=PodCIDR基址+Pod在节点内的偏移序号\text{PodIP} = \text{PodCIDR基址} + \text{Pod在节点内的偏移序号}
PodCIDR基址是节点网段的起始IP,偏移序号是Pod从该网段领取的顺序号,两者相加得到Pod的全局唯一IP。
  1. PodCIDR基址节点所在子网的起始地址,相当于公寓楼门牌号段的首号。例:节点网段10.244.2.0/24,基址是10.244.2.0。
    PodCIDR基址=节点网段起始IP\text{PodCIDR基址} = \text{节点网段起始IP}
  2. Pod在节点内的偏移序号Pod在该节点内的分配顺序,类似楼内房间号。每个Pod占用一个唯一偏移量。
    偏移序号∈[2,PodPerNode+1]\text{偏移序号} \in [2, \text{PodPerNode}+1]
  3. 两者相叠加基址 + 偏移 = 该Pod的全局唯一IP,保证全市不重号。
    PodIPi,j=基址i+j\text{PodIP}_{i,j} = \text{基址}_{i} + j

CNI插件机制

市政意识到:不能允许各家快递公司各行其是,否则住户得记住N套寄件流程。于是“快递协会”(CNI)出场,制定了一份统一面单规范:不管哪家公司接单,信封尺寸、面单字段、收寄流程必须一致。这样住户(Pod)只要按标准填单,就能享受任意一家快递(网络插件)的服务。

CNI(Container Network Interface,容器网络接口)是Kubernetes、容器运行时(containerd/CRI-O)与网络插件之间的标准协议。它定义了两个核心操作:ADD(把新Pod接入网络)和DEL(把Pod移出网络)。任何网络插件——Flannel、Calico、Cilium、Weave——只要实现了这两个操作,就能无缝接入K8s。

当用户创建Pod,kubelet通过CRI(容器运行时接口)请求containerd启动容器。containerd发现Pod需要网络,就调用预先配置的CNI插件。插件收到的参数包括容器ID、网络命名空间路径、网卡名等。它负责:创建veth网卡对、把一端塞进容器网络命名空间、分配IP、写路由表、把另一端挂到网桥上。整个过程在容器启动的毫秒级窗口内完成。CNI配置通常存放在/etc/cni/net.d/目录,插件二进制在/opt/cni/bin/。

有了统一面单和标准流程,快递公司可以随时换新:今天用Calico,明天换Cilium,住户无感知。标准带来的自由,正是CNI最大的价值。接下来看两套主流投递系统的内部运作。

CNI ADD(ContainerID⏟容器ID,NetNS⏟网络命名空间,CNI_IFNAME⏟容器内网卡名)\text{CNI ADD}(\underbrace{\text{ContainerID}}_{容器ID}, \underbrace{\text{NetNS}}_{网络命名空间}, \underbrace{\text{CNI\_IFNAME}}_{容器内网卡名})
这是CNI插件收到的最关键三个参数,如同快递面单上的三个核心字段。
  1. ContainerID(容器ID)唯一标识要接入网络的容器,相当于快递面单上的“收件人主单号”。
    ContainerID=容器唯一标识符\text{ContainerID} = \text{容器唯一标识符}
  2. NetNS(网络命名空间)容器的网络命名空间路径(/proc/\<pid\>/ns/net),插件要进到这个房间里配置网络。
    NetNS=/proc/PID/ns/net\text{NetNS} = \text{/proc}/\text{PID}/\text{ns/net}
  3. CNI_IFNAME(容器内网卡名)容器内预期生成的网卡名,默认eth0,相当于“房间内收货口编号”。
    CNI_IFNAME=eth0\text{CNI\_IFNAME} = \text{eth0}

Calico数据面

Calico是传统邮政系统的集大成者。每个邮局(节点)定期用BGP广播向全城宣布:“我这栋楼能送到哪些门牌号。”所有邮局收到广播后,各自拼出一张全局投递地图——不需要中央调度员告诉它每封信该走哪条路,地图上写得明明白白。

BGP(Border Gateway Protocol,边界网关协议)是互联网实际使用的“跨网络路由广播语言”。Calico把每个K8s节点当成一个BGP路由器,节点之间直接建立BGP会话(Peer),互相通告Pod网段路由,从而构造出完整的路由表。数据包到达后查表转发即可。

跨节点通信时,Calico面临一个现实问题:目标Pod的IP不一定在物理网络里可路由。解决办法是“封装”:IPIP模式给原始IP包套一个外层IP头(20字节),目标地址是目的节点IP,像把信装进一个普通信封;VXLAN模式则套上UDP+VXLAN头(50字节),像加了防震气泡的信封,适合底层网络不支持IPIP的三层网络。无论哪种模式,封装都会压缩有效负载:物理MTU 1500下,IPIP的有效MTU是1480,VXLAN是1450。Calico还支持eBPF数据面,但标志性路线是BGP路由。

邮政系统的优势是简单、直接,每条路线都由邮局间“人传人”的广播达成。但节点多了,邮局之间要维持的消息会话(全互联)会飞速膨胀——100个节点就有4950条BGP会话。地图越来越大、越来越贵,这正是Calico在超大规模下要面对的问题。

C=N(N−1)2C = \frac{N(N-1)}{2}
封装会“吃掉”一部分数据包空间,容器内网卡能发送的最大数据包必须减去封装头字节数。
  1. 物理MTU网卡允许的最大帧大小,默认1500字节。
    物理MTU=1500\text{物理MTU} = 1500
  2. 封装头IPIP多20字节,VXLAN多50字节。
    封装头IPIP=20,封装头VXLAN=50\text{封装头}_{\text{IPIP}} = 20, \quad \text{封装头}_{\text{VXLAN}} = 50
  3. 有效MTU容器内网卡能发送的最大数据包,超过就必须分片,分片会带来性能损失。
    有效MTUIPIP=1480,有效MTUVXLAN=1450\text{有效MTU}_{\text{IPIP}} = 1480, \quad \text{有效MTU}_{\text{VXLAN}} = 1450

Cilium数据面

Cilium像新一代智能物业,给每栋楼装上“管家机器人”。这个机器人(eBPF)不住在邮局,而是住在楼宇的“神经系统”(Linux内核)里,每封信只要在收件口一刷,机器人立刻识别出收件人,从楼内直达通道直接送到对方家门口——完全不需要经过邮局分拣中心。

eBPF(extended Berkeley Packet Filter)是Linux内核的一项革命性能力:允许用户在内核中安全运行由内核验证的程序。Cilium把数据包处理逻辑编译成BPF字节码,挂载到网卡收包点,让数据包在进入传统协议栈之前就被识别、决策和转发。

Cilium最典型的能力是SocketLB:当进程发起connect()时,eBPF程序在socket层直接完成ClusterIP到目标Pod IP的负载均衡与转发,完全绕过iptables和conntrack。数据面使用eBPF map(哈希表)做查表,复杂度O(1),不随规则或服务数量线性增长。此外,Cilium基于eBPF提供透明的带宽管理、DNS可见性和Hubble可观测性。数据包的路径从“进协议栈逐层解析+遍历iptables链”缩短为“网卡收包→eBPF查表→目标网卡”,时延显著降低。

智能管家用“直达通道+秒级识别”换来了极致的投递效率,但也对楼宇“神经系统”的版本有要求——需要内核支持较新的eBPF特性。并不是所有城市(集群)都买得起这台机器人,这为后面的选型埋下伏笔。

TCilium=T收包+TeBPF查找≪T收包+T协议栈遍历+Tiptables链T_{\text{Cilium}} = T_{\text{收包}} + T_{\text{eBPF查找}} \ll T_{\text{收包}} + T_{\text{协议栈遍历}} + T_{\text{iptables链}}
两种方案在数据包进入网卡时都要付出收包开销,但Cilium后续只需一次哈希查表,而传统方案要逐层解析协议栈并遍历iptables规则。
  1. T收包(数据包进入开销)网卡触发中断、数据进内核的固定耗时,两种方案都有。
    T收包=网卡中断 + 内核拷贝T_{\text{收包}} = \text{网卡中断 + 内核拷贝}
  2. T eBPF查找(哈希查表)eBPF map按key查value,一次哈希运算,常数时间O(1)。
    TeBPF查找=O(1)T_{\text{eBPF查找}} = O(1)
  3. T协议栈遍历传统路径要经过IP层、TCP/UDP层、conntrack等多层处理。
    T协议栈遍历=O(L),L=协议栈层数T_{\text{协议栈遍历}} = O(L), \quad L=\text{协议栈层数}
  4. T iptables链kube-proxy的iptables规则逐条匹配,规则越多耗时越长,可达到线性增长。
    Tiptables链=O(R),R=规则条数T_{\text{iptables链}} = O(R), \quad R=\text{规则条数}

网络策略对比

光有投递还不够,城市安全部门要求:某些住户之间的通信必须受控。Calico和Cilium各自拿出了不同的“门禁系统”——一个用纸质花名册逐行核对,另一个用智能闸机刷脸秒过。

K8s NetworkPolicy定义了一组“谁可以访问谁”的规则,CNI插件负责执行。Calico的策略引擎在节点和Pod的veth上安装iptables规则,每条规则描述来源/目的选择器、协议和端口,数据包逐条匹配;Cilium则把每个Pod分配一个32位安全身份ID(Endpoint Identity),策略被编译进BPF map,数据包携带身份ID,一次map查询即得结论。

Calico的网络策略支持K8s原生NetworkPolicy,还提供了更精细的GlobalNetworkPolicy(集群级)和GlobalNetworkSet。iptables匹配顺序是线性的:R条规则最坏情况匹配R次。Cilium的策略不仅覆盖L3/L4,还能解析HTTP/gRPC等L7协议做细粒度控制;BPF map哈希查找不随规则数增长——当然,map容量有上限,超限也会丢包。生产环境中,两种策略引擎都要注意规则数量与误拦截排查:被拒绝的包在Calico里查DROP规则,在Cilium里查policy verdict监控。

门禁系统的选择同样取决于城市规模:小社区一个保安拿花名册就够,超大城市必须上智能闸机。策略性能的差异,直接影响最终选型。

TCalico=O(R),TCilium=O(1)T_{\text{Calico}} = O(R), \qquad T_{\text{Cilium}} = O(1)
O(R)表示规则量线性增长,O(1)表示哈希查表恒定时间。规则数几百条时差异微小,几千条以上Cilium优势显著。
  1. T Calico = O(R)规则量线性增长,每多一条规则,最坏匹配次数多一次——纸质花名册越厚,找名字越慢。
    TCalico=c1×RT_{\text{Calico}} = c_1 \times R
  2. T Cilium = O(1)身份ID作为哈希key直接查map,常数时间——刷脸闸机不管名单多长都是秒过。
    TCilium=c2T_{\text{Cilium}} = c_2

性能与选型

城市最终要在两套投递系统中做决定,是延续便宜可靠的邮政,还是采购成本更高的智能管家?答案永远取决于城市规模、信件流量、预算和物业团队水平。

K8s网络选型没有绝对优劣,只有是否匹配。核心考量维度有四个:数据面性能(PPS、延迟)、功能特性(策略、加密、可观测性)、运维复杂度(部署、排障、团队技能)和生态适配(是否与物理网络集成、是否支持云平台)。

Calico的优势:BGP纯路由模式是与传统数据中心网络(如TOR交换机)集成的天然选择,适合千节点以上、基础设施团队熟悉网络协议的场景;IPIP/VXLAN封装在非直连网络也能跑。Cilium的优势:eBPF带来高PPS、低延迟,对高并发微服务(如网关、实时推荐)增益明显;Hubble提供内核级可观测性;透明加密(WireGuard)开箱即用。双方也在互相融合:Calico推出了eBPF数据面,Cilium也能用BGP做路由广播(BGPControlPlane)。据社区数据,在大量策略规则和高PPS场景,Cilium吞吐量可达iptables方案的数倍;在纯BGP转发场景,两者差距缩小。

没有哪套系统是放之四海皆准的银弹:邮政在城市间穿梭尚可,但面对海量即时信件的CBD也得引入智能管家。选型的关键是把自身集群的规模、流量模式、团队能力放到这张打分表上。

S=w1P+w2F+w3O,(w1+w2+w3=1)S = w_1 P + w_2 F + w_3 O, \quad (w_1 + w_2 + w_3 = 1)
S是综合选型评分。把性能、功能、运维三个维度的得分按权重加权求和,权重由团队自己的痛点决定。
  1. P(性能分)由PPS、延迟、封装开销等量化得出,Cilium在高规则高并发下占优。
    P=性能基准测试得分P = \text{性能基准测试得分}
  2. F(功能分)网络策略、加密、可观测性等需求的满足度,两者各自加分项不同。
    F=功能需求覆盖率F = \text{功能需求覆盖率}
  3. O(运维分)部署难度、排障工具成熟度、团队熟悉度,Calico上手更简单。
    O=运维成本折算得分O = \text{运维成本折算得分}
  4. w(权重)权重由团队痛点决定,是“打分表”的重量级系数。
    w1+w2+w3=1w_1 + w_2 + w_3 = 1

部署与排障

再好的物业也要巡检和应急维修。网络系统上线后,日常监控和故障响应才是住户安心指数的保障:总闸跳了要能快速定位是线路问题还是电表问题。

部署阶段,Calico通常用calicoctl或Operator在Kubernetes上安装;Cilium用cilium-cli或Helm一键部署。排障阶段,Calico提供calicoctl node status检查BGP peer状态、calicoctl get wep查看工作负载端点;Cilium提供cilium status、cilium connectivity test一键自检。

四类高频故障:一是MTU不一致,节点间路径最大帧小于容器MTU导致大包黑洞,排查用ping -M do探测;二是BGP peer断连,导致跨节点路由丢失,检查node-to-node mesh或RR配置;三是CNI配置错误,二进制/配置目录版本不匹配,Pod一直Pending或ContainerCreating;四是网络策略误拦截,表现为“部分服务突然不通”,用cilium policy trace或看calico felix日志。监控方面:Prometheus抓取Calico的felix指标、Cilium的agent指标,Hubble可观测Pod级流量,配合Alertmanager配置告警,比如BGP会话down、Packet drop率突增。

物业的底气来自两方面:楼宇本身过硬(MTTF),维修队响应迅速(MTTR)。把监控告警配置好、把排障工具练熟,无论Calico还是Cilium,都能让城市网络平稳运行。

A=MTTFMTTF+MTTRA = \frac{\text{MTTF}}{\text{MTTF} + \text{MTTR}}
MTTF是平均无故障时间,MTTR是平均恢复时间。可用性A越接近1,系统越可靠。
  1. MTTF(平均无故障时间)系统平均能稳定运行多久,由硬件质量、配置规范、架构冗余度决定。
    MTTF=累计运行时间故障次数\text{MTTF} = \frac{\text{累计运行时间}}{\text{故障次数}}
  2. MTTR(平均恢复时间)故障从发生到恢复的平均耗时,由监控告警速度、排障工具链、团队熟悉度决定。
    MTTR=累计修复时间故障次数\text{MTTR} = \frac{\text{累计修复时间}}{\text{故障次数}}
  3. A(可用性)MTTF越长、MTTR越短,可用性越趋近于1——住户的安心指数。
    A=MTTFMTTF+MTTRA = \frac{\text{MTTF}}{\text{MTTF} + \text{MTTR}}

AI 应用场景

AI驱动的K8s网络异常检测与根因分析

阶段:监控与可观测性(部署运维阶段)

解决的问题:传统网络排障依赖人工抓包和日志分析,故障定位慢、经验依赖强。AI结合Cilium Hubble/eBPF采集的流量指标、Calico felix指标,学习正常流量基线,实时检测异常模式(突发丢包、延迟抖动、BGP会话状态异常)并自动给出根因候选。

具体案例:某电商平台大促期间,AI系统基于Hubble的TCP重传率和Pod间延迟指标,提前12分钟预警某节点带宽耗尽,自动关联出“某Pod日志压缩任务造成带宽峰值”的根因,运维提前处理避免了流量超时。

网络策略自动生成与瘦身

阶段:策略管理(安全设计阶段)

解决的问题:微服务架构下,人工编写和维护Cilium/Calico网络策略容易出现规则膨胀、误拦截和权限过宽。AI分析服务调用矩阵(通过Hubble抓取流),自动生成最小权限策略,并识别冗余/失效规则。

具体案例:某金融企业300+微服务,AI扫描一周调用链,自动生成的策略比人工维护的规则减少62%,并识别出3条长期无效的放行规则,消除了攻击面。

Python 演示

python71 行
"""模拟K8s网络数据面: 对比Calico与Cilium的转发路径开销""" import randomfrom dataclasses import dataclass, fieldfrom typing import Dict, List, Tuple  @dataclassclass Pod:    ip: str    node_id: str    name: str  @dataclassclass Node:    node_id: str    pod_cidr: str    pods: List[Pod] = field(default_factory=list)  def build_cluster(nodes: int = 5, pods_per_node: int = 10) -> Dict[str, Node]:    """构建模拟K8s集群: 每个节点分配一个/24的PodCIDR"""    cluster = {}    for i in range(nodes):        cidr = f"10.244.{i}.0/24"        node = Node(node_id=f"node-{i}", pod_cidr=cidr)        for j in range(pods_per_node):            pod_ip = f"10.244.{i}.{j + 2}"            node.pods.append(Pod(ip=pod_ip, node_id=node.node_id, name=f"pod-{i}-{j}"))        cluster[node.node_id] = node    return cluster  def calico_forward(src: Pod, dst: Pod, use_ipip: bool) -> Tuple[int, int]:    """Calico数据面: BGP路由查表 + 可选IPIP封装"""    hops = 1                      # 查BGP路由表命中    encap_bytes = 0    if src.node_id != dst.node_id:        hops += 1                 # 下一跳转发到目标节点        if use_ipip:            encap_bytes = 20      # 新增外层IP头    return hops, encap_bytes  def cilium_forward(src: Pod, dst: Pod) -> int:    """Cilium数据面: eBPF map哈希查找, O(1)直通转发"""    return 1  def simulate(trials: int = 1000, use_ipip: bool = True) -> None:    """运行模拟并输出对比结果"""    cluster = build_cluster()    all_pods = [p for n in cluster.values() for p in n.pods]    total_calico_hops = total_cilium_hops = total_encap = 0    for _ in range(trials):        src, dst = random.sample(all_pods, 2)        calico_hops, encap = calico_forward(src, dst, use_ipip)        total_calico_hops += calico_hops        total_encap += encap        total_cilium_hops += cilium_forward(src, dst)    avg_calico = total_calico_hops / trials    avg_cilium = total_cilium_hops / trials    print(f"样本数: {trials} 对随机Pod")    print(f"Calico 平均转发跳数: {avg_calico:.2f}, IPIP封装总字节: {total_encap}")    print(f"Cilium 平均转发跳数: {avg_cilium:.2f}")    print(f"Cilium 路径比 Calico 平均少 {avg_calico - avg_cilium:.2f} 跳")  if __name__ == "__main__":    simulate()
目的:用简单的转发模拟器,量化Calico(BGP+IPIP封装)与Cilium(eBPF直通)在数据面上路径步骤的差异。
  1. cidr = f"10.244.{i}.0/24"为每个节点分配一个/24网段,对应K8s中kube-controller-manager的PodCIDR分配
  2. def calico_forward(src: Pod, dst: Pod, use_ipip: bool)模拟Calico数据面:跨节点先查BGP路由,再经下一跳转发
  3. hops = 1BGP路由表一次命中,像邮局地图一查即得
  4. encap_bytes = 20跨节点时IPIP封装多出20字节外层IP头
  5. def cilium_forward(src: Pod, dst: Pod) -> int模拟Cilium的eBPF直通,恒为一跳
  6. src, dst = random.sample(all_pods, 2)从集群中随机抽取一对Pod模拟通信
  7. print(f"Cilium 路径比 Calico 平均少 {avg_calico - avg_cilium:.2f} 跳")输出路径差异,直观体现两种数据面的效率差距

常见误区

误区很多初学者以为K8s装完网络就固定了,想从Flannel换Calico就得重新搭集群,因为“网络是K8s自带的功能”。

正解CNI是标准接口,K8s本身只提供极简的kubenet。Flannel、Calico、Cilium都是通过DaemonSet以Pod方式部署的插件,只要配置/etc/cni/net.d/指向新插件,先排空旧插件再部署新插件,即可在线切换网络方案。就像快递协会换了合作快递公司,住户的门牌号规则不变,只是投递员换了。

为何常见:新手安装集群时通常一条命令就装好了Calico,界面上看不到"CNI"字眼,很容易把网络方案当成K8s内置组件。

误区觉得Cilium的eBPF在所有场景都碾压Calico的BGP,选型直接跟风社区热点选Cilium。

正解Calico已推出eBPF数据面,Cilium也能用BGP做路由广播(BGPControlPlane),两者技术边界在融合。纯BGP转发场景下两者差距不大;Cilium的优势主要体现在大量规则、高PPS、L7策略场景。Calico的成熟路由集成和极低运维门槛在千节点BGP数据中心仍是硬优势。选型要看场景而不是单点性能。

为何常见:技术社区喜欢制造“新旧阵营”对立,基准测试又只挑有利于自己的场景,导致印象标签化。

误区安全团队倾向于给每个服务都加最细的规则,认为“白名单越严越安全”,忽略规则膨胀对数据面的拖累。

正解Calico的iptables策略是线性匹配,几千条规则会明显增加转发延迟;Cilium的BPF map虽是O(1),但map容量有上限,超限会直接丢包。策略应遵循最小化原则,定期用Hubble等工具分析真实流量、清理冗余规则。安全是设计出来的,不是规则堆砌出来的。

为何常见:安全审核只看“有没有规则”,不看性能和可维护性,规则越加越多缺乏治理。

误区新手配置容器MTU时很随意,觉得节点间MTU不同也能通信,反正IP协议会分片。

正解IP分片不仅性能差,在隧道场景(IPIP/VXLAN)还会造成黑洞:封装后的包超过下游MTU时,很多设备直接丢弃分片包。VXLAN场景容器MTU应设为1450,IPIP设为1480,且要保证整条路径MTU一致。这也是集群间Pod通信“偶发大包卡死”最常见的原因。

为何常见:单机本地回环MTU都是65536,小流量实验不容易触发分片,跨节点传输大包时才暴露。

误区Pod间直连没问题,但ClusterIP访问超时,第一反应是“Calico/Cilium是不是挂了”。

正解Pod网络(CNI负责)和Service网络(kube-proxy负责)是两层。ClusterIP流量走kube-proxy的iptables/ipvs或Cilium的SocketLB,排查顺序应该是:Endpoints是否正常 → kube-proxy规则是否存在 → 对应CNI数据面转发是否正常。很多“网络故障”其实是Service层问题。

为何常见:Pod IP和ClusterIP都在同一张“网络”里,初学者分不清两者的实现归属,一股脑归因于CNI。

面试题

Q1. CNI(容器网络接口)在K8s中的定位是什么?

单选题 · easy

  • A.一个内置的Pod网络插件
  • B.一款实现负载均衡的组件
  • C.标准化的网络插件接入接口← 正确答案
  • D.一种容器运行时实现方案

答案:C。CNI是标准接口而非具体实现,K8s通过它接入Calico/Cilium等插件。A错在“内置”,B错在负载均衡是kube-proxy职责,D错在容器运行时是containerd/CRI-O。

Q2. Calico与Cilium各自的核心数据面技术分别是什么?

单选题 · easy

  • A.Conntrack与iptables机制
  • B.BGP路由和eBPF技术← 正确答案
  • C.VXLAN与Overlay网络
  • D.IPVS与SocketLB技术

答案:B。Calico标志性技术是BGP路由分发(IPIP/VXLAN只是封装手段),Cilium标志性技术是eBPF内核编程。A和D是kube-proxy的负载均衡技术,C是通用Overlay方案描述。

Q3. 物理网卡MTU为1500时,VXLAN封装后容器有效MTU约为多少?

单选题 · mid

  • A.1500
  • B.1480
  • C.1450← 正确答案
  • D.1400

答案:C。VXLAN封装头约50字节(外层IP 20 + UDP 8 + VXLAN 8 + 其他),1500减去50得1450。如果选B,那是IPIP封装的MTU(减20字节)。

Q4. Calico在IPIP模式下,跨节点数据包新增了什么开销?

单选题 · mid

  • A.8字节UDP头部
  • B.20字节IP头部← 正确答案
  • C.50字节VXLAN头
  • D.54字节以太头

答案:B。IPIP是IP-in-IP封装,新增一层20字节的外层IP头。VXLAN才是50字节,UDP头是VXLAN的一部分而非IPIP的一部分。

Q5. 以下哪些属于eBPF为Cilium带来的能力?

多选题 · mid

  • A.数据包在socket层直接转发← 正确答案
  • B.通过哈希表实现策略O1匹配← 正确答案
  • C.使用BGP广播全集群路由
  • D.绕过iptables减少规则遍历← 正确答案

答案:ABD。A是SocketLB的核心特性,B是BPF map查表,D是绕过iptables链,三者都是eBPF带来的能力。C是Calico的BGP特性,不是eBPF特有。

Q6. BGP全互联模式下,100个节点的BGP会话总数是多少?

单选题 · mid

  • A.100
  • B.4950← 正确答案
  • C.5050
  • D.9900

答案:B。全互联会话数公式为C=N(N-1)/2,代入100得4950。5050是100×101/2的错误计算,9900是N×(N-1)没除以2。

Q7. 集群所有Pod间通信突然普遍变慢且偶发丢包,应优先排查什么?

单选题 · hard

  • A.Pod镜像是否过大
  • B.节点的MTU配置一致性← 正确答案
  • C.Deployment副本数设置
  • D.Service的type设置

答案:B。全集群范围的“普遍变慢+偶发丢包”最典型原因是跨节点路径MTU不一致,大包被丢弃导致重传。镜像大小、副本数和Service类型只影响局部,不产生全集群普遍性丢包。

Q8. 关于Calico与Cilium的选型判断,正确的是?

多选题 · hard

  • A.千节点BGP大集群可选Calico← 正确答案
  • B.高PPS微服务场景Cilium占优← 正确答案
  • C.Calico无法对接物理网络BGP
  • D.Cilium不支持网络策略功能

答案:AB。A正确,Calico的BGP纯路由天然适配大规模数据中心;B正确,eBPF绕过协议栈带来高吞吐。C错误,Calico的核心强项恰恰是与物理网络BGP集成;D错误,Cilium支持L3-L7级网络策略。

Q9. 创建Pod时,kubelet最终通过哪条链路调用CNI插件配置网络?

单选题 · easy

  • A.kube-proxy经iptables转给Flannel
  • B.kubelet经CRI调containerd再调CNI← 正确答案
  • C.etcd经kube-scheduler触发CNI插件
  • D.kubelet直接执行CNI做网络配置

答案:B。正确调用链是kubelet → CRI(containerd) → CNI插件。containerd负责加载CNI配置并调用插件二进制。kube-proxy只负责Service转发,etcd和kube-scheduler不参与CNI调用。

Q10. 排除K8s网络故障时,以下哪些手段是有效的?

多选题 · mid

  • A.用tcpdump抓通信两端报文← 正确答案
  • B.检查Cilium或Calico的Pod日志← 正确答案
  • C.重启整个集群的所有节点
  • D.查看监控指标判丢包与延迟← 正确答案

答案:ABD。tcpdump抓包定位丢包点、检查CNI插件日志定位配置错误、查看监控指标判断是否系统性故障,都是标准排障手段。重启整个集群是破坏性操作,不是排查手段,也无助于定位根因。