如果你已经使用过kubernetes技术并跑过一些测试或生产服务,你可能已经体验过K8s技术带来的革命性变化。小伙伴,建议尽快入坑,毕竟这是技术趋势。目前虽然有很多工具可以用来架设和管理集群,但是我们还是需要知道k8s底层到底发生了什么,尤其是遇到问题的时候,只有知道底层原理才能从某个现象来分析哪里有问题才能解决实际问题。从技术上讲,Kubernetes其实在底层是非常复杂的,它有很多组件。因此,有必要了解他们如何合作和共同努力,才能真正了解实际问题。说到这里,不得不说K8sNetworking是最复杂和最关键的网络之一。因此,在本文中,我们通过图文并茂的方式来深入了解Kubernetes中的网络是如何工作的。KubernetesNetworking的核心是一个重要的基本设计概念:每个Pod都有一个唯一的IP。此PodIP由该Pod中的所有容器共享,并且可与所有其他Pod路由。你有没有注意到Kubernetes节点上运行着一些“暂停”的容器?这些被称为“沙盒容器”,其唯一工作是保留和保存Pod中所有容器共享的网络命名空间(netns)。这样,即使容器死了,并且在其位置创建了一个新容器,容器IP也不会改变。这种单机IP模式的最大好处是与底层主机没有IP或端口冲突。此外,我们不必担心应用程序使用哪个端口。有了这个,Kubernetes的唯一要求是这些podIP可以从所有其他pod路由/访问,无论它们在哪个节点上。节点内通信的第一步是确保同一节点上的Pod可以相互通信。然后将该想法扩展到跨节点通信、互联网等。在每个Kubernetes节点(在本例中为Linux机器)上,都有一个根网络命名空间(root作为root,而不是超级用户)——rootnetns。主网络接口eth0在此根netns中。同样,每个pod都有自己的网络,并且有一个虚拟以太网对将其连接到根网络。这基本上是一对管道,一端在根网格中,另一端在豆荚网格中。我们将pod-end命名为eth0,因此pod不知道底层主机并认为它有自己的根网络设置。另一端的名称类似于vethxxx。可以使用ifconfig或ipa命令在节点上列出所有这些接口。对节点上的所有pod执行此操作。为了让这些Pod相互通信,使用了Linux以太网桥cbr0。Docker使用一个名为docker0的类似桥接器。可以使用brctlshow命令列出网桥。假设一个数据包从pod1到pod2。它将pod1的网络保持在eth0,根网络保持在vethxxx。将其传递给cbr0,它使用ARP请求发现目的地并说“谁拥有这个IP?”vethyyy说它有那个IP,所以网桥知道将数据包转发到哪里。数据包到达vethyyy,通过管道对到达pod2的网络。这就是节点上的容器相互通信的方式。显然还有其他方法,但这可能是最简单的方法。节点间通信如前所述,Pod也必须在节点之间可达。Kubernetes不关心它是如何完成的。我们可以使用L2(跨节点的ARP)、L3(跨节点的IP路由——就像云提供商的路由表)覆盖网络。只要流量可以到达另一个节点上所需的pod就没有关系。每个节点都为PodIP分配了一个唯一的CIDR块(IP地址范围),因此每个Pod都有一个唯一的IP,不会与另一个节点上的Pod冲突。在大多数情况下,尤其是在云环境中,云提供商路由表可确保数据包到达正确的目的地。同样的事情可以通过在每个节点上设置正确的路由来完成。还有许多其他网络插件也可以发挥作用。这里我们有两个节点,类似于我们之前看到的。每个节点都有不同的网络名称空间、网络接口和网桥。假设一个数据包从pod1到pod4(在另一个节点上)。1.它保持pod1的网络在eth0和根网络在vethxxx。2.它被传递给cbr0,cbr0发出ARP请求以找到目的地。3.它从cbr0到主网络接口eth0,因为此节点上没有人拥有pod4的IP地址。4、它会离开node1,此时src=pod1,dst=pod4。5.路由表为每个节点CIDR块设置了一条路由,数据包被路由到其CIDR块包含pod4IP的节点。6.因此,数据包到达主网络接口eth0上的node2。现在,即使pod4不是eth0的IP,由于节点配置了IP转发,数据包还是转发到了cbr0。在节点的路由表中查找与pod4IP匹配的所有路由。它发现cbr0作为该节点的CIDR块的目标。您可以使用route-n命令列出节点路由表。7.网桥收到包,发出ARP请求,发现IP属于vethyyy。8.数据包通过管道对到达pod4
