您好,登录后才能下订单哦!
这篇文章给大家介绍Kubernetes中的网络原理解析该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
覆盖⽹络(overlay network)是将TCP数据包装在另⼀种⽹络包⾥⾯进⾏路由转发和通信的技术。Overlay⽹络不是默认必须的,但是它们在特定场景下⾮常有⽤。⽐如当我们没有⾜够的IP空间,或者⽹络⽆法处理额外路由,抑或当我们需要Overlay提供的某些额外管理特性。⼀个常⻅的场景是当云提供商的路由表能处理的路由数是有限制时,例如AWS路由表最多⽀持50条路由才不⾄于影响⽹络性能。因此如果我们有超过50个Kubernetes节点, AWS路由表将不够。这种情况下,使⽤Overlay⽹络将帮到我们。
本质上来说, Overlay就是在跨节点的本地⽹络上的包中再封装⼀层包。你可能不想使⽤Overlay⽹络,因为它会带来由封装和解封所有报⽂引起的时延和复杂度开销。通常这是不必要的,因此我们应当在知道为什么我们需要它时才使⽤它。
为了理解Overlay⽹络中流量的流向,我们拿Flannel做例⼦,它是CoreOS 的⼀个开源项⽬。Flannel通过给每台宿主机分配⼀个⼦⽹的⽅式为容器提供虚拟⽹络,它基于Linux TUN/TAP,使⽤UDP封装IP包来创建overlay⽹络,并借助etcd维护⽹络的分配情况。
Kubernetes Node with route table (通过Flannel Overlay网络进行跨节点的Pod-to-Pod通信)
这⾥我们注意到它和之前我们看到的设施是⼀样的,只是在root netns中新增了⼀个虚拟的以太⽹设备,称为flannel0。它是虚拟扩展⽹络Virtual Extensible LAN(VXLAN)的⼀种实现,但是在Linux上,它只是另⼀个⽹络接⼝。
从pod1到pod4(在不同节点)的数据包的流向类似如下:
1)它由pod1中netns的eth0⽹⼝离开,通过vethxxx进⼊root netns。
2)然后被传到cbr0, cbr0通过发送ARP请求来找到⽬标地址。
3)数据封装
3a. 由于本节点上没有Pod拥有pod4的IP地址,因此⽹桥把数据包发送给了flannel0,因为节点的路由表上flannel0被配成了Pod⽹段的⽬标地址。
3b. flanneld daemon和Kubernetes apiserver或者底层的etcd通信,它知道所有的Pod IP,并且知道它们在哪个节点上。因此Flannel创建了Pod IP和Node IP之间的映射(在⽤户空间)。flannel0取到这个包,并在其上再⽤⼀个UDP包封装起来,该UDP包头部的源和⽬的IP分别被改成了对应节点的IP,然后发送这个新包到特定的VXLAN端⼝(通常是8472)。
Packet-in-packet encapsulation(notice the packet is encapsulated from 3c to 6b in previous diagram)
尽管这个映射发⽣在⽤户空间,真实的封装以及数据的流动发⽣在内核空间,因此仍然是很快的。
3c. 封装后的包通过eth0发送出去,因为它涉及了节点间的路由流量。
4. 包带着节点IP信息作为源和⽬的地址离开本节点。
5. 云提供商的路由表已经知道了如何在节点间发送报⽂,因此该报⽂被发送到⽬标地址node2。
6. 数据解包
6a. 包到达node2的eth0⽹卡,由于⽬标端⼝是特定的VXLAN端⼝,内核将报⽂发送给了
flannel0。
6b. flannel0解封报⽂,并将其发送到 root 命名空间下。从这⾥开始,报⽂的路径和我们之前在Part1 中看到的⾮Overlay⽹络就是⼀致的了。
6c. 由于IP forwarding开启着,内核按照路由表将报⽂转发给了cbr0。
7. ⽹桥获取到了包,发送ARP请求,发现⽬标IP属于vethyyy。
8. 包跨过管道对到达pod4
这就是Kubernetes中Overlay⽹络的⼯作⽅式,虽然不同的实现还是会有细微的差别。有个常⻅的误区是,当我们使⽤Kubernetes,我们就不得不使⽤Overlay⽹络。事实是,这完全依赖于特定场景。因此请确保在确实需要的场景下才使⽤。
由于Kubernetes(更通⽤的说法是分布式系统)天⽣具有不断变化的特性,因此它的Pod(以及Pod的IP)总是在改变。变化的原因可以是针对不可预测的Pod或节点崩溃⽽进⾏的滚动升级和扩展。这使得Pod IP不能直接⽤于通信。我们看⼀下Kubernetes Service,它是⼀个虚拟IP,并伴随着⼀组Pod IP作为Endpoint(通过标签选择器识别)。它们充当虚拟负载均衡器,其IP保持不变,⽽后端Pod IP可能会不断变化。
Kubernetes service对象中的label选择器
整个虚拟IP的实现实际上是⼀组iptables(最新版本可以选择使⽤IPVS,但这是另⼀个讨论)规则,由Kubernetes组件kube-proxy管理。这个名字现在实际上是误导性的。它在v 1.0之前确实是⼀个代理,并且由于其实现是内核空间和⽤户空间之间的不断复制,它变得⾮常耗费资源并且速度较慢。现在,它只是⼀个控制器,就像Kubernetes中的许多其它控制器⼀样,它watch api serverendpoint的更改并相应地更新iptables规则。
Iptables DNAT
有了这些iptables规则,每当数据包发往Service IP时,它就进⾏DNAT(DNAT=⽬标⽹络地址转换)操作,这意味着⽬标IP从Service IP更改为其中⼀个Endpoint - Pod IP - 由iptables随机选择。这可确保负载均匀分布在后端Pod中。
conntrack表中的5元组条⽬
当这个DNAT发⽣时,这个信息存储在conntrack中——Linux连接跟踪表(iptables规则5元组转译并完成存储:protocol, srcIP, srcPort, dstIP, dstPort)。这样当请求回来时,它可以un-DNAT,这意味着将源IP从Pod IP更改为Service IP。这样,客户端就不⽤关⼼后台如何处理数据包流。
因此通过使⽤Kubernetes Service,我们可以使⽤相同的端⼝⽽不会发⽣任何冲突(因为我们可以将端⼝重新映射到Endpoint)。这使服务发现变得⾮常容易。我们可以使⽤内部DNS并对服务主机名进⾏硬编码。
我们甚⾄可以使⽤Kubernetes提供的service主机和端⼝的环境变量来完成服务发现。
专家建议:采取第⼆种⽅法,你可节省不必要的DNS调⽤,但是由于环境变量存在创建顺序的局限性(环境变量中不包含后来创建的服务),推荐使⽤DNS来进⾏服务名解析。
到⽬前为⽌我们讨论的Kubernetes Service是在⼀个集群内⼯作。但是,在⼤多数实际情况中,应⽤程序需要访问⼀些外部api/website。通常,节点可以同时具有私有IP和公共IP。对于互联⽹访问,这些公共和私有IP存在某种1:1的NAT,特别是在云环境中。对于从节点到某些外部IP的普通通信,源IP从节点的专⽤IP更改为其出站数据包的公共IP,⼊站的响应数据包则刚好相反。但是,当Pod发出与外部IP的连接时,源IP是Pod IP,云提供商的NAT机制不知道该IP。因此它将丢弃具有除节点IP之外的源IP的数据包。
因此你可能也猜对了,我们将使⽤更多的iptables!这些规则也由kube-proxy添加,执⾏SNAT(源⽹络地址转换),即IP MASQUERADE(IP伪装)。它告诉内核使⽤此数据包发出的⽹络接⼝的IP,代替源Pod IP同时保留conntrack条⽬以进⾏反SNAT操作。
到⽬前为⽌⼀切都很好。Pod可以互相交谈,也可以访问互联⽹。但我们仍然缺少关键部分 - 为⽤户请求流量提供服务。截⾄⽬前,有两种主要⽅法可以做到这⼀点:
NodePort /云负载均衡器(L4 - IP和端⼝)
将服务类型设置为NodePort默认会为服务分配范围为30000-33000d的nodePort。即使在特定节点上没有运⾏Pod,此nodePort也会在每个节点上打开。此NodePort上的⼊站流量将再次使⽤iptables发送到其中⼀个Pod(该Pod甚⾄可能在其它节点上!)。
云环境中的LoadBalancer服务类型将在所有节点之前创建云负载均衡器(例如ELB),命中相同的nodePort。
Ingress(L7 - HTTP / TCP)
许多不同的⼯具,如Nginx, Traefik, HAProxy等,保留了http主机名/路径和各⾃后端的映射。通常这是基于负载均衡器和nodePort的流量⼊⼝点,其优点是我们可以有⼀个⼊⼝处理所有服务的⼊站流量,⽽不需要多个nodePort和负载均衡器。
可以把它想象为Pod的安全组/ ACL。NetworkPolicy规则允许/拒绝跨Pod的流量。确切的实现取决于⽹络层/CNI,但⼤多数只使⽤iptables。
⽬前为⽌就这样了。在前⾯的部分中,我们研究了Kubernetes⽹络的基础以及overlay⽹络的⼯作原理。现在我们知道Service抽象是如何在⼀个动态集群内起作⽤并使服务发现变得⾮常容易。我们还介绍了出站和⼊站流量的⼯作原理以及⽹络策略如何对集群内的安全性起作⽤。
关于Kubernetes中的网络原理解析该怎么理解就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。