做者 | 阿里巴巴高级技术专家 叶磊node
本文来介绍一下 Kubernetes 对网络模型的一些想法。你们知道 Kubernetes 对于网络具体实现方案,没有什么限制,也没有给出特别好的参考案例。Kubernetes 对一个容器网络是否合格作出了限制,也就是 Kubernetes 的容器网络模型。能够把它归结为约法三章和四大目标。后端
先来看下约法三章:api
后文中会讲一下我我的的理解,为何 Kubernetes 对容器网络会有一些看起来武断的模型和要求。微信
四大目标实际上是在设计一个 K8s 的系统为外部世界提供服务的时候,从网络的角度要想清楚,外部世界如何一步一步链接到容器内部的应用?网络
最终要达到目标,就是外部世界能够链接到最里面,对容器提供服务。数据结构
对基本约束,能够作出这样一些解读:由于容器的网络发展复杂性就在于它实际上是寄生在 Host 网络之上的。从这个角度讲,能够把容器网络方案大致分为 **Underlay/Overlay **两大派别:less
下面简单讲一下,Network Namespace 里面能网络实现的内核基础。狭义上来讲 runC 容器技术是不依赖于任何硬件的,它的执行基础就是它的内核里面,进程的内核表明就是 task,它若是不须要隔离,那么用的是主机的空间( namespace),并不须要特别设置的空间隔离数据结构( nsproxy-namespace proxy)。运维
相反,若是一个独立的网络 proxy,或者 mount proxy,里面就要填上真正的私有数据。它能够看到的数据结构如上图所示。微服务
从感官上来看一个隔离的网络空间,它会拥有本身的网卡或者说是网络设备。网卡多是虚拟的,也多是物理网卡,它会拥有本身的 IP 地址、IP 表和路由表、拥有本身的协议栈状态。这里面特指就是 TCP/Ip协议栈,它会有本身的status,会有本身的 iptables、ipvs。工具
从整个感官上来说,这就至关于拥有了一个彻底独立的网络,它与主机网络是隔离的。固然协议栈的代码仍是公用的,只是数据结构不相同。
这张图能够清晰代表 pod 里 Netns 的关系,每一个 pod 都有着独立的网络空间,pod net container 会共享这个网络空间。通常 K8s 会推荐选用 Loopback 接口,在 pod net container 之间进行通讯,而全部的 container 经过 pod 的 IP 对外提供服务。另外对于宿主机上的 Root Netns,能够把它看作一个特殊的网络空间,只不过它的 Pid 是1。
接下来简单介绍一下典型的容器网络实现方案。容器网络方案多是 K8s 里最为百花齐放的一个领域,它有着各类各样的实现。容器网络的复杂性,其实在于它须要跟底层 Iass 层的网络作协调、须要在性能跟 IP 分配的灵活性上作一些选择,这个方案是多种多样的。
下面简单介绍几个比较主要的方案:分别是 Flannel、Calico、Canal ,最后是 WeaveNet,中间的大多数方案都是采用了跟 Calico 相似的策略路由的方法。
Flannel 方案是目前使用最为广泛的。如上图所示,能够看到一个典型的容器网方案。它首先要解决的是 container 的包如何到达 Host,这里采用的是加一个 Bridge 的方式。它的 backend 实际上是独立的,也就是说这个包如何离开 Host,是采用哪一种封装方式,仍是不须要封装,都是可选择的。
如今来介绍三种主要的 backend:
下面介绍一下 Network Policy 的概念。
刚才提到了 Kubernetes 网络的基本模型是须要 pod 之间全互联,这个将带来一些问题:可能在一个 K8s 集群里,有一些调用链之间是不会直接调用的。好比说两个部门之间,那么我但愿 A 部门不要去探视到 B 部门的服务,这个时候就能够用到策略的概念。
基本上它的想法是这样的:它采用各类选择器(标签或 namespace),找到一组 pod,或者找到至关于通信的两端,而后经过流的特征描述来决定它们之间是否是能够联通,能够理解为一个白名单的机制。
在使用 Network Policy 以前,如上图所示要注意 apiserver 须要打开一下这几个开关。另外一个更重要的是咱们选用的网络插件须要支持 Network Policy 的落地。你们要知道,Network Policy 只是 K8s 提供的一种对象,并无内置组件作落地实施,须要取决于你选择的容器网络方案对这个标准的支持与否及完备程度,若是你选择 Flannel 之类,它并无真正去落地这个 Policy,那么你试了这个也没有什么用。
接下来说一个配置的实例,或者说在设计一个 Network Policy 的时候要作哪些事情?我我的以为须要决定三件事:
本文内容到这里就结束了,咱们简单总结一下:
在 pod 的容器网络中核心概念就是 IP,IP 就是每一个 pod 对外通信的地址基础,必须内外一致,符合 K8s 的模型特征;
那么在介绍网络方案的时候,影响容器网络性能最关键的就是拓扑。要可以理解你的包端到端是怎么联通的,中间怎么从 container 到达 Host,Host 出了 container 是要封装仍是解封装?仍是经过策略路由?最终到达对端是怎么解出来的?
容器网络选择和设计选择。若是你并不清楚你的外部网络,或者你须要一个普适性最强的方案,假设说你对 mac 是否直连不太清楚、对外部路由器的路由表可否控制也不太清楚,那么你能够选择 Flannel 利用 Vxlan 做为 backend 的这种方案。若是你确信你的网络是 2 层可直连的,你能够进行选用 Calico 或者 Flannel-Hostgw 做为一个 backend;
最后就是对 Network Policy,在运维和使用的时候,它是一个很强大的工具,能够实现对进出流的精确控制。实现的方法咱们也介绍了,要想清楚你要控制谁,而后你的流要怎么去定义。
最后留一些思考,你们能够想想:
为何接口标准化 CNI 化了,可是容器网络却没有一个很标准的实现,内置在 K8s 里面?
Network Policy 为何没有一个标准的 controller 或者一个标准的实现,而是交给这个容器网络的 owner 来提供?
有没有可能彻底不用网络设备来实现容器网络呢?考虑到如今有 RDMA 等有别于 TCP/IP 的这种方案。
在运维过程当中网络问题比较多、也比较难排查,那么值不值得作一个开源工具,让它能够友好的展现从 container 到 Host 之间、Host 到 Host 之间,或者说封装及解封装之间,各个阶段的网络状况,有没有出现问题,可以快速的定位。据我所知应该如今是没有这样的工具的。
以上就是我对 K8s 容器网络的基本概念、以及 Network Policy 的一些介绍。
“ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术公众号。”