iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Kubernetes中的网络原理解析该怎么理解
  • 254
分享到

Kubernetes中的网络原理解析该怎么理解

2023-06-04 16:06:55 254人浏览 泡泡鱼
摘要

这篇文章给大家介绍kubernetes中的网络原理解析该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。01 覆盖网络覆盖⽹络(overlay network)是将tcp数据包装在另⼀种⽹络包⾥⾯进⾏路由转发和通

这篇文章给大家介绍kubernetes中的网络原理解析该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

01 覆盖网络

覆盖⽹络(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中的网络原理解析该怎么理解

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)。

Kubernetes中的网络原理解析该怎么理解

Packet-in-packet encapsulation(notice the packet is encapsulated from 3c to 6b in previous diagram)

尽管这个映射发⽣在⽤户空间,真实的封装以及数据的流动发⽣在内核空间,因此仍然是很快的。

3c. 封装后的包通过eth0发送出去,因为它涉及了节点间的路由流量。

包带着节点IP信息作为源和⽬的地址离开本节点。
5. 云提供商的路由表已经知道了如何在节点间发送报⽂,因此该报⽂被发送到⽬标地址node2。
6. 数据解包

6a. 包到达node2的eth0⽹卡,由于⽬标端⼝是特定的VXLAN端⼝,内核将报⽂发送给了
flannel0。
6b. flannel0解封报⽂,并将其发送到 root 命名空间下。从这⾥开始,报⽂的路径和我们之前在Part1 中看到的⾮Overlay⽹络就是⼀致的了。
6c. 由于IP forwarding开启着,内核按照路由表将报⽂转发给了cbr0。

⽹桥获取到了包,发送ARP请求,发现⽬标IP属于vethyyy。
8. 包跨过管道对到达pod4

这就是Kubernetes中Overlay⽹络的⼯作⽅式,虽然不同的实现还是会有细微的差别。有个常⻅的误区是,当我们使⽤Kubernetes,我们就不得不使⽤Overlay⽹络。事实是,这完全依赖于特定场景。因此请确保在确实需要的场景下才使⽤。

02动态集群

由于Kubernetes(更通⽤的说法是分布式系统)天⽣具有不断变化的特性,因此它的Pod(以及Pod的IP)总是在改变。变化的原因可以是针对不可预测的Pod或节点崩溃⽽进⾏的滚动升级和扩展。这使得Pod IP不能直接⽤于通信。我们看⼀下Kubernetes Service,它是⼀个虚拟IP,并伴随着⼀组Pod IP作为Endpoint(通过标签选择器识别)。它们充当虚拟负载均衡器,其IP保持不变,⽽后端Pod IP可能会不断变化。

Kubernetes中的网络原理解析该怎么理解

Kubernetes service对象中的label选择器

整个虚拟IP的实现实际上是⼀组iptables(最新版本可以选择使⽤IPVS,但这是另⼀个讨论)规则,由Kubernetes组件kube-proxy管理。这个名字现在实际上是误导性的。它在v 1.0之前确实是⼀个代理,并且由于其实现是内核空间和⽤户空间之间的不断复制,它变得⾮常耗费资源并且速度较慢。现在,它只是⼀个控制器,就像Kubernetes中的许多其它控制器⼀样,它watch api serverendpoint的更改并相应地更新iptables规则。

Kubernetes中的网络原理解析该怎么理解

Iptables DNAT

有了这些iptables规则,每当数据包发往Service IP时,它就进⾏DNAT(DNAT=⽬标⽹络地址转换)操作,这意味着⽬标IP从Service IP更改为其中⼀个Endpoint - Pod IP - 由iptables随机选择。这可确保负载均匀分布在后端Pod中。

Kubernetes中的网络原理解析该怎么理解

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来进⾏服务名解析。

2.1 出站流量

到⽬前为⽌我们讨论的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操作。

2.2 入站流量

到⽬前为⽌⼀切都很好。Pod可以互相交谈,也可以访问互联⽹。但我们仍然缺少关键部分 - 为⽤户请求流量提供服务。截⾄⽬前,有两种主要⽅法可以做到这⼀点:

将服务类型设置为NodePort默认会为服务分配范围为30000-33000d的nodePort。即使在特定节点上没有运⾏Pod,此nodePort也会在每个节点上打开。此NodePort上的⼊站流量将再次使⽤iptables发送到其中⼀个Pod(该Pod甚⾄可能在其它节点上!)。

云环境中的LoadBalancer服务类型将在所有节点之前创建云负载均衡器(例如ELB),命中相同的nodePort。

  • Ingress(L7 - Http / TCP)

许多不同的⼯具,如Nginx, Traefik, HAProxy等,保留了http主机名/路径和各⾃后端的映射。通常这是基于负载均衡器和nodePort的流量⼊⼝点,其优点是我们可以有⼀个⼊⼝处理所有服务的⼊站流量,⽽不需要多个nodePort和负载均衡器。

2.3 网站策略

可以把它想象为Pod的安全组/ ACL。NetworkPolicy规则允许/拒绝跨Pod的流量。确切的实现取决于⽹络层/CNI,但⼤多数只使⽤iptables。

⽬前为⽌就这样了。在前⾯的部分中,我们研究了Kubernetes⽹络的基础以及overlay⽹络的⼯作原理。现在我们知道Service抽象是如何在⼀个动态集群内起作⽤并使服务发现变得⾮常容易。我们还介绍了出站和⼊站流量的⼯作原理以及⽹络策略如何对集群内的安全性起作⽤。

关于Kubernetes中的网络原理解析该怎么理解就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: Kubernetes中的网络原理解析该怎么理解

本文链接: https://www.lsjlt.com/news/238496.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在 Golang 中替换正则表达式匹配的文本?
    在 go 中,可使用 regexp.replaceall 函数替换符合正则表达式的文本,该函数需要三个参数:待替换字符串、匹配模式和替换文本。例如,将字符串中 "fox" 替换为 "do...
    99+
    2024-05-14
    golang 正则表达式
  • 如何在 Golang 中测试随机数生成器的准确性?
    在 go 中测试随机数生成器准确性的步骤包括:生成大量随机数并计算每个范围内的出现次数,以确保均匀分布。针对指定均值和标准差计算每个范围内的出现次数,以确保正态分布。 如何在 Gola...
    99+
    2024-05-14
    golang 随机数
  • 面向对象设计原则在C++中的体现
    c++++ 体现了 oop 原则,包括:封装:使用类将数据和方法封装在对象中。继承:允许派生类从基类继承数据和行为。多态:允许对象的行为根据其类型而改变,通过虚函数实现。 面向对象设计...
    99+
    2024-05-14
    c++ 面向对象
  • c语言怎么区分小数和整数
    c 语言区分小数和整数的方法有:数据类型不同:小数类型(float、double)包含小数点,整数类型(int)不包含。printf() 函数中使用不同格式化字符串:小数用 %f,整数用...
    99+
    2024-05-14
    c语言
  • 设计模式在C++ 中的可复用性和可扩展性
    在 c++++ 中,设计模式通过提供经过验证的解决方案来提高可复用性和可扩展性。可复用性允许重复使用代码,例如 factory method 模式,它支持创建不同的产品而不影响具体类。可...
    99+
    2024-05-14
    c++ 设计模式 高可扩展性
  • C++语法中函数模板的灵活运用
    C++ 语法中函数模板的灵活运用 函数模板是 C++ 中的一项强大功能,允许您创建可用于不同数据类型的一组代码。这可以提高代码的可重用性,并使您能够编写更通用、更可维护的代码。 语法 ...
    99+
    2024-05-14
    c++语法 函数模板 c++
  • c语言怎么计算字符串长度和宽度
    在 c 语言中,计算字符串长度和宽度的函数分别为:strlen() 函数用于计算字符串长度,不包括终止符 '\0'。strwidth() 函数用于计算字符串在终端中的宽度,返回显示像素数...
    99+
    2024-05-14
    c语言
  • 如何用 Golang 正则匹配多个单词或字符串?
    golang 正则表达式使用管道符 | 来匹配多个单词或字符串,将各个选项作为逻辑 or 表达式分隔开来。例如:匹配 "fox" 或 "dog":fox|dog匹配 "quick"、"b...
    99+
    2024-05-14
    golang 正则 python
  • c语言怎么跳出多层循环
    在 c 语言中,可以使用嵌套的 break 语句跳出多层循环。对于每个要跳出的循环层,都需要一个单独的 break 语句。例如:使用一个 break 语句跳出内层循环再使用一个 brea...
    99+
    2024-05-14
    c语言
  • c语言怎么注释成中文
    c语言中文注释提供两种方式:行内注释(以"//"开头)和块注释(以"/"开头并以"/"结尾)。最佳实践包括:使用简明扼要的语言,在函数和类开头处添加块注释,在关键部分添加行内注释,保持注...
    99+
    2024-05-14
    c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作