首先,向大家科普下Kubernetes所选择的CNI网络接口,简单介绍下网络实现的背景。 CNI即Container Network Inte**ce,是一套容器网络的定义规范,包括方法规范、参数规范、响应规范等等。CNI只要求在容器创建时为容器分配网络资源、删除容器时释放网络资源。CNI与调用者之间的整个交互过程如下图所示: CNI实现与外界的交互都通过进程参数和环境变量传递,也只要求输出结果符合CNI规范即可,与实现语言也没什么特殊要求。比如Calico早期版本就使用Python实现了CNI规范,为Kubernetes提供了网络实现。常见的环境变量设置如下:
正因如此,CNI规范实现起来非常容易扩展,除了CNI自带的Bridge、Macvlan等基本实现以外,还有大量的第三方实现可供选择,包括Calico、Romana、Flannel等常用实现。同时CNI支持多种容器运行时,包括Docker、rkt、Mesos、Hyper等容器引擎都可以使用。这也是Kubernetes选择使用CNI的一大重要原因。 相对的,Docker提出的CNM(Cotainer Network Model)模型实现就比较复杂,但更为完善,比较接近传统的网络概念。如下图所示: Sandbox就是容器的网络命名空间,Endpoint为容器连接到网络中的一张网卡,而网络则是一组相互通信的Endpoint的集合,比较接近Neutron中的网络定义。 在CNM中,docker engine通过HTTP REST API调用网络实现,为容器配置网络。这些API接口涵盖网络管理、容器管理、创建endpoint等十几个接口。同时CNM模型还隐含在docker自身附带的service机制、dns机制等附加约束,因此可以在一定程度上说,CNM模型只是专为docker容器实现的,对别的容器运行时并不友好。 由于上面这些技术上的原因以及一些商业上的原因,Kubernetes最终选择了CNI作为自己的网络接口。 当然,Kubernetes也提供一些取巧的方法,将CNI接口转化为对CNM模型的调用,从而实现两种模型的通用。例如to_docker,这个脚本就将Kubernetes对CNI的调用转换为Docker CNM网络的对应操作,从而实现CNI到CNM的转换。 接下来,给大家介绍下Kubernetes中网络概念和通信原理。 在Kubernetes的网络模型中,约定了三个基本约束:
在满足约束的基础上,Kubernetes不关心具体的网络通信原理,只以三个约束为既定事实,在此基础上,根据Kubernetes自身逻辑处理网络通信,从而避免Kubernetes功能纠结在纷繁复杂的网络实现中。 而在网络概念上,Kubernetes中有两种核心IP:
以集群的DNS服务为例,相关的核心iptables如下图所示: 这些iptables都是由kube-proxy生成的,而且kube-proxy并不实际负责进行转发,因此即使kube-proxy服务异常,已经产生的iptables依然可以使流量能够正确的在服务IP和POD IP之间流转。其网络流量路径可以参考下图: 当访问DNS服务的端口10.254.0.3时,kube-proxy生成的iptables DNAT规则,将流量转发到后端POD IP及对应端口上,将流量按后端POD的IP个数实行随机均等分配。 而kube-proxy可以从kube-apiserver获取服务和POD的状态更新,随时根据其状态更新iptables,从而实现服务的高可用与动态扩展。 在基础的IP通信机制上,Kubernetes还通过Network Policy和Ingress提高网络安全性和响应性能。 Network Policy提供了网络隔离能力,它基于SIG-Network group演进而来,Kubernetes只提供内置的labelSelector和label以及Network Policy API定义,本身并不负责实现如何隔离。在Kubernetes使用的CNI网络实现中,目前只有Calico、Romana、Contiv等少少几个实现了Network Policy集成。一个典型的Network Policy定义如下所示:
它指定约束,具有role:db标签的POD只能被具有role:frontend标签的POD访问,除此之外拒绝所有流量。从功能上来讲,Network Policy可以等价于Neutron的安全组。 Ingress是负责对外提供服务的,通过Nginx对外提供一个单独接口,实现集群中的所有服务的对外提供,从而取代使用NodePort暴露每个服务的现有实现。目前,Kubernetes的Ingress提供了Nginx和GCE两种实现,感兴趣的同学可以直接参考官文档,https://github.com/kubernetes/ingress/tree/master/controllers。 Kubernetes社区中,比较常见的几种网络实现主要是以下两种:
从上面这些网络实现来看,目前Kubernetes的网络实现都还谈不上是比较成熟的SDN,因此我们公司在考察Kubernetes后,决定基于Neutron,为Kubernetes提供一个可用的SDN实现,这就是Skynet项目的由来。 下面我来跟大家分享下,Skynet在实践过程中的一些经验。 在实践中,首先要解决的就是Kubernetes中的网络概念,怎么翻译到Neutron中,才能比较合适地实现功能。 在第一个版本中,Kubernetes网络中概念翻译对应如下表所示:
|
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|