k8s网络基础
k8s的4种通信范围
pod内容器通信、各pod间通信、pod与service通信、集群外部与service通信
k8s对service和pod资源对象使用了专门网络,service的网络由k8s管理,但集群自身没有pod网络,需要通过兼容CNI(容器网络接口)规范网络插件配置实现
pod间可不通过NAT机制直接通信
所有节点可不通过NAT机制与容器通信
所有pod对象位于同一平面网络中,而且可以使用pod自身地址直接通信
三个网络
节点网络
各主机自身的网络,就是物理网卡,各主机通过物理网卡通信,该网络本身就存在,不能被k8s管理,需要管理员在集群构建前自行配置并管理
service网络
完全虚拟的网络,此类地址不会配置在物理网卡或pod网卡上,它是由对应节点的
kube-proxy生成对应的iptables或ipvs规则,安照该规则将访问service的数据包转发至后端指定的pod
pod网络
各pod通过该网络进行通信,该网络需要通过网络插件来生成,常见实现机制有overlay和underlay两种,常见解决方案有10多种,
下图客户端pod提供相应service访问,不过集群IP(service地址)是私有网络地址,只能供集群内部访问
总结:k8s创建3种网络分别供节点、pod、service使用,3种网络在node节点实现交汇,由iptables和ipvs规则实现数据转发
也就是说k8s集群中每个节点都有三个维度的网络
pod在不同维度如何通信
pod内容器通信
同一pod内两个容器有一个根容器(pause容器),它是在真正提供服务的容器创建前就创建出来的,不提供任何服务,把所有的容器收纳到一起,一个基础容器,唯一目的就是保存所有的命名空间
同一个节点多个 Pod
pause 容器启动之前,会为容器创建一对虚拟ethernet接口,一个保留在宿主机vethxxx (插在网桥上),一个保留在容器网络命名空间内,并重命名为eth0。两个虚拟接口的两端,从一端进入,另一端出来。任何 Pod 连接到该网桥的 Pod 都可以收发数据
如图所示
通过网桥把veth0和veth1组成为一个以太网,他们直接是可以直接通信的,另外这里通过veth对让pod1的eth0和veth0、pod2的eth0和veth1关联起来,从而让pod1和pod2相互通信。
Pod 1通过自己默认的以太网设备eth0发送一个数据包,eth0把数据传递给veth0,数据包到达网桥后,网桥通过转发表把数据传递给veth1,然后虚拟设备veth1直接把包传递给Pod2网络命名空间中的虚拟设备eth0
linux以太网桥(Linux Ethernet bridge)是一个虚拟的2层网络设备,目的是把多个以太网段链接起来,网桥维护了一个转发表,通过检查转发表通过它传输的数据包的目的地并决定是否将数据包传递到连接到网桥的其他网段,网桥代码通过查看网络中每个以太网设备特有的MAC地址来决定是传输数据还是丢弃数据
通过网桥这里把veth0和veth1组成为一个以太网,他们直接是可以直接通信的,另外这里通过veth对让pod1的eth0和veth0、pod2的eth0和veth1关联起来,从而让pod1和pod2相互通信。
Pod 1通过自己默认的以太网设备eth0发送一个数据包,eth0把数据传递给veth0,数据包到达网桥后,网桥通过转发表把数据传递给veth1,然后虚拟设备veth1直接把包传递给Pod2网络命名空间中的虚拟设备eth0
不同节点两个pod通信
k8s网络模型需要每个pod必须通过ip地址可以进行访问,每个pod的ip地址总是对网络中的其他pod可见,并且每个pod看待自己的ip与别的pod看待的是一样的(虽然他没规定如何实现),下面我们看不同Node间Pod如何交互
k8s中每个集群中的每个Node都会被分配了一个CIDR块(无类别域间路由选择,把网络前缀都相同的连续地址组成的地址组称为CIDR地址块)用来给该Node上的Pod分配IP地址。(保证pod的ip不会冲突)
另外还需要把pod的ip与所在的node ip关联起来
如上图Node1(vm1)上的Pod1与Node2(vm2)上Pod4之间进行交互。
首先pod1通过自己的以太网设备eth0把数据包发送到关联到root命名空间的veth0上,然后数据包被Node1上的网桥设备cbr0接受到,网桥查找转发表发现找不到pod4的Mac地址,则会把包转发到默认路由(root命名空间的eth0设备),然后数据包经过eth0就离开了Node1,被发送到网络。
数据包到达Node2后,首先会被root命名空间的eth0设备接收,然后通过网桥cbr0把数据路由到虚拟设备veth1,最终数据表会被流转到与veth1配对的另外一端(pod4的eth0)
疑问:如果k8s集群有多个node节点的root命名空间网络设备都是eth0,如何将数据转发给正确的node?是不是在集群局域网中广播询问谁有对应的mac地址?
每个Node都知道如何把数据包转发到其内部运行的Pod,当一个数据包到达Node后,其内部数据流就和Node内Pod之间的流转类似了。
集群外部客户端与pod通信
外部客户端访问pod的4种方式:
基于pod当前节点的端口
基于pod当前节点的网络命名空间
基于集群级别的nodeport
基于集群级别的LoadBancer(一种特殊的service)
注意:不管是4层还是7层负载调度都要经过两次转发:请求到达用于接收外部负载调度的LoadBalancer,转发给对应节点,节点通过ipvs规则再转发给对应pod
CNI网络插件
定义:是容器引擎与网络插件的中间层,用于给容器配置网络信息,目前由RKT、Docker、Openshift、Mecos等容器运行时维护
CNI网络插件往往是一个可执行文件,有容器编排系统调用,他有两个插件:NetPlugin和IPAM,NetPlugin在容器网络命名空间插入一个接口,在宿主机上执行虚拟网络配置,做网络管理,随后IPAM为刚建立的容器网络接口分配IP,这样容器网络管理和IP地址分配有两个插件分工进行
注意:图中CNI包含的两个插件没有分开显示
NetPlugin
为了保证所有pod在同一平面网络,他有两种方案来实现
overlay网络:借助VXLAN、UDP、IPIP或GRE隧道协议,通过隧道协议报文封装pod间的通信报文(IP报文或数据帧)来构建虚拟网络,这种方案由于需要额外报文封装,会有额外性能开销。但生产中还会用该方案,pod不被外部网络发现,相对安全
underlay网络:使用直接路由技术在pod子网间路由pod的报文,或者用Bridge、MAC、IP VLAN直接将容器暴漏给外部网络
NetPlugin为容器网络命名空间创建虚拟接口的方式
Veth设备对:创建一个网桥,相当于用一根网线把容器和宿主机内核/OpenSwitch网桥连接起来
多路复用:生成一个中间网络设备,该设备暴漏多个虚拟接口,端口的管理方式有两种,要么分配MAC地址并生成相关转发规则,要么分配IP地址并生成相关转发规则
硬件交换:如今市面上有相当数量的NIC支持SR-IOV(单根I/O虚拟化),SR-IOV是创建设备的一种实现方式,每个设备自身表现为一个独立的PCI设备,有自己的VLAN及硬件强制关联的QoS,SR-IOV提供了接近硬件级别的性能
IPAM分配IP方案
方案一:从本地主机地址空间分配IP,该方式没有地址租约,属于静态分配机制
方案二:通过DHCP插件生成客户端守护进程并运行在宿主机,它充当DHCP客户端与服务端的中间代理,可以续订租约
总结:k8s借助CNI插件完成容器的网络编排。每次初始化一个pod时,kubelet调用默认的CNI插件创建一个虚拟设备附加到对应的底层网络,为其配置IP参数、路由信息,将其映射到pod的网络命名空间。具体过程:kubelet在默认目录/etc/cni/net.d/查找JSON格式的CNI配置文件,基于该配置文件的type属性到/opt/cni/bin/查找相关的插件二进制文件,由该命令基于配置信息完成相应操作
overlay网络模型
大二层网络
在物理网络中,通过媒介联通多个物理网桥,只要各网桥上的每个主机IP不冲突即可,同理,宿主机的虚拟网桥可以基于二层网络建立一个局域网,让容器通过分配的IP相互通信,解决IP冲突的方案:将每个宿主机分配到同一网络中的不同子网,各宿主机基于自由子网分配容器IP
弊端:数据链路层的请求,其他节点无法识别,只能识别节点级别的网络信息
解决方案:基于原有建立的二层网络构建另一个网络通信的隧道,隧道转发的本质是将容器双方的通信报文分别封装为各自宿主机间的报文,让其他节点能够识别,前提是宿主机也就是节点支持隧道协议
在VXLAN技术中,大二层域可以简单理解为一个二层的局域网,被称为Bridge-Domain,以下简称BD。
VLAN需要VLAN ID进行标识和分区,同样BD需要VNI标识,为了VXLAN通信机制的正确性,通过VXLAN通信的IP报文一律不能分片,这就要就二层物理网络中的MTU(最大传输单元,通信协议某一层上面能传输的最大字节数)值必须足够大或者修改MTU值。
VTEP
VXLAN需要在原有网络基础上添加额外设备构建虚拟的逻辑网络,该设备成为VTEP(VXLAN Tunnel Endpoints)它工作于VXLAN网络边缘,负责协议报文的封包和解封,是VXLAN隧道的守门员,可以理解为交换机
在同一个BD的两个VTEP(同一个BD内可以有多个VTEP)通过建立隧道实现相互通信。对于flannel来说,这个VTEP设备就是各节点生成的flannel.1网络接口,其中1就是BD的标识VNI,只要flannel网络接口的VNI一样,就属于同一个BD
二层和三层网关
相同BD内,VTEP间通过二层网关通信;不同BD或VXLAN跟非VXLAN通信需要三层网关转发流量。VXLAN支持使用集中式和分布式网关,前者对流量进行集中管理,配置简单,转发效率低;后者每个节点都作为二层和三层网关,消除了瓶颈
VXLAN中的pod在通信前,源VTEP不知道目标VTEP位于哪个节点的哪个pod
方案一:多播,即同一BD内各VTEP加入同一个多播域,通过多播报文查询目标pod所在的目标VTEP
方案二:控制中心,建立共享存储服务,上面保存所有pod子网及相关VTEP的映射信息,各宿主机运行一个守护进程与该共享文件系统交互,查询相关映射信息。flannel默认采用该方式通信,共享存储就是etcd
注意:Linux内核从3.7开始支持VXLAN模块,之前版本可用UDP、IPIP、GRE隧道技术实现。考虑到现在公有云底层网络功能限制,overlay是最为可行的容器网络解决方案,适用于只注重网络性能的场景
Underlay网络模型
简介
是一种传统网络,有交换机和路由器等组成,借助以太网、路由协议、VLAN协议等实现通信,是Overlay的底层网络。容器中的Uderlay网络就是指借助驱动程序,把宿主机的网口暴漏给容器使用的技术,常见方案有MAC VLAN、IP VLAN、直接路由
MAC VLAN
MAC VLAN支持在同一个以太网接口上虚拟多个网络接口,每个接口拥有唯一MAC地址,可按需配置IP。它被网络工程师称为子接口,但在MAC VLAN中常用上层或下层接口表示。与docker网桥模式相比,MAC VLAN不依赖虚拟网桥、NAT、端口映射。它允许容器以虚拟接口方式直接连接物理接口。
MAC VLAN的工作特性
Private:禁止构建在同一物理接口上的多个MAC VLAN实例(容器接口)相互通信,即便外部物理交换机支持“发夹模式”也不行
VPEA:允许构建在同一物理接口上的多个MAC VLAN实例(容器接口)相互通信,需要外部物理交换机开启“发夹模式”或存在报文转发功能的路由器设备
Bridge:即docker网桥模式
Passthru:允许一个MAC VLAN实例直接连接物理接口
除了Passthru模式,其余模式都受到MAC VLAN控制,可将宿主机与容器完全隔离,隔离级别高于网桥式网络模型,适用于多租户模型。由于各实例有专用MAC地址,MAC VLAN允许传输广播和多播流量,但他要求物理接口工作于混杂模式,考虑到多数公有云环境不允许使用混杂模式,MAC VLAN更适用于本地网络环境
注意:MAC VLAN要求容器MAC地址唯一,这可能会生安全策略以防止MAC欺骗的交换机出现问题,因为这类交换机的每个接口只允许连接一个MAC地址。另外有些物理网卡支持的MAC地址数量有上限
IP VLAN
类似于MAC VLAN,它同样可以创建虚拟接口,分配IP。不同点:每个接口共享宿主机MAC地址,不会生成违反MAC欺骗的交换机安全策略,因为这符合交换机只允许连接一个MAC地址的规则,一个MAC地址也在物理网卡支持的MAC地址数量范围之内
IP VLAN有L2、L3两种模型,L2工作模式类似于MAC VLAN的Bridge模式,上层接口(物理接口) 用作网桥或交换机,用于为下层接口交换报文;L3模式中,上层接口看作路由器,为下层接口路由报文
L2与MAC VLAN Bridge模式都支持ARP协议和广播流量,都有用于直接接入网桥设备的网络接口,可通过802.1d数据包进行泛洪和MAC地址学习。在L3模式中,网络栈在容器内处理,不支持多播或广播流量,所以他的运行机制和路由器的报文处理机制相同
疑问:L2模型中各容器和宿主机共用一个MAC地址,网桥如何通过MAC地址交换报文
CNI选型
CNI概述:负责连接容器管理系统和网络插件,它们通过json文件通信,完成容器管理网络。具体操作由插件实现:创建容器网络命名空间(netns)、把接口关联到指定netns、为借口分配IP等,相当于先创建netns,然后调用CNI为netns配置网络,最后启动容器进程
网络插件概览
flannel:使用VXLAN或UDP协议封装IP报文(创建overlay网络)、将网络分配信息存储在etcd,同节点pod通信由本地虚拟网桥cni连接,跨节点pod通信由flannel守护进程封装隧道内的报文后,查询etcd路由信息并以此传输到目的地。flannel也支持host-gw路由模型
calico:性能灵活良好,可执行网络策略。是路由型CNI插件,它在各节点运行一个vRouter,通过BGP协议实现跨界点数据包路由。借助iptables实现访问控制
weavenet:也支持网络策略,也运行一个Vrouter,用来构建网格化的tcp连接,通过Gossip协议来同步控制信息。在数据平面上,weavenet通过UDP封装实现L2隧道报文封装,封装有2种模式:一是运行在用户空间的sleeve(套筒)模式,二是运行在内核空间的fastpath(快速路径)模式,当网络拓扑不适合fastpath时,自动切换到sleeve模式
multus CNI:多CNI插件,实现了所有内置插件插件和第三方插件,也支持k8s的
SR-IOV、DPDK、OVS-DPDK、VPP工作负载和k8s的云原生应用程序、基于NFV的应用程序,应用场景:需要为pod创建多网络接口
antrea:致力解决k8s原生网络,使用OpenSwitch构建数据平面,基于overlay网络完成pod间报文转换,支持网络策略、使用IPSee ESP加密GRE隧道流量
DAMM:诺基亚发布的电信网络插件,支持具有高级功能的IP VLAN,内置IPAM模块,可管理多个集群内的不连续三层网络;支持通过CNI meta插件将网络管理委派给任何其他网络插件
kube-router:k8s的一体化解决方案,可取代kube-proxy实现基于ipvs的service,为pod提供网络,支持网络策略,完美兼容GCP协议
插件的选择依据
底层系统环境限制:公有云多有专有实现,他们通常是当前环境好的选择。若虚拟环境限制较多,只能选择overlay网络,第三方插件方案有flannel VXLAN、calico IPIP、weavenet、antrea等。物理机几乎支持任何插件
容器网络功能网络需求:支持网络策略有calico、weavenet、antrea...后两个支持节点间通信加密。大量pod需要与集群外通信时应选择underlay一类插件
容器网络性能需求:overlay中的隧道传输有开销,性能稍差。underlay则不存在开销,overlay、underlay路由时支持较快的pod创建速度,但underlay中IP VLAN和MAC VLAN创建速度较慢
Flannel
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划实现,简单来说,它的功能有以下几点:
- 使集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
- 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。
- 创建一个新的虚拟网卡flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。
- 路由信息一般存放到etcd:多个node上的Flanneld依赖一个etcd cluster来做集中配置服务,etcd保证了所有node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化
- Flannel首先会在Node上创建一个名为flannel0的网桥(vxlan类型的设备),并且在每个Node上运行一个名为flanneld的代理.每个node上的flannel代理会从etcd上为当前node申请一个CIDR地址块用来给该node上的pod分配地址。
- Flannel致力于给k8s集群中的nodes提供一个3层网络,他并不控制node中的容器是如何进行组网的,仅仅关心流量如何在node之间流转。
如上图ip为10.1.15.2的pod1与另外一个Node上的10.1.20.3的pod2进行通信。
首先pod1通过veth对把数据包发送到docker0虚拟网桥,网桥通过查找转发表发现10.1.20.3不在自己管理的网段,就会把数据包转发给默认路由(这里为flannel0网桥)
flannel.0网桥是一个vxlan设备,flannel.0收到数据包后,由于自己不是目的10.1.20.3,也要尝试将数据包重新发送出去。数据包沿着网络协议栈向下流动,在二层时需要封二层以太包,填写目的mac地址,这时一般应该发出arp:”who is 10.1.20.3″。但vxlan设备的特殊性就在于它并没有真正在二层发出这个arp包,而是由linux kernel引发一个”L3 MISS”事件并将arp请求发到用户空间的flanned程序。
flanned程序收到”L3 MISS”内核事件以及arp请求(who is 10.1.20.3)后,并不会向外网发送arp request,而是尝试从etcd查找该地址匹配的子网的vtep信息,也就是会找到node2上的flanel.0的mac地址信息,flanned将查询到的信息放入node1 host的arp cache表中,flanneel0完成这项工作后,linux kernel就可以在arp table中找到 10.1.20.3对应的mac地址并封装二层以太包了:
由于是Vlanx设备,flannel0还会对上面的包进行二次封装,封装新的以太网mac帧:
node上2的eth0接收到上述vxlan包,kernel将识别出这是一个vxlan包,于是拆包后将packet转给node上2的flannel.0。flannel.0再将这个数据包转到docker0,继而由docker0传输到Pod2的某个容器里。
如上图,总的来说就是建立VXLAN 隧道,通过UDP把IP封装一层直接送到对应的节点,实现了一个大的 VLAN
pod与service通信
pod的ip地址是不持久的,当集群中pod的规模缩减或者pod故障或者node故障重启后,新的pod的ip就可能与之前的不一样的。所以k8s中衍生出来Service来解决这个问题。
k8s中 Service管理了一系列的Pods,每个Service有一个虚拟的ip,要访问service管理的Pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。
当数据包到达Service虚拟ip后,数据包会被通过k8s给该servcie自动创建的负载均衡器路由到背后的pod容器。下面我们看看具体是如何做到的
netfilter
为了实现负载均衡,k8s依赖linux内建的网络框架-netfilter。Netfilter是Linux提供的内核态框架,允许使用者自定义处理接口实现各种与网络相关的操作。 Netfilter为包过滤,网络地址转换和端口转换提供各种功能和操作,以及提供禁止数据包到达计算机网络内敏感位置的功能。在linux内核协议栈中,有5个跟netfilter有关的钩子函数,数据包经过每个钩子时,都会检查上面是否注册有函数,如果有的话,就会调用相应的函数处理该数据包
- NF_IP_PRE_ROUTING: 接收的数据包刚进来,还没有经过路由选择,即还不知道数据包是要发给本机还是其它机器。
- NF_IP_LOCAL_IN: 已经经过路由选择,并且该数据包的目的IP是本机,进入本地数据包处理流程。
- NF_IP_FORWARD: 已经经过路由选择,但该数据包的目的IP不是本机,而是其它机器,进入forward流程。
- NF_IP_LOCAL_OUT: 本地程序要发出去的数据包转发到IP层,还没进行路由选择。
- NF_IP_POST_ROUTING: 本地程序发出去的数据包,或者转发(forward)的数据包已经经过了路由选择,即将交由下层发送出去。
netfilter是工作在哪一层?
iptables
iptables是运行在用户态的用户程序,其基于表来管理规则,用于定义使用netfilter框架操作和转换数据包的规则。根据rule的作用分成了好几个表,比如用来过滤数据包的rule就会放到filter表中,用于处理地址转换的rule就会放到nat表中,其中rule就是应用在netfilter钩子上的函数,用来修改数据包的内容或过滤数据包。目前iptables支持的表有下面这些:
- Filter:从名字就可以看出,这个表里面的rule主要用来过滤数据,用来控制让哪些数据可以通过,哪些数据不能通过,它是最常用的表。
- NAT(*):里面的rule都是用来处理网络地址转换的,控制要不要进行地址转换,以及怎样修改源地址或目的地址,从而影响数据包的路由,达到连通的目的,这是家用路由器必备的功能。
- Mangle:里面的rule主要用来修改IP数据包头,比如修改TTL值,同时也用于给数据包添加一些标记,从而便于后续其它模块对数据包进行处理(这里的添加标记是指往内核skb结构中添加标记,而不是往真正的IP数据包上加东西)。
- Raw:在netfilter里面有一个叫做connection tracking的功能,主要用来追踪所有的连接,而raw表里的rule的功能是给数据包打标记,从而控制哪些数据包不被connection tracking所追踪。
- Security:里面的rule跟SELinux有关,主要是在数据包上设置一些SELinux的标记,便于跟SELinux相关的模块来处理该数据包。
在k8s中,iptables规则由kube-proxy控制器配置,该控制器监视K8s API服务器的更改。当对Service或Pod的虚拟IP地址进行修改时,iptables规则也会更新以便让service能够正确的把数据包路由到后端Pod。
iptables规则监视发往Service虚拟IP的流量,并且在匹配时,从可用Pod集合中选择随机Pod IP地址,iptables规则将数据包的目标IP地址从Service的虚拟IP更改为选定的Pod的ip。总的来说iptables已在机器上完成负载平衡,并将指向Servcie的虚拟IP的流量转移到实际的pod的IP。
在从service到pod的路径上,IP地址来自目标Pod。 在这种情况下,iptables再次重写IP头以将Pod IP替换为Service的IP,以便Pod认为它一直与Service的虚拟IP通信。
IPVS
k8s的最新版本(1.11)包括了用于集群内负载平衡的第二个选项:IPVS。 IPVS(IP Virtual Server)也构建在netfilter之上,并实现传输层负载平衡(属于Linux内核的一部分)。 IPVS包含在LVS(Linux虚拟服务器)中,它在主机上运行,并在真实服务器集群前充当负载均衡器。 IPVS可以将对基于TCP和UDP的服务的请求定向到真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。这使得IPVS非常适合Kubernetes服务。
声明Kubernetes服务时,您可以指定是否要使用iptables或IPVS完成群集内负载平衡。 IPVS专门用于负载平衡,并使用更高效的数据结构(哈希表),与iptables相比,允许几乎无限的规模。在创建IPVS负载时,会发生以下事情:在Node上创建虚拟IPVS接口,将Service的IP地址绑定到虚拟IPVS接口,并为每个Service的IP地址创建IPVS服务器。将来,IPVS成为集群内负载平衡的默认方法。
数据包从pod到service的流转
- 如上图当从一个Pod发送数据包到Service时候,数据包先从Pod1所在的虚拟设备eth0离开pod1,并通过veth对的另外一端veth0传递给网桥cbr0,网桥找不到service对应ip的mac地址,所以把包转发给默认路由,也就是root命名空间的eth0
- 在root命名空间的设备eth0接受到数据包前,数据包会经过iptables进行过滤,iptables接受数据包后会使用kube-proxy在Node上安装的规则来响应Service或Pod的事件,将数据包的目的地址从Service的IP重写为Service后端特定的Pod IP(本例子中是pod4).
- 现在数据包的目的ip就不再是service的ip地址了,而是pod4的ip地址。
- iptables利用Linux内核的conntrack来记住所做的Pod选择,以便将来的流量路由到同一个Pod(禁止任何扩展事件)。 从本质上讲,iptables直接在Node上进行了集群内负载均衡,然后流量使用我们已经检查过的Pod-to-Pod路由流到Pod。
Service到Pod的一个包的流转
- 收到此数据包的Pod将会回发包到源Pod,回包的源IP识别为自己的IP(比如这里为Pod4的ip),将目标IP设置为最初发送数据包的Pod(这里为pod1的ip)。
- 数据包进入目标Pod(这里为Pod1)所在节点后,数据包流经iptables,它使用conntrack记住它之前做出的选择,并将数据包的源IP重写为Service的IP。 从这里开始,数据包通过网桥流向与Pod1的命名空间配对的虚拟以太网设备,并流向我们之前看到的Pod1的以太网设备。
更多网络传输知识请参考http://www.360doc.com/content/20/1209/21/55423461_950464924.shtml
pod网络文档 https://blog.csdn.net/yang75108/article/details/101101384
service网络文档 https://blog.csdn.net/yang75108/article/details/101267444
nodeport vs loadbalancer vs ingress网络文档
https://www.bilibili.com/video/BV1Ft4y117Ch?p=3
kube-proxy视频 https://www.bilibili.com/video/BV1Ft4y117Ch?p=4