当前位置:   article > 正文

k8s网络详解

k8s网络详解

一、Kubernetes网络基础

1、kubernetes的网络层级

  • 节点网络:集群宿主机节点间的网络通信,并且负责打通与集群外部的通讯。
  • pod网络:为集群上的pod提供网络,通过CNI网络插件来完成,如Fannel、Calico、Cilium等。
  • service网络:部署集群时指定网段,service从这里面分配。service对象的IP地址存在于相关的ipvs、iptables规则中,k8s集群自行管理

2、kubernetes集群中的流量

Kubernetes网络中主要存在四种流量

  • 同一pod内的容器间通讯
  • pod间的通讯
  • pod与service的通讯
  • 集群外部流量与service间的通讯

3、CNI插件条件

pod网络插件,需要满足的功能要求

  • 所有pod间直接通信而不需要通过NAT机制
  • 所有节点与pod间直接通讯而不需要通过NAT机制
  • 所有pod对象都位于同一平面网络内

4、CNI插件的类型

网络插件:负责将pod连接到网络中

IPAM:(IP地址管理),负责分配pod IP地址

5、CNI插件的网络模型

overlay:覆盖网络,基于数据包的二次加密进行通讯。

​ 缺点:对性能有轻微影响,封装数据包的过程需要占用少量的CPU,由于数据包中需要额外的字节来对封装进行编码,(添加VXLAN或者IP-in-IP头),从而减少了可发送的内部数据包的最大大小,意味着相同的数据需要发送更多次。

route:路由网络,基于路由条目进行通信。

二、Flannel网络插件

1、Flannel支持三种后端实现

VXLAN:经典模式
host-gw:
UDP:已经弃用,性能较低

2、VXLAN模式

1.概述

cni0:他同docker网络模式不同的是,docker默认会创建一个名为docker0的网桥,而flannel会通过一个cni0来替换docker0。

overlay:(覆盖网络),在现有的三层网络之下,“覆盖一层”虚拟的,由内核VXLAN模块负责维护的二层网络,使得在连接在这个VXLAN二层网络的pod之间,可以像在同一个局域网里一样,自由通讯。

VXLAN:(虚拟可扩展局域网),是linux内核本身就支持的一种网络虚拟化技术。VXLAN完全就可以在内核实现封装和解封装的行为。

架构图

VTEP:(VXLAN Tunnel End Point 虚拟隧道端点),是宿主机上的特殊的网络设备,它既有IP地址,也有MAC地址;可以封装和解封装二层数据帧;这个行为都在内核中完成。

2.工作流详解

根据下图来进行一系列的分析

在这里插入图片描述

如上图所示,假设我们给pod配置的子网范围(CIDR)是10.244.0.0./16(在kube-controller-manager中配置),假设container-1要访问container-2,这个源地址为10.0244.0.2,目标地址为10.244.1.3的IP包,会先到cni0的网桥上,然后被路由到flannel.1上进行处理封装,查看Node1上的路由表如下

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
...
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

因为目标pod的地址为10.244.1.3,根据路由的最长匹配原则,匹配到第二条。也就是下面这条,这条路由信息是由每台宿主机上的flanneld进程维护的,比如当一个新node节点启动并且加入到Flannel网络之后,在所有的node节点就会出现这么一条路由规则。

10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
  • 1

这条指定了目标网段为10.244.1.0的数据包,都交由flannel.1设备进行处理,网关是10.244.1.0,正是隧道的另一端VTEP设备,也就是宿主机node2的flannel.1设备。

注:下面会将Node1、Node2的VETP设备称为源VETP设备和目标VETP设备,数据包称为原始数据包

由于flannel的目的是通过VETP设备将集群变为一个虚拟二层网络。即通过mac地址进行通讯,通过路由表已知目标设备的IP,我们再通过APR协议来获得目标VTEP的 Mac地址。

这时flannel.1设备将原始数据包的包头进行了二层封包,将目的VTEP设备的mac地址封到了头部,但是,我们并不能知道,目标容器在哪一个宿主机,我们还要想办法知道对面宿主机的IP和mac地址,把我们的这个数据包还要再次进行封装;

为了让对端接收到数据帧的时候,知道这是一个VXLAN的数据帧,所以我们在前面封装一个特殊的VXLAN头VNI,VNI是一个32位的标识符,用于区分不同的VXLAN隧道,来表示这是一个VXLAN专用数据帧。

然后linux内核会把他封装成一个普通的UDP包(默认4789端口)发出去,(因为UDP的简单性和高性能等特点,所有封装UDP数据包),这时内部的数据包已经封装完成,就差获取目标容器的宿主机的IP地址;flannel会维护一个FDB(Forwarding Database)转发数据库,里面有其他Node节点IP地址与其VTEP的MAC地址的对应关系,来获取目标Node节点的IP地址,以及Mac地址,最终完成数据包的封装,通过低层网络发出去。FDB如下

# 在Node 1上,使用“目的VTEP设备”的MAC地址进行查询
$ bridge fdb show flannel.1 | grep 5e:f8:4f:00:e3:37
5e:f8:4f:00:e3:37 dev flannel.1 dst 10.168.0.3 self permanent
  • 1
  • 2
  • 3

这时候,完整的数据帧就出来了,如下图所示

在这里插入图片描述

这个帧会经过宿主机网络来到 Node 2 的 eth0 网卡。这时候,Node 2 的内核网络栈会发现这个数据帧里有 VXLAN Header,并且 VNI=1。所以 Linux 内核会对它进行拆包,拿到里面的内部数据帧,然后根据 VNI 的值,把它交给 Node 2 上的 flannel.1 设备。而 flannel.1 设备则会进一步拆包,取出“原始 IP 包”。最终,IP 包就进入到了 container-2 容器的 Network Namespace 里。以上,就是 Flannel VXLAN 模式的具体工作原理了

3.VXLAN模式简单概述

在Flannel的VXLAN模式下,数据包的流程如下:

  1. 源容器发送数据包:源容器(例如Container-1)生成一个IP数据包,并将其发送到本地的cni0设备。

  2. 数据包到达本地节点:数据包通过本地节点的cni0设备进入Linux内核。

  3. 封装数据包:Linux内核根据路由表中的信息,将数据包封装在VXLAN头部中。VXLAN头部包含了目标VTEP设备的MAC地址和IP地址,以及VNI(VXLAN Network Identifier)标识。

  4. 发送封装后的数据包:封装后的数据包通过UDP协议的4789端口发送到目标节点。

  5. 目标节点接收数据包:目标节点的Linux内核接收到UDP数据包。

  6. 解封装数据包:目标节点的Linux内核根据VXLAN头部中的VNI标识,将数据包解封装,并将其发送到目标VTEP设备(例如flannel.1)。

  7. 转发数据包:目标VTEP设备将数据包转发给目标容器(例如Container-2)。

  8. 目标容器接收数据包:目标容器接收到数据包,并进行相应的处理。

3、host-gw模式

1.概述

host-gw模式为三层解决方案;不存在flannel.1的设备,因为不需要进行加密,

工作原理:将Flannel子网的下一跳配置成宿主机的IP地址,主机充当网关;flannel 子网和主机都保存到etcd中,flanneld需要watch这些键值的变化,实时更新路由表即可。

host-gw模式必须要求宿主机二层互通。

2.工作流详解

根据下图进行分析

在这里插入图片描述

假设Node 1上的infra-container-1要访问Node 2 上的infra-container-2,当你新增node节点时,flannel会在每个节点上创建一条如下的规则,

$ ip route
...
10.244.1.0/24 via 10.168.0.3 dev eth0
  • 1
  • 2
  • 3

表示为,如果目标IP地址的网段是10.244.1.0,则发往eth0网卡,下一跳的IP地址为10.168.0.3,也就是Node 2的网卡。

当IP包从网络层进入到数据链路层进行封装的时候,就会将下一跳的地址作为Mac地址,作为目的mac地址,显然这个mac地址就是node 2的地址,这样就可以通过二层网络进入到node 2上。

当node 2拿到数据包后,发现目标的IP地址为infra-container-2的IP地址,这时根据路由表,再发给cni0网桥,进入infra-container-2中。

3.限制

要求集群宿主机之间是二层联通的

三、Calico网络插件

1、BGP协议

1.概念

AS:autonomous system,当路由发生变化时,进行路由通告的范围。

IGP:Interior Gateway Protocol,只在AS内部进行更新的路由协议,比如RIP(距离矢量路由洗衣)、OSPF(链路状态路由协议)、IS-IS等。

BGP:Border Gateway Protocol,在AS与AS之间同步路由协议。

BGP AS号:2字节长度AS号范围是1-65535,共有AS的范围是1-64511,私有AS范围是64512-65534

BGP邻居:

  • 使用TCP传递信息,端口号为179。
  • BGP不会主动发现BGP邻居,邻居需要手动配置;必须双方都指定邻居,互发数据包才行。
  • 一个AS内可能有多个边界路由器,同一个AS内的边界路由器建立的邻居关系为Internal BGP(iBGP),不同AS邻居关系为External BGP(eBGP);
  • BGP要求eBGP必须直连;
  • 只有BGP形成邻居后,才开始交换路由信息,之后就是增量更新

BGP TTL:BGP可能会经过多个AS,防止环路,经过的每一个AS都打上AS号,当出现相同的AS号时,判断为出现环路,丢弃路由;BGP强制在AS内部只传一跳。

BGP 路由表:在边界路由器中:BGP得到的路由与普通路由分开存放,边界路由器会有两张路由表。

2.简述

在每个自治系统上的边界网关路由器,又运行一个程序,他会将本自治系统的路由信息,通过TCP发给其他自治系统的边界网关的179端口,而其他边界网关的这个程序对这些路由信息进行分析,再将自己需要的写到自己的自治系统中的边界路由器中,这样所有的自治系统内都有其他自治系统的路由信息了,可以通过边界网关路由器互相访问了

2、Node-to-Node模式

1.架构组成

CNI插件:与k8s对接

Felix:以Daemonset的形式部署在每一台宿主机上,负责在宿主机上插入路由规则,以及维护Calico所需的网络设备。

BIRD:BGP的客户端,负责在集群中分发路由规则信息

2.工作流详解

架构如下图

在这里插入图片描述

Calico的CNI插件会为每一个容器创建一个Veth Pair设备,把一端直接放到宿主机上(名字以cali开头);与flannel host-gw模式不同的是,不再创建网桥设备。CNI插件的作用是,需要为每个虚拟网卡配置条路由规则。如下

10.233.2.3 dev cali5863f3 scope link
  • 1

即发往10.233.2.3的数据包应发给cali5863f3设备。

BGP的作用是,在源宿主机上配置路由规则,路由规则里指明了,目标网段的下一跳,就是目标的宿主机网卡;到达目标宿主机的网卡后,再根据CNI插件创建的路由规则,转发到对应的虚拟网卡上,这样就完成了,一次数据包发送。

3.限制

要求宿主机二层网络连通

3、IP-in-IP模式

1.为什么使用IP-in-IP模式

用于宿主机节点不在同一二层网络内,XVLAN是基于mac地址工作,工作在二层;IPIP是基于IP地址工作,工作在三层。

2.工作流

IP-in-IP示意图

在这里插入图片描述

IP-in-IP模式会在每个宿主机上创建一个tunl0的虚拟网卡,所有pod网段的路由也有指定到这个网卡上面。如下

10.233.2.0/24 via 192.168.2.2 tunl0
  • 1

规则表示,下一跳没有改变,将数据包发出的设备,变成了tunl0,tunl0是一个IP隧道设备;当数据包进入到tunl0时,IPIP驱动会将这个数据包直接封装在宿主机的IP包中,经过封装后的IP包的目的地址正是Node2的地址,这样原本是Container 1到Node 2的数据包,就变成了一个从Node 1发往Node 2的数据包。由于宿主机之前是三层连通的,所以会转发到Node 2的网卡上,,Node 2的网络内核栈会使用IPIP驱动进行解包,从而拿到原始包,再通过路由规则发送给容器Container 4。

3.IP-in-IP模式的三种类型

Never:绝不使用IP-in-IP模式;适用于低层网络工作在同一个子网下。

CrossSubnet:混合模式;适用于集群存在于不同网络中,在同一子网内不使用IPIP进行加密,在不同子网中,使用IPIP进行封装。

Always:始终使用IP-in-IP进行封装。在公有云场景下,自建集群可以使用。

4.MTU配置

MTU:(最大传输单元),增大MTU可以提高性能,减小可以解决MTU过高时的丢包问题。

当配置为IPIP模式时,由于使用了覆盖标头,所以将calico的MTU配置为,网卡的默认MTU减去覆盖标头的大小,(IP in IP 使用 20 字节标头,IPv4 VXLAN 使用 50 字节标头,IPv6 VXLAN 使用 70 字节标头,IPv4 WireGuard 使用 60 字节标头,IPv6 WireGuard 使用 80 字节标头)

查看默认的MTU

[root@iZbp1igh8gtzjj9sgk4cykZ jws2]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.185.245  netmask 255.255.240.0  broadcast 172.16.191.255
        inet6 fe80::216:3eff:fe0c:cb2b  prefixlen 64  scopeid 0x20<link>
        ether 00:16:3e:0c:cb:2b  txqueuelen 1000  (Ethernet)
        RX packets 2162482167  bytes 356805441901 (332.3 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2145825982  bytes 387956365773 (361.3 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

查看calico的MTU

[root@iZbp1igh8gtzjj9sgk4cykZ jws2]# ifconfig 
tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480
        inet 172.20.93.64  netmask 255.255.255.255
        tunnel   txqueuelen 1000  (IPIP Tunnel)
        RX packets 7129777  bytes 4936439040 (4.5 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8200734  bytes 2071010638 (1.9 GiB)
        TX errors 0  dropped 4 overruns 0  carrier 0  collisions 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、Router Reflector模式

1.为什么使用Router Reflector模式

Node-to-Node的模式,在小规模节点上是没有问题的,但是当集群的节点大于100;

因为每台Node节点都要与其他节点进行通讯进行路由信息交换,随着节点数增加,连接数会以指数的形式上升,从而给集群网络带来压力。

所以需要用到Route Reflector模式,Calico会指定专门的节点,他们负责和所有节点建立BGP连接,从而学习到所有的路由规则,这样,所有节点在从这几个节点交换路由规则,就会极大的减少tcp连接数

5、Felix组件

Felix是Calico的核心组件之一,它是一个代理程序,负责在每个节点上管理网络和安全策略。

Felix的功能和使用场景如下:

  1. 网络管理:Felix负责在每个节点上配置和管理网络连接。它使用Linux内核的网络命名空间和网络设备,为每个容器创建虚拟以太网接口(veth pair),并将其连接到主机网络。Felix还负责为容器分配IP地址,并处理网络流量的转发和路由。

  2. 安全策略:Felix实现了Calico的网络安全功能,包括网络策略和入口/出口规则。它根据定义的策略规则,过滤和控制容器之间的网络通信。Felix会监视Kubernetes API服务器上的网络策略变化,并相应地更新节点上的iptables规则,以确保策略的一致性和正确性。

  3. 路由管理:Felix负责管理节点上的路由表,确保容器之间的网络流量能够正确地转发。它会监视网络拓扑的变化,并相应地更新路由表,以确保容器之间的通信能够顺利进行。

  4. 故障恢复:Felix具有自动故障恢复的能力。它会监视节点上的网络连接和服务的状态,并在发现故障时采取相应的措施。例如,如果一个容器或节点失去连接,Felix会尝试重新建立连接或重新启动容器,以确保网络的连通性和可靠性。

总之,Felix是Calico的关键组件之一,负责在Kubernetes集群中提供高性能的容器网络和网络安全功能。它管理网络连接、实施安全策略、管理路由和处理故障恢复,以确保容器之间的通信能够安全、可靠和高效地进行。

参考:

为什么很少看到基于tcp的隧道?–>https://www.jianshu.com/p/5118192ca414

容器网络–>https://www.jianshu.com/p/5468928d31e5

吃透BGP—>https://zhuanlan.zhihu.com/p/665266069

BGP协议介绍总结—>https://blog.csdn.net/weixin_63832692/article/details/130677022

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/434241
推荐阅读
相关标签
  

闽ICP备14008679号