【Kubernetes系列】第10篇 网络原理解析(下篇)

3. 覆盖网络 - Overlay Network

覆盖网络(overlay network)是将TCP数据包装在另外一种网络包里面进行路由转发和通讯的技术。Overlay网络不是默认必须的,可是它们在特定场景下很是有用。好比当咱们没有足够的IP空间,或者网络没法处理额外路由,抑或当咱们须要Overlay提供的某些额外管理特性。一个常见的场景是当云提供商的路由表能处理的路由数是有限制时,例如AWS路由表最多支持50条路由才不至于影响网络性能。所以若是咱们有超过50个Kubernetes节点,AWS路由表将不够。这种状况下,使用Overlay网络将帮到咱们。node

本质上来讲,Overlay就是在跨节点的本地网络上的包中再封装一层包。你可能不想使用Overlay网络,由于它会带来由封装和解封全部报文引发的时延和复杂度开销。一般这是没必要要的,所以咱们应当在知道为何咱们须要它时才使用它。web

为了理解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上,它只是另外一个网络接口。api

从pod1到pod4(在不一样节点)的数据包的流向相似以下:安全

1.它由pod1中netns的eth0网口离开,经过vethxxx进入root netns。网络

2.而后被传到cbr0,cbr0经过发送ARP请求来找到目标地址。负载均衡

3.数据封装分布式

*a. 因为本节点上没有Pod拥有pod4的IP地址,所以网桥把数据包发送给了flannel0,由于节点的路由表上flannel0被配成了Pod网段的目标地址。
*b. flanneld daemon和Kubernetes apiserver或者底层的etcd通讯,它知道全部的Pod IP,而且知道它们在哪一个节点上。所以Flannel建立了Pod IP和Node IP之间的映射(在用户空间)。flannel0取到这个包,并在其上再用一个UDP包封装起来,该UDP包头部的源和目的IP分别被改为了对应节点的IP,而后发送这个新包到特定的VXLAN端口(一般是8472)。ide

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

尽管这个映射发生在用户空间,真实的封装以及数据的流动发生在内核空间,所以仍然是很快的工具

*c. 封装后的包经过eth0发送出去,由于它涉及了节点间的路由流量。

4.包带着节点IP信息做为源和目的地址离开本节点。

5.云提供商的路由表已经知道了如何在节点间发送报文,所以该报文被发送到目标地址node2。

6.数据解包

*a. 包到达node2的eth0网卡,因为目标端口是特定的VXLAN端口,内核将报文发送给了 flannel0。
*b. flannel0解封报文,并将其发送到 root 命名空间下。从这里开始,报文的路径和咱们以前在Part 1 中看到的非Overlay网络就是一致的了。
*c. 因为IP forwarding开启着,内核按照路由表将报文转发给了cbr0。

7.网桥获取到了包,发送ARP请求,发现目标IP属于vethyyy。

8.包跨过管道对到达pod4

这就是Kubernetes中Overlay网络的工做方式,虽然不一样的实现仍是会有细微的差异。有个常见的误区是,当咱们使用Kubernetes,咱们就不得不使用Overlay网络。事实是,这彻底依赖于特定场景。所以请确保在确实须要的场景下才使用。

4. 动态集群

因为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 server的endpoint的更改并相应地更新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来进行服务名解析。

4.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操做。

4.2 入站流量

到目前为止一切都很好。Pod能够互相交谈,也能够访问互联网。但咱们仍然缺乏关键部分 - 为用户请求流量提供服务。截至目前,有两种主要方法能够作到这一点:

* NodePort /云负载均衡器(L4 - IP和端口)

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

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

* Ingress(L7 - HTTP / TCP)

许多不一样的工具,如Nginx,Traefik,HAProxy等,保留了http主机名/路径和各自后端的映射。一般这是基于负载均衡器和nodePort的流量入口点,其优势是咱们能够有一个入口处理全部服务的入站流量,而不须要多个nodePort和负载均衡器。

4.3 网络策略

能够把它想象为Pod的安全组/ ACL。 NetworkPolicy规则容许/拒绝跨Pod的流量。确切的实现取决于网络层/CNI,但大多数只使用iptables。

结束语

目前为止就这样了。 在前面的部分中,咱们研究了Kubernetes网络的基础以及overlay网络的工做原理。 如今咱们知道Service抽象是如何在一个动态集群内起做用并使服务发现变得很是容易。咱们还介绍了出站和入站流量的工做原理以及网络策略如何对集群内的安全性起做用。

参考文章:

An illustrated guide to Kubernetes Networking - part1

An illustrated guide to Kubernetes Networking - part2

An illustrated guide to Kubernetes Networking - part3

_

相关文章
相关标签/搜索