作者 | 陈赟豪(环河)

背景容器网络为何出现

在一个汽车发动机的生产车间中,汽车发动机的各个组件会存在一定的顺序进行组装,这就要求有直接关系的组件必须知道下一个组件的具体位置。当一个汽车发动机组装完成后,距离最后成品汽车,还差了很多部件,比如底盘,车身等。此时,需要将发动机发往一个装配中心进行组合安装,这样我们就必须知道装配中心的地理位置。

这些位置在容器中可以理解为 IP 地址,容器网络便是如此。在上面这个例子里,即描述了容器网络本节点内部互通场景,又描述了跨节点的通信场景。

随着云计算的发展,应用间通信从物理机网络,虚拟机网络,发展到目前的容器网络。由于容器不同于物理机、虚拟机,容器可以被理解为一个标准的,轻量级的,便携的,独立的集装箱,集装箱之间相互隔离,都使用自己的环境和资源。但随着越来越复杂环境变化,容器在运行中会需要容器间或者容器与集群外部之间的信息传输,这时候容器就要在网络层面拥有一个名字(即 IP 地址),由此容器网络就应运而生。

再从技术的角度来谈容器网络的由来,首先要从容器本质说起,它是由以下几点来实现的:

由于主机与容器、容器与容器间的网络栈并不相通,也没有统一的控制面,导致容器间无法直接的感知。为了解决这个问题,本文中我们要讨论的容器网络出现了,再配合不同的网络虚拟化技术带来了多样化的容器网络方案。

容器网络的基本要求网络插件介绍网络插件概述

容器和该容器所在的宿主机是分隔的两地,如果需要连通就得建立一座桥梁,但由于容器侧还没有名字,就无法建立桥梁,这时候就先需要给容器侧命名,这样才能成功建立起桥梁。网络插件就是起到给容器侧命名和建立桥梁的功能。

即网络插件将网络接口插入容器网络命名空间(例如,veth 对的一端),并在主机上进行任何必要的改变(例如将 veth 的另一端连接到网桥)。然后通过调用适当的 IPAM 插件(ip 地址管理插件)分配给接口一个空闲的 IP 地址,并设置与此 IP 地址相对应的路由规则。

对于 K8s 来讲,网络属于最重要的功能之一,因为没有一个良好的网络,集群不同节点之间甚至同一个节点之间的 pod 就无法良好的运行起来。

但是 K8s 在设计网络的时候,采用的准则就一点:“灵活”!那怎么才能灵活呢?那就是 K8s 自身没有实现太多跟网络相关的操作,而是制定了一个规范:

  1. 有配置文件,能够提供要使用的网络插件名,以及该插件所需信息
  2. 让 CRI 调用这个插件,并把容器的运行时信息,包括容器的命名空间,容器 ID 等信息传给插件
  3. 不关心网络插件内部实现,只需要最后能够输出网络插件提供的 pod IP 即可

没错一共就这三点,如此简单灵活的规范就是大名鼎鼎的 CNI 规范。

不过恰恰因为 K8s 自己“啥也不干”,所以大家可以自由发挥,自由实现不同的 CNI 插件,即网络插件。除了社区大名鼎鼎的 Calico、Bifrost 网络插件,阿里也开发了一款功能和性能极优的网络插件 Hybridnet。

Hybridnet 是专为混合云设计的开源容器网络解决方案,与 Kubernetes 集成,并被以下 PaaS 平台使用:

Hybridnet 专注于高效的大规模集群、异构基础设施和用户友好性。

Calico 是一种广泛采用、久经考验的开源网络和网络安全解决方案,适用于 Kubernetes、虚拟机和裸机工作负载。Calico 为 Cloud Native 应用程序提供两大服务:

Bifrost 是一个可为 Kubernetes 启用 L2 网络的开源解决方案,支持以下特性

通信路径介绍

Overlay 方案:意味着将不同主机上的容器用同一个虚拟网络连接起来的跨主机网络

Underlay 方案:由交换机和路由器等设备组成,借助以太网协议、路由协议和 VLAN 协议等驱动的网络。

网络插件的原理网络插件分类及对比

overlay 方案

underlay 方案

主流方案

路由或 SDN 方案:Calico IPIP/Calico VXLAN

Calico BGP/MACVLAN/IPVLAN

优点

  1. 对物理网络无侵入
  2. 维护和管理简单
  1. 高性能
  2. 网络流量可管理、可监控

缺点

  1. 容器网络难以监控
  2. 容器访问集群外部通过 Node SNAT,无法精确管理流量
  1. 对现有组网有侵入
  2. 维护和管理工作量大
  3. 占用现网 IP 地址,前期需要详细规划

hybridnet

calico ipip

calico bgp

bifrost

支持场景

overlay/underlay

overlay

underlay

underlay

网络栈

IPv4/IPv6

IPv4

IPv4/IPv6

IPv4

通信技术

vxlan/vlan/bgp

ipip

bgp

macvlan

通信机制

隧道通信/二层 三层通信/三层通信

隧道通信

三层通信

二层通信

容器通信

veth pair

veth pair

veth pair

macvlan子接口

是否支持固定IP/固定IP池

IPPool模式

block detail

block(如1.1.1.0/24)

block(如1.1.1.0/24)

detail(如1.1.1.1~1.1.1.9)

南北向流量出口

SNAT/podIP

SNAT

SNAT/podIP

podIP

是否支持网络策略

商用版支持

网络插件应用场景

针对数据中心复杂的网络情况,我们要按需求出发去选择相对应的容器网络方案

本文我们将对 hybridnet vxlan、hybridnet vlan、hybridnet bgp、calico IPIP、calico BGP 和基于 macvlan 改造的 bifrost 进行 pod 数据链路上的详细分析

网络插件架构及通信路径Hybridnet

网络容器教程(一文彻悟容器网络通信)(1)

1、VXLAN 模式

网络容器教程(一文彻悟容器网络通信)(2)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod2 的路由规则
  3. 流量从 hybrYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从pod2的eth0->主机侧的hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到39999路由表,并在39999路由表中匹配到 Pod1 的路由规则
  3. 流量从 hybrXXX 网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(3)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 40000 路由表,并在 40000 路由表中匹配到 Pod2 所在网段需要发往 eth0.vxlan20 网卡的路由规则
  3. eth0.vxlan20 设备的转发表中记录了对端 vtep 的 mac 地址和 remoteip 的对应关系
  4. 流量经过 eth0.vxlan20 网卡,封装一个 UDP 的头部
  5. 经过查询路由,与本机处于同网段,通过 mac 地址查询获取到对端物理网卡的 mac 地址,经由 Node1 eth0 物理网卡发送
  6. 流量从 Node2 eth0 物理网卡进入,并经过 eth0.vxlan20 网卡解封一个 UDP 的头部
  7. 根据 39999 路由表,流量从hybrYYY网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 40000 路由表,并在 40000 路由表中匹配到 Pod1 所在网段需要发往 eth0.vxlan20 网卡的路由规则
  3. eth0.vxlan20 设备的转发表中记录了对端 vtep 的 mac 地址和 remoteip 的对应关系
  4. 流量经过 eth0.vxlan20 网卡,封装一个 UDP 的头部
  5. 经过查询路由,与本机处于同网段,通过 mac 地址查询获取到对端物理网卡的 mac 地址,经由 Node2 eth0 物理网卡发送
  6. 流量从 Node1 eth0 物理网卡进入,并经过 eth0.vxlan20 网卡解封一个 UDP 的头部
  7. 根据 39999 路由表,流量从 hybrXXX 网卡进入 Pod1 容器网络栈,完成回包动作
2、VLAN 模式

网络容器教程(一文彻悟容器网络通信)(4)

Pod1 访问 Pod2 的通信过程发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod2 的路由规则
  3. 流量从 hybrYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod1 的路由规则
  3. 流量从 hybrXXX 网卡进入 Pod1 容器网络栈,完成回包动作

跨节点通信

网络容器教程(一文彻悟容器网络通信)(5)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 10001 路由表,并在 10001 路由表中匹配到 Pod2 相对应的路由规则
  3. 根据路由规则,流量从 eth0.20 网卡所对应的 eth0 物理网卡发出,并发往交换机
  4. 在交换机上匹配到 pod2 的 MAC 地址,所以将流量发往 Node2 所对应的 eth0 物理网卡
  5. 流量被 eth0.20 vlan 网卡接收到,并根据 39999 路由表匹配到的路由,将流量从 hybrYYY 网卡打入 pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 10001 路由表,并在 10001 路由表中匹配到 Pod1 相对应的路由规则
  3. 根据路由规则,流量从 eth0.20 网卡所对应的 eth0 物理网卡发出,并发往交换机
  4. 在交换机上匹配到 pod1 的 MAC 地址,所以将流量发往 Node1 所对应的 eth0 物理网卡
  5. 流量被 eth0.20 vlan 网卡接收到,并根据 39999 路由表匹配到的路由,将流量从 hybrXXX 网卡打入 pod1 容器网络栈,完成回包动作
3、BGP 模式

网络容器教程(一文彻悟容器网络通信)(6)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod2 的路由规则
  3. 流量从 hybrYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod1 的路由规则
  3. 流量从 hybrXXX 网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(7)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 10001 路由表,并在 10001 路由表中匹配到默认路由
  3. 根据路由,将流量发往 10.0.0.1 所对应的交换机
  4. 在交换机上匹配到 pod2 所对应的特定路由,将流量发往 Node2 eth0 物理网卡
  5. 流量从 hybrYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 hybrYYY,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 10001 路由表,并在 10001 路由表中匹配到默认路由
  3. 根据路由,将流量发往 10.0.0.1 所对应的交换机
  4. 在交换机上匹配到 pod1 所对应的特定路由,将流量发往 Node1 eth0 物理网卡
  5. 流量从 hybrXXX 网卡进入 Pod1 容器网络栈,完成回包动作
Calico

基本概念:

网络容器教程(一文彻悟容器网络通信)(8)

1、IPIP 模式

网络容器教程(一文彻悟容器网络通信)(9)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 caliXXX,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod2 的路由规则
  3. 流量从 caliYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 caliYYY,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod1 的路由规则
  3. 流量从 caliXXX 网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(10)

Pod1 访问 Pod2 的通信过程发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 caliXXX,进入主机网络栈中
    1. src: pod1IP
    2. dst: pod2IP
  1. 根据目的 IP,流量在路由表中匹配到将流量转发到 tunl0 网卡上的路由规则
    1. src: pod1IP
    2. dst: pod2IP
  1. 流量从 tunl0 进行 IPIP 封装(即封装一个 IP 头部),通过 eth0 物理网卡发出
    1. src: Node1IP
    2. dst: Node2IP
  1. 流量从 Node2 的 eth0 网卡进入 Node2 的主机网络栈
    1. src: Node1IP
    2. dst: Node2IP
  1. 流量进入 tunl0 进行 IPIP 解包
    1. src: pod1IP
    2. dst: pod2IP
  1. 流量从 caliYYY 网卡进入 Pod2 容器网络栈,完成发包动作
    1. src: pod1IP
    2. dst: pod2IP

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 caliYYY,进入主机网络栈中
    1. src: pod2IP
    2. dst: pod1IP
  1. 根据目的 IP,流量在路由表中匹配到将流量转发到 tunl0 网卡上的路由规则
    1. src: pod2IP
    2. dst: pod1IP
  1. 流量从 tunl0 进行 IPIP 封装(即封装一个 IP 头部),通过 eth0 物理网卡发出
    1. src: Node2IP
    2. dst: Node1IP
  1. 流量从 Node1 的 eth0 网卡进入 Node1 的主机网络栈
    1. src: Node2IP
    2. dst: Node1IP
  1. 流量进入 tunl0 进行 IPIP 解包
    1. src: pod2IP
    2. dst: pod1IP
  1. 流量从 caliXXX 网卡进入 Pod1 容器网络栈,完成回包动作
    1. src: pod2IP
    2. dst: pod1IP
2、BGP 模式

网络容器教程(一文彻悟容器网络通信)(11)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 caliXXX,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod2 的路由规则
  3. 流量从 caliYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 caliYYY,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod1 的路由规则
  3. 流量从 caliXXX 网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(12)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 caliXXX,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod2 相对应网段的路由规则,并从 Node1 eth0 物理网卡发出
  3. 流量从 Node2 eth0 物理网卡进入,并从 caliYYY 网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 veth-pair 网卡,即从 pod2 的 eth0->主机侧的 caliYYY,进入主机网络栈中
  2. 根据目的 IP,流量在路由表中匹配到 Pod1 相对应网段的路由规则,并从 Node2 eth0 物理网卡发出
  3. 流量从 Node1 eth0 物理网卡进入,并从 caliXXX 网卡进入 Pod1 容器网络栈,完成回包动作
Bifrost

网络容器教程(一文彻悟容器网络通信)(13)

1、MACVLAN 模式

网络容器教程(一文彻悟容器网络通信)(14)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 macvlan 网卡,即 pod1 的 eth0 走二层网络进入 eth0-10 vlan 子网卡
  2. 由于 macvlan 开启 bridge 模式,能够匹配到 pod2 的 MAC 地址
  3. 流量从 eth0-10 vlan 子网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 macvlan 网卡,即 pod2 的 eth0 走二层网络进入 eth0-10 vlan 子网卡
  2. 由于 macvlan 开启 bridge 模式,能够匹配到 pod1 的 MAC 地址
  3. 流量从 eth0-10 vlan 子网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(15)

Pod1 访问 Pod2 的通信过程发包过程:

  1. Pod1 流量通过 macvlan 网卡,即 pod1 的 eth0 走默认路由(网关为 5.0.0.1)进入 eth0-5 vlan 子网卡
  2. 由于在 eth0-5 上找到网关 5.0.0.1 的 MAC 地址,所以将流量从 eth0 物理网卡出打到交换机上
  3. 流量在交换机上匹配到了 pod2 的 MAC 地址
  4. 流量进入 Pod2 所在宿主机的物理网卡,并进入相对应的 eth0-10 vlan 子网卡
  5. 流量从 eth0-10 vlan 子网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 macvlan 网卡,即 pod2 的 eth0 走默认路由(网关为 10.0.0.1)进入 eth0-10 vlan 子网卡
  2. 由于在 eth0-10 上找到网关 10.0.0.1 的 MAC 地址,所以将流量从 eth0 物理网卡出打到交换机上
  3. 流量在交换机上匹配到了 pod1 的 MAC 地址
  4. 流量进入 Pod1 所在宿主机的物理网卡,并进入相对应的 eth0-5 vlan 子网卡
  5. 流量从 eth0-5 vlan 子网卡进入 Pod1 容器网络栈,完成回包动作

网络容器教程(一文彻悟容器网络通信)(16)

Pod1 访问 Pod2 的通信过程

发包过程:

  1. Pod1 流量通过 macvlan 网卡,即 pod1 的 eth0 走默认路由(网关为 5.0.0.1)进入 eth0-5 vlan 子网卡
  2. 由于在 eth0-5 上找到网关 5.0.0.1 的 MAC 地址,所以将流量从 eth0 物理网卡出打到交换机上
  3. 流量在交换机上匹配到了 pod2 的 MAC 地址
  4. 流量进入 Pod2 所在宿主机的物理网卡,并进入相对应的 eth0-10 vlan 子网卡
  5. 流量从 eth0-10 vlan 子网卡进入 Pod2 容器网络栈,完成发包动作

回包过程:

  1. Pod2 流量通过 macvlan 网卡,即 pod2 的 eth0 走默认路由(网关为 10.0.0.1)进入 eth0-10 vlan 子网卡
  2. 由于在 eth0-10 上找到网关 10.0.0.1 的 MAC 地址,所以将流量从 eth0 物理网卡出打到交换机上
  3. 流量在交换机上匹配到了 pod1 的 MAC 地址
  4. 流量进入 Pod1 所在宿主机的物理网卡,并进入相对应的 eth0-5 vlan 子网卡
  5. 流量从 eth0-5 vlan 子网卡进入 Pod1 容器网络栈,完成回包动作
面临的问题及未来发展IPv4/IPv6 双栈

IP 作为互联网最基础的要素,是为计算机网络相互连接进行通信而设计的协议,正是因为有了 IP 协议,因特网才得以迅速发展成为世界上最大的、开放的计算机通信网络。IP 协议随着互联网的发展,产生了 IPv4 和 IPv6 两种协议:

IPv4 占主流,IPv6 还未兴起时,主要面临的问题:

  1. IPv4 地址数量已经不再满足需求,需要 IPv6 地址进行扩展
  2. 随着国内下一代互联网发展政策的明确,客户数据中心需要使用 IPv6 来符合更严格的监管

hybridnet

calico IPIP

calico BGP

bifrost

是否支持IPv6/双栈

calico IPIP 不支持 IPv6 的原因:

多网卡(多通信机制)

通常情况下在 K8s 中,一个 Pod 只有一个接口,即单网卡,用于集群网络中 pod 和 pod 通信。而 Pod 需要和异构网络进行通信时,可选择在 Pod 中建立多个接口,即多网卡。目前的问题:

  1. 部分客户真实 IP 资源紧张,导致无法全部使用 underlay 方案
  2. 客户希望把 UDP 网络和 TCP 网络分开,导致如基于 TCP 协议的网络模型无法独立存在于 UDP 网络中

目前实现多网卡的方案,大致两种:

网络流量管控

通常在数据中心中,我们将其网络流量分为两种类型,一种是数据中心外部用户和内部服务器之间交互的流量,这样的流量称作南北向流量或者纵向流量;另外一种就是数据中心内部服务器之间交互的流量,也叫东西向流量或者横向流量。那么在容器云范畴内,我们将东西向流量定义为集群内宿主机和容器、容器间或宿主机间的流量,南北向流量为容器云外部与容器云内部之间交互的流量。目前的问题:

  1. 传统防火墙在容器云的东西向场景下,难以起到流量管控,需要提供服务间或容器间流量管控的能力

calico

cillum

bifrost-商用版

技术基础

iptables

ebpf

ebpf

适配性

三层路由且流量经过主机网络栈

二层且满足cillum通信方式

主流CNI插件

参考资料

1、calico vxlan ipv4 overlay组网跨主机通信分析

https://www.jianshu.com/p/5edd6982e3be

2、Qunar容器平台网络之道:Calico

http://dockone.io/article/2434328

3、最好的vxlan介绍

https://www.jianshu.com/p/cccfb481d548

4、揭秘 IPIP 隧道

https://morven.life/posts/networking-3-ipip/

5、BGP基础知识

https://blog.csdn.net/qq_38265137/article/details/80439561

6、VLAN基础知识

https://cshihong.github.io/2017/11/05/VLAN基础知识/

7、Overlay和Underlay网络协议区别及概述讲解

https://www.cnblogs.com/fengdejiyixx/p/15567609.html#二underlay网络模型

8、东西向流量牵引方案小结

http://blog.nsfocus.net/east-west-flow-sum/

9、容器网络接口(CNI)

https://jimmysong.io/kubernetes-handbook/concepts/cni.html

10、K8s 网络之深入理解 CNI

https://zhuanlan.zhihu.com/p/450140876

,