欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

一篇文章彻底揭示容器网络通信的奥秘

最编程 2024-02-24 06:59:32
...

作者 | 陈赟豪(环河)


背景


容器网络为何出现


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


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


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


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


  • cgroup:实现资源的可配额
  • overlay fs:实现文件系统的安全性和便携性
  • namespace:实现资源的隔离性
  • IPC :System V IPC 和 POSIX 消息队列
  • Network:网络设备、网络协议栈、网络端口等
  • PID:进程
  • Mount:挂载点
  • UTS:主机名和域名
  • USR:用户和用户组


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


容器网络的基本要求


  • IP-per-Pod,每个 Pod 都拥有一个独立 IP 地址,Pod 内所有容器共享一个网络命名空间
  • 集群内所有 Pod 都在一个直接连通的扁平网络中,可通过 IP 直接访问
  • 所有容器之间无需 NAT 就可以直接互相访问
  • 所有 Node 和所有容器之间无需 NAT 就可以直接互相访问
  • 容器自己看到的 IP 跟其他容器看到的一样
  • Service cluster IP 尽可在集群内部访问,外部请求需要通过 NodePort、LoadBalance 或者 Ingress 来访问

网络插件介绍


网络插件概述


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


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


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


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


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


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


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


  • Hybridnet

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

  • 阿里云 ACK 发行版
  • 阿里云 AECP
  • 蚂蚁金服 SOFAStack


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


  • Calico

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

  • 工作负载之间的网络连接
  • 工作负载之间的网络安全策略


  • Bifrost

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

  • Bifrost 中的网络流量可以通过传统设备进行管理和监控
  • 支持 macvlan 对于 service 流量的访问


通信路径介绍


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

  • VXLAN
  • VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),是由 IETF 定义的 NVO3(Network Virtualization over Layer 3)标准技术之一,采用 L2 over L4(MAC-in-UDP)的报文封装模式,将二层报文用三层协议进行封装,可实现二层网络在三层范围内进行扩展,同时满足数据中心大二层虚拟迁移和多租户的需求
  • IPIP
  • 基于 TUN 设备实现 IPIP 隧道,TUN 网络设备能将三层(IP 网络数据包)数据包封装在另外一个三层数据包之中,Linux 原生支持好几种不同的 IPIP 隧道类型,但都依赖于 TUN 网络设备
  • ipip: 普通的 IPIP 隧道,就是在报文的基础上再封装成一个 IPv4 报文
  • gre: 通用路由封装(Generic Routing Encapsulation),定义了在任意网络层协议上封装其他网络层协议的机制,所以对于 IPv4 和 IPv6 都适用
  • sit: sit 模式主要用于 IPv4 报文封装 IPv6 报文,即 IPv6 over IPv4
  • isatap: 站内自动隧道寻址协议(Intra-Site Automatic Tunnel Addressing Protocol),类似于 sit 也是用于 IPv6 的隧道封装
  • vti: 即虚拟隧道接口(Virtual Tunnel Interface),是一种 IPsec 隧道技术
  • 本文中我们使用的是 ipip 这种普通的 IPIP 隧道


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

  • BGP
  • 边界网关协议BGP(Border Gateway Protocol)是一种实现自治系统AS(Autonomous System)之间的路由可达,并选择最佳路由的距离矢量路由协议
  • Vlan
  • VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。VLAN内的主机间可以直接通信,而VLAN间不能直接通信,从而将广播报文限制在一个VLAN内


网络插件的原理


  • calico 利用 IPIP 等隧道技术或者宿主机间建立 BGP 连接完成容器路由的互相学习解决了跨节点通信的问题。
  • hybridnet 利用 vxlan 隧道技术、宿主机间建立 BGP 连接完成容器路由的互相学习或者 ARP 代理来解决跨节点通信的问题。
  • bifrost 通过内核 macvlan 模块利用交换机 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
是否支持网络策略 商用版支持


  • SNAT: 对数据包的源 IP 地址进行转化
  • podIP:由 podIP 直接通信
  • veth pair:在 Linux 下,可以创建一对 veth pair 的网卡,从一边发送包,另一边就能收到,对于容器流量来说会通过主机侧的 veth pair 网卡进入主机网络栈,即会过主机的 iptables 规则后再由物理网卡发出。
  • macvlan子接口:macvlan 子接口和原来的宿主机主接口是完全独立的,可以单独配置 MAC 地址和 IP 地址,对外通信时,容器流量不会进入主机网络栈,既不会过主机的iptables规则,只会经过二层由物理网卡发出。


网络插件应用场景


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

  • 希望对数据中心物理网络较少侵入性,可选择使用隧道方案
  • 需支持双栈,则可选 hybridnet vxlan 方案
  • 只支持单栈 IPv4,则可选 calico IPIP,calico vxlan 方案
  • 希望数据中心支持并使用 BGP
  • 宿主机处于同网段内,则可选 calico BGP 方案(支持双栈)
  • 宿主机处于不同网段内,则可选 hybridnet bgp 方案(支持双栈)
  • 对于业务的高性能和低延迟的追求,出现了 macvlan,ipvlan l2 等方案
  • 公有云场景下,可选用 terway 方案,或者其他 ipvlan l3 方案,或者隧道方案
  • 也有为了满足全场景而开发的方案,如 hybridnet、multus 等,Multus 一款为支持其他 CNI 能力的开源容器网络插件


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


网络插件架构及通信路径


Hybridnet


  • 整体架构

1.png

  • Hybridnet-daemon:控制每个节点上的数据平面配置,例如 Iptables 规则,策略路由等


  • 通信路径

1、VXLAN 模式

  • 同节点通信

2.png

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.png

image.gif 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 模式

  • 同节点通信

image.gif 4.png

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

  1. Pod1 流量通过 veth-pair 网卡,即从 pod1 的 eth0->主机侧的 hybrXXX,进入主机网络栈中
  2. 根据目的 IP,流量在主机的策略路由匹配到 39999 路由表,并在 39999 路由表中匹配到 Pod2 的路由规则
  3. 上一篇: UDS的使用

    下一篇: 在不中断Oracle 19c DG主库的情况下,实现主库RAC与备库独立部署教程