Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >多图汇总梳理VPC与三种K8s网络模型

多图汇总梳理VPC与三种K8s网络模型

作者头像
LanceZhang
发布于 2022-01-25 01:01:37
发布于 2022-01-25 01:01:37
5.5K0
举报
文章被收录于专栏:二哥聊云原生

大家好,我是二哥。今天这期是一篇关于VPC和三种K8s网络模型的汇总性文章。也是春节前最后一篇文章,发完二哥就准备进入过年模式了。提前祝大家虎年虎虎生威,万事如意。

本文所有的高清大图,我都放到github上去了:https://github.com/LanceHBZhang/LanceAndCloudnative。以后也是如此,就不再发预热预告了。图片版权归二哥所有,除个人学习外用于其它用途前请先通过公众号联系二哥授权。

我们在学习K8s的时候,总是会碰到一个痛点:K8s作为一个完整的商用解决方案,包含了很多零散的基础知识点。比如单网络模型方面就涉及到网络虚拟化、iptables、eBPF、SDN等等。单个知识点我们可能学过、见过甚至用过,但把K8s基本用法撸完一遍下来依旧觉得无法识得庐山真面目。我想一个可能的原因是我们过于关注在细节而忽略了它整体的样子。所以我总是尽量在一张图中画出与这个主题相关的全景全局图,比如K8s既然被尊称为云原生时代的“数据中心操作系统(DCOS)”,那从网络拓扑方面来说,它和数据中心是如何配合的呢?我将这三种K8s网络模型和VPC相遇时的样子分别画了出来。希望能给你一种鸟瞰的视角,而不是迷失在技术的细节丛林里。

Overlay模型下,网络包如同害羞的儿童,每次和别人说话都躲在妈妈背后,要妈妈帮他传话。host-gw模型下,网络包就像未成年的小伙子,既想走出去直面凶险的江湖,但又离不开妈妈的大力支持。而Underlay模型,网络包就是大人的模样了,有什么需求和想法,自己直接和对方谈。

但无论是哪种模式,都离不开一些基础概念。在二哥看来,理解好了这些基础,再去看K8s三种网络模式能起到事半功倍之效。所以本文二哥先花了一些篇幅把这个基础知识再梳理一遍。重要的话再强调一下:图1非常基础,也非常重要。图2-图5都与图1有关系。

来吧,进入正题。

1. 基础和基石

1.1 TCP/IP协议栈和网络栈

K8s“扁平网络”的三种典型实现方式是:Overlay、主机间路由(host-gw)以及Underlay。它们都会在容器内虚拟一张网卡,取决于实现方式的不同,这张虚拟网卡既可能是veth类型的,也可能直接对物理网卡的虚拟。

我们说Network namespace用来隔离包括网卡(Network Interface)、回环设备(Loopback Device)、网络栈、IP地址、端口等等在内的网络资源。它的特点是由可配置的数据组成。对于一个进程来说,这些要素,其实就构成了它发起和响应网络请求的基本环境。这里所谓“网络栈(Networking stack)”,包括了:路由表(Routing Table), network filter,iptables 规则等。

无论是一个 Linux 容器还是宿主机的进程所能看见的“网络栈”,实际上是被隔离在它们各自的 Network namespace 当中的,通信双方的网卡(如典型的veth pair)也自然被隔离到相应的namespace中。

另外还有一个栈也会被经常提起:TCP/IP协议栈。我们可以将TCP/IP协议栈看成是程序的代码部分,而网络栈看成是程序的数据部分。很显然TCP/IP栈应该是被这个OS上所有人共享的,无论是进程还是容器,甚至是基于qemu-kvm的虚拟机都共享着宿主机的协议栈,但网络栈却是各个network namespace独享的。

网络包无论是从容器内的网卡流出,还是离开容器后再与其它网络设备打交道,必然都会经过宿主机内核TCP/IP协议栈。容器内的网卡属于容器所在的network namespace,而网络包离开容器后的下一跳(个)网络设备同样也属于它自己的network namespace。

1.2 虚拟网卡数据接收流程

二哥在文章《看图写话:聊聊veth数据流》和《高清大图描绘辛苦的ksoftirqd》中结合图1,描述了网路包从veth一端流出到流入另一端过程中所涉及到的数据流以及在这个过程中内核线程ksoftirqd起到的至关重要的作用。这张图也适用普通虚拟网卡。

图1有一些关键的地方,我把它们列在这里,希望你看完后可以不自觉地拍下大腿,轻呼一声:哦,原来如此。

  • 为了便于对比,它包含了两种类型的网络设备:一个物理网卡和veth虚拟网卡。数据流分为两条线路:线路1和线路2。 线路1从物理网卡的数据接收开始,涉及到中断处理流程和DMA。这一步的处理结果是网络包被放进了与每个网卡相关的queue(RingBuffer)里面。 线路2从容器内的进程在veth一端发送数据开始,它相对简单很多,主要是单纯的软件调用,没有硬件的介入。这一步的处理结果是skb被放入到了input_pkt_queue里。
  • 无论是线路1还是线路2,它们都需要唤起ksoftirqd以便来处理skb,并提前将相应的网卡挂到per CPU的poll_list上。我们可以将poll_list想象成晾晒香肠的架子,而每个网络设备则如同香肠一样挂到架子上面等待ksoftirqd处理。
  • ksoftirqd扛起了网络包处理的重担。它从pull_list里找到要处理的网卡并从该网卡的queue里面拿到skb,然后沿着网络设备子系统 -> IP协议层 -> TCP层一路调用内核里面的函数来分析和处理这个skb,最终将其放置到位于TCP层的socket接收队列里。 这个处理过程包括iptables的处理、路由查询、TCP协议处理等各种费时费力的工作。如图1所示,这里的iptables、路由查询等数据部分与每个network namespace相关,宿主机OS上会有若干个network ns,但TCP/IP协议栈作为代码部分却是大家共享的。

图 1:物理网卡和虚拟网卡数据接收完整数据处理流程

图2所示的K8s Overlay网络模型的实现有一个重要的技术点:veth pair。我们暂时将位于容器内的veth叫veth1,而插在bridge端口的那个对端veth称为veth-peer。当网络包从veth1流出时,其实是在图1的2.a处把skb所属的设备修改为veth-peer,先暂时放到了input_pkt_queue里,但这个时候skb还没有到设备veth-peer处。

步骤2.c所触发的软中断使得ksoftirqd/4开始消费input_pkt_queue里的skb。

当skb沿着图1右上部分的TCP/IP协议栈流到位于链路层的网络设备子系统的时候,也就来到了veth-peer的怀抱。对于veth-peer而言,这就开始了它接收网络包的协议栈相关的处理流程,这个流程包含了二层和三层的数据包过滤、数据包转换、路由查询等细节。对数据包的处理和路由查询所涉及到的规则和路由表都属于网络栈,而这个网络栈与veth-peer所在的network namespace有关。

图2-图6(除图4)都有一个公共的部分:VPC(Virtual Private Cloud)。它可以让我们在XX云上创建一个虚拟的私有网络。各个VPC之间的网络默认是完全的隔离的。VPC可以基于包括GRE、VXLAN在内的各种技术实现。二哥在文章《当vpc遇到K8s overlay》中介绍了基于VXLAN的实现方法。

通常VM被用来做K8s Work Node。这些图中的VM通过VPC被分成了两个隔离的网络,淡橙色部分的VM网段为172.20.6.35/16,VXLAN ID为1234;蓝色部分的网段为172.10.5.25/16,VXLAN ID为5678。

当然,一台物理服务器上会混合地运行属于不同VPC的VM,这几张图也强调了这点。

2. VPC与Overlay

这部分细节参考二哥的文章《当vpc遇到K8s overlay》。

图2的重点是在每台VM上,K8s CNI都会创建一个bridge和vtep。veth pair的一端安装在了Pod内部,而另一端则插到了网桥上。

bridge即为网桥,它的行为类似二层交换机。如果网络包的目的 MAC 地址为网桥本身,并且网桥设置了 IP 地址的话,那么bridge就认为该网络包应该是发往创建该网桥的那台主机,于是这个数据包将不会转发到任何设备,而是直接交给上层(三层)协议栈去处理。处理的过程会涉及到基于本机路由表的路由查询。

VTEP(VXLAN Tunnel Endpoints)是VXLAN网络中绝对的主角,它既可以是物理设备,也可以是虚拟化设备,主要负责 VXLAN 协议报文的封包和解包。

在本机路由规则的精心配合下,从Pod发出来的网络包先到达运行于这台VM上的VTEP设备,在那里进行 VXLAN 封包。类似地在对端VM上VTEP设备也会参与其中并进行解封包操作。两端VTEP的配合,给通信双方的Pod营造了一个假象:它们如同在同一个扁平的二层互通的局域网一样。

但这没有完,如果通信双方的Pod位于不同的VM里,还需要VPC的配合。这是另外一个VXLAN的封包和解包的故事,也就出现了另外一个隧道。所以你会在图2中看到两层VXLAN隧道:深青色VXLAN隧道和粉色VXLAN隧道。

图 2:vpc和K8s overlay网络模型

前文说到图1是基础,是基石。那么它的基础性在图2中是如何体现的呢?图2是veth pair+bridge+vtep的组合。那么当网络包从位于Pod内部的veth(发送端)流出的时候,就对应于图1中的线路2入口处。发送端veth将网络包递交给接收端veth的过程涉及到图1中的2.a、2.b、2.c。因为接收端veth插在网桥里面,这个过程涉及到网桥的处理,它体现在图1中TCP/IP协议栈里面,bridge部分的处理流程部分。

3. VPC与Underlay

这部分细节参考二哥的文章《广角-聊聊Underlay》和《一等公民,聊聊Underlay(微距篇)》。

和图2不同,图3里网络包从Pod流出后,像VM的eth0一样,直接进入了Open vSwith上。简单、粗暴、直接。但可惜,这种好事不是你想要就能有,得看K8s云产商是否提供这个功能。

图 3:vpc和K8s underlay网络模型

隔离特性使得流经这些network namespace里的,各自网络设备上面的流量是相互独立、平行的,尤其重要的是Pod里的流量进出这台虚拟机的时候,root network namespace无法感知到,所以在VM上对iptables、路由等设置对进出Pod的流量不起任何作用。traffic离开Pod和VM里的进程产生的traffic离开VM一样,都是离开各自的network namespace。

为了强调这样的平行关系,我在图3里画了两个蓝色的箭头和一个红色的箭头,它们的出发点分别是Pod和VM,终点是穿过Open vSwitch的远方。traffic从各自的network namespace离开,互不见面,互不问候,互不干扰。

不同的network ns有不同的实例。如前文所述,不同的实例包含了不同的网卡设备、IP地址等数据。TCP/IP协议栈只关心对于一个skb,要执行何种net filter规则、该做何种路由又该从哪个网卡将这个skb送走。至于这个网卡是在Pod内还是在宿主机VM上,重要吗?不重要。

什么?还是觉得抽象?没关系,换个姿势。二哥把内核中负责描述进程的数据结构task_struct和network namespace之间的结构关系画出来了。进程1和进程2共享宿主机root network namespace,它包含网卡eth0。Pod内的容器自然位于Pod自己的network ns中。但容器本质上也是进程而已,虽然在图中看起来Pod隔离了一个完全属于自己的eth1,但在内核看来,一样也是用相同的数据结构来描述它和network ns之间的关系。

好了,看完这个数据结构,我们再来想想,对于TCP/IP协议栈而言,是不是它面对的只是位于不同ns中的网卡而已呢?

图 4:network namespace与task_struct结构关系图

4. VPC与host-gw

可惜,这部分二哥之前没有专门撰文介绍。

Host-gw简单来讲就是将每个Node当成Pod的网关。所谓网关就像城门,是网络包离开当前局部区域的卡口。从当前位置动身出发至目的地,一路上会有若干个城池,若干个城门。沿途中每一个这样的卡口称为“下一跳”,也即下一次暂时落脚的地方。大家见过青蛙在荷叶上连续跳动的样子吧?青蛙每次都会选择下一个可以歇脚的荷叶,并把它作为下一次跳跃的起点。你可以把网络包想象成青蛙。

“下一跳”这个概念,我想唐僧一定感悟颇深:贫僧来自东土大唐(就是源 IP 地址),欲往西天拜佛求经(指的是目标 IP 地址)。路过宝地,借宿一晚,明日启程,请问接下来该怎么走啊?

Host-gw的实现方式有两种典型的代表:Flannel和Calico。它们的共同点都是以Node为网关,也都会查询宿主机上的路由表。但在宿主机的网络层看来,需要处理的网络包来自不同的设备。

4.1 VPC与host-gw(Flannel)

Flannel的实现方案里,由bridge来将离开Pod的网络包丢进宿主机TCP/IP协议栈进行路由的查询。最终网络包经由宿主机的eth0离开并进入对方宿主机的eth。当然这个过程中离不开OVS基于VXLAN所架设的隧道。

图中flanneld是一个daemonset,它负责维护每个Node(网关)的IP信息并更新宿主机的路由表。

图 5:vpc和K8s host-gw网络模型(Flannel实现方案)

图5和图1的关系在哪里呢?其实无论是网络包通过veth pair流动到网桥这一部分还是网络包从网桥出来后查询宿主机路由表部分都与图2“VPC与Overlay”非常相似。只不过差别在于经过路由查询后,二者的对网络包的处理不一样。图2部分,网络包被交给了vtep进行第一层的封包,而在这里,网络包则被直接从本机eth0发送出去了。可以看到这里少了一次VXLAN的封包和解封包操作,故而效率提高了一些。

4.2 VPC与host-gw(Calico)

Calico方案与Flannel方案最大的区别就是网桥不见了。图6中cali-xxx和Pod中的veth为veth pair。图6少了网桥,相应地也就不需要图1中bridge相关的处理过程,当cali-xxx收到了网络包后沿着图1所示的接收处理流程,直接将其丢进宿主机TCP/IP协议栈进行路由的查询。

图6中BGP Client用于在集群里分发路由规则信息,而Felix则负责更新宿主机的路由表。

其它类似,二哥就不再赘述了。

图 6:vpc和K8s host-gw网络模型(Calico实现方案)

以上就是本文的全部内容。谢谢!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 二哥聊云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一等公民,聊聊Underlay(微距篇)
上一篇二哥借助一张广角图聊了下数据中心、可用区、机架、物理机、VM、Pod之间的宏观关系。我们也确实可以看到,如今IT正在往虚拟化这个方向狂奔,十多年前,我们还在为以VM为代表的云计算机技术兴奋不已,如今大家的注意力已经完全被容器化吸引。
LanceZhang
2021/12/06
6070
一等公民,聊聊Underlay(微距篇)
当vpc遇到K8s overlay
在文章《广角-聊聊Underlay》中,二哥用一张大图画出了实现K8s“扁平网络”的三种典型实现方式:Overlay、主机间路由(host-gw)以及Underlay。
LanceZhang
2022/01/13
1.3K2
当vpc遇到K8s overlay
K8s网络模型
k8s网络模型设计基础原则:每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中 。 所以不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问。设计这个原则的原因 是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题。
加多
2019/04/18
3.6K2
K8s网络模型
multi-network ns在Underlay下的应用-本手篇
对容器而言,multiple namespace 这个技术的重要性怎么强调都不过分。因为 namespace 的出现,使得容器所用到的诸如 Hostname、Network、Mount Points 等资源被隔离起来,由公用变成独享。
LanceZhang
2022/06/20
5600
multi-network ns在Underlay下的应用-本手篇
Kubernetes网络模型
在Kubernetes中设计了一种网络模型,要求无论容器运行在集群中的哪个节点,所有容器都能通过一个扁平的网络平面进行通信,即在同一IP网络中。需要注意的是:在K8S集群中,IP地址分配是以Pod对象为单位,而非容器,同一Pod内的所有容器共享同一网络名称空间。
mikelLam
2022/10/31
1.1K0
Kubernetes网络模型
K8S之CNI
之前我们解决了跨主机间容器间通信的问题,但是这也只能说我们铺好了路,村里通路了,但是其实作为 k8s 来说,还有好多其他的问题等待着我们解决。今天我们就通过这些问题来看看 k8s 的 CNI 的设计。CNI 到底究竟是个什么东西,到底是不是和你想的一样那么困难。
LinkinStar
2022/09/01
1.3K0
K8S之CNI
特洛伊木马-图解VXLAN容器网络通信方案
一篇文章围绕一张图,讲述一个主题。不过这个主题偏大,我估计需要好几篇文章才能说得清楚。
LanceZhang
2021/12/06
8120
特洛伊木马-图解VXLAN容器网络通信方案
K8s网络模型
容器不是模拟一个完整的操作系统,而是对进程进行隔离,对容器里的进程来说它接触到的各种资源都是独享的,比虚拟机启动快、占用资源少。
冬夜先生
2021/09/02
1.9K0
kubernetes集群网络
问题:Pod是K8S最小调度单元,一个Pod由一个容器或多个容器组成,当多个容器时,怎么都用这一个Pod IP?
yuezhimi
2020/09/30
1.5K0
理解 net device Ingress 和 Egress 双重角色
本文是书稿《图解 VPC & K8s 网络模型》其中一篇。书稿还在继续写,进度不快也不慢,因为二哥不急也不躁。好肉需要慢炖,好书需要多磨。
LanceZhang
2023/03/09
2.4K0
理解 net device Ingress 和 Egress 双重角色
kubernetes(十八)集群网路
OSI(Open System Interconnection)是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。
alexhuiwang
2020/09/23
1.5K0
kubernetes(十八)集群网路
multi-network ns在Underlay下的应用-妙手篇
接着上篇《multi-network ns在Underlay下的应用-本手篇》,我们来聊聊基于 multiple network ns 的妙手级应用:Underlay 。
LanceZhang
2022/06/20
1.2K0
multi-network ns在Underlay下的应用-妙手篇
深入理解kubernetes(k8s)网络原理之三-跨主机pod连接
在之前的两篇文章中分别介绍了pod与主机连接并且上外网的原理及service的clusterIP和nodeport的实现原理,对于组织pod的网络这件事来说,还有最后一环需要打通,就是分布在不同集群节点的pod之间如何相互通信,本章我们来解决这最后一环的问题
一生无聊
2021/08/31
2.9K1
深入理解kubernetes(k8s)网络原理之三-跨主机pod连接
扁平-K8s网络模型漫谈
K8s定义了一个网络模型,目的是给Pod,service等使用者提供一个简单、一致的网络视图和使用体验,对它们屏蔽宿主机环境的网络拓扑的同时,也屏蔽网络模型实现上的细节。
LanceZhang
2021/12/06
2.1K0
扁平-K8s网络模型漫谈
K8S之跨主机通信
你是否之前看过 k8s 的网络部分,第一次看是否会觉得很困难?或者说你有没有想过为什么 k8s 要这样设计它的网络,跨主机之间的网络通信究竟是怎么实现的?今天就来搞一篇干货,其实想写这个很久了,但是一直拖延症,这次正好碰到了一个新的点想让我仔细重新审视一下。
LinkinStar
2022/09/01
1.6K0
K8S之跨主机通信
036.集群网络-K8S网络模型及Linux基础网络
  Kubernetes网络模型设计的一个基础原则是:每个Pod都拥有一个独立的IP地址,并假定所有Pod都在一个可以直接连通的、扁平的网络空间中。所以不管它们是否运行在同一个Node(宿主机)中,都要求它们可以直接通过对方的IP进行访问。设计这个原则的原因是,用户不需要额外考虑如何建立Pod之间的连接,也不需要考虑如何将容器端口映射到主机端口等问题。
不会飞的小鸟
2020/03/22
7360
tun设备的妙用-Flannel UDP模式篇
在文章《特洛伊木马-图解VXLAN容器网络通信方案》里,二哥画了下面这张鸟瞰大图。它把基于Flannel VXLAN模式实现的K8s Overlay网络模型所需要的各类网路设备放在了一起,主要突出的是这些设备之间的数据流向。但那篇文章有些许缺点(凡尔赛一下):
LanceZhang
2022/04/15
1K0
tun设备的妙用-Flannel UDP模式篇
Kubernetes容器网络模型解析
云原生(Cloud Native)可以认为是一套技术体系或生态,它包含2大部分:云(Cloud)和原生(Native)。云(Cloud)表示应用程序位于云中,而不是传统的数据中心;原生(Native)表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳状态运行,充分利用和发挥云平台的弹性和分布式优势。
Luga Lee
2021/12/09
1.1K0
Kubernetes容器网络模型解析
K8S跨Node网络
前面一章我们介绍了Node节点上面不同的容器之间的通讯方式,主要是根据docker0(网桥)+Veth Pair的方式来玩起来的。
灰子学技术
2022/01/18
5280
K8S跨Node网络
k8s实践(4)--k8s集群网络详解和flannel
在讨论Kubernetes网络之前,让我们先来看一下Docker网络。Docker采用插件化的网络模式,默认提供bridge、host、none、overlay、maclan和Network plugins这几种网络模式,运行容器时可以通过–network参数设置具体使用那一种模式。
黄规速
2022/04/14
2.6K0
k8s实践(4)--k8s集群网络详解和flannel
相关推荐
一等公民,聊聊Underlay(微距篇)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 大模型知识引擎×DeepSeek实践征文