您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 基于OpenStack和Kubernetes构建组合云平台――网络集成方案综述
基于OpenStack和Kubernetes构建组合云平台——网络集成方案综述Kubernetes的优秀设计图1Kubernetes集群的架构在我们介绍网络方案之前,先向大家简单介绍一下Kubernetes的基础构架。一个Kubernetes集群是由分布式存储(etcd),服务节点(Minion)和控制节点(Master)构成的。所有的集群状态都保存在etcd中,Master节点上则运行集群的管理控制模块。Minion节点是真正运行应用容器的主机节点,在每个Minion节点上都会运行一个Kubelet代理,控制该节点上的容器、镜像和存储卷等。支持多容器的微服务实例Kubernetes有很多基本概念,最重要的也是最基础的是Pod。Pod是一个运行部署的最小单元,他是可以支持多容器的。为什么要有多容器?比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。自动提供微服务的高可用Kubernetes集群自动提供微服务的高可用能力,由复制控制器(ReplicationController)即RC进行支持。RC通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。微服务在集群内部的负载均衡在Kubernetes内部,一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。在Kubernetes中真正对应一个微服务的概念是服务(Service),每个服务会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个微服务。图2Kubernetes集群内的负载均衡在Kubernetes集群中,集群管理员管理的是一系列抽象资源,例如对应一个微服务的抽象资源就是Service;对应一个微服务实例的抽象资源就是Pod。从Service到Pod的数据转发是通过Kubernetes集群中的负载均衡器,即kube-proxy实现的。Kube-proxy是一个分布式代理服务器,在Kubernetes的每个Minion节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。Kube-proxy对应的是Service资源。每个节点的Kube-proxy都会监控Master节点针对Service的配置。当部署一个新的Service时,计入这个Service的IP是10.0.0.1,port是1234,那每个Kube-proxy都会在本地的IPTable上加上redirect规则,将所有发送到10.0.0.1:1234的数据包都REDIRECT到本地的一个随机端口,当然Kube-proxy也在这个端口监听着,然后根据一些负载均衡规则,例如roundrobin把数据转发到不同的后端Pod。可替换选择的组网方案Kube-proxy只负责把服务请求的目标替换成目标Pod的端口,并不指定如何实现从当前节点将数据包发送到指定Pod;后面如何再发送到Pod,那是Kubernetes自身的组网方案解决的。这里也体现了Kubernetes优秀的设计理念,即组网方式和负载均衡分式可以独立选择,互不依赖。Kubernetes对组网方案的要求是能够给每个Pod以内网可识别的独立IP并且可达。如果用flannel组网的话,那就是每个节点上的flannel把发向容器的数据包进行封装后,再用隧道将封装后的数据包发送到运行着目标Pod的Minion节点上。目标Minion节点再负责去掉封装,将去除封装的数据包发送到目标Pod上。云平台的多租户隔离对于一个完整的云平台,最基础的需求是多租户的隔离,我们需要考虑租户Kubernetes集群之间的隔离问题。就是我们希望把租户自己的虚拟机和容器集群可以互联互通,而不同租户之间是隔离不能通信的。使用OpenStack的多租户私有网络可以实现网络的隔离。OpenStack以前叫租户即Tenant,现在叫项目即Project;Tenant和Project是一个意思,即把独立分配管理的一组资源放在一起管理,与其他组的资源互相隔离互不影响。为了提供支持多租户的容器和虚拟机组合服务,可以把容器集群和虚拟机放到一个独立租户的私有网络中去,这样就达到了隔离作用。这种隔离有两个效果,一是不同租户之间的容器和虚拟机不能通信,二是不同租户可以重用内网IP地址,例如10.0.0.1这个IP,两个租户都可用。放在同一个私有网络中的容器和虚拟机,互相访问通过内网通信,相对于绕道公网,不仅节省公网带宽,而且可以大大提高访问性能。图3集成OpenStack和Kubernetes的多租户支持对外发布应用服务虚拟机的内网IP,Kubernetes集群节点的IP,服务的虚拟IP以及服务后端Pod的IP,这些IP在外网都是不可见的,集群外的客户端无法访问。想让外网的客户端访问虚拟机,最简单是用浮动IP;例如,一个VM有一个内网IP,我们可以给它分配一个外网浮动IP;外网连接这个浮动IP,就会转发到相应的内网固定IP上。浮动IP的模式只适用于虚拟机,不适用于Kubernetes中的服务。在OpenStack网络中,支持外网要利用nodePort和LoadBalancer结合的方式。比如这里有个服务,它的服务的虚拟IP(也叫ClusterIP)是10.0.0.1,端口是1234,那么我们知道内网的客户端就是通过这个IP和端口访问的。为了让外网访问相应的服务,Kubernetes集群中针对每个服务端口,会设置一个nodePort31234,群中的每个节点都会监听这个端口,并会在通过IPTable的REDIRECT规则,将发向这个端口的数据包,REDIRECT对应服务的虚拟IP和端口。所有发向nodePort31234这个端口的数据包,会被转发到微服务的虚拟IP和端口上去,并进一步REDIRECT到Kube-proxy对应的端口上去。再进一步,只要从外网进来的数据包,就发送到服务节点的nodePort端口上。那我们用LoadBalancer来做,LoadBalancer的前端是它的内网IP和发布端口,后端是所有内网的节点IP和nodePort。因此所有发到负载均衡器的包,会做一次负载均衡,均衡地转发到某个节点的nodePort上去,到达节点的nodePort的数据包又会转发给相应的服务。为了让外网访问,我们要给LoadBalancer绑一个外网IP,例如111.111.111.1,这样所有来自外网,发送到111.111.111.1:11234的数据包,都会转发给对应的微服务10.0.0.1:1234,并最终转发给某个随机的Pod副本。实现了以上工作,我们部署在Kubernetes集群中的服务就可以实现在OpenStack的基础平台上对外发布和访问了。图4Kubernetes微服务的对外发布基于Kuryr的组网方案Docker从1.6版本开始,将网络部分抽离出来成为Libnetwork项目,使得第三方可以以插件机制为Dockers容器开发不同网络管理方案。Libnetwork包括4种驱动类型:Null:顾名思义,就是没有网络支持。Bridge:传统的Docker0网桥机制,只适用于单主机容器之间的通信,不能支持跨主机通信。Overlay:在下层主机网络的上层,基于隧道封装机制,搭建层叠网络,实现跨主机的通信;Overlay无疑是架构最简单清晰的网络实现机制,但数据通信性能则大受影响。Remote:Remote驱动并不真正实现驱动,而是以REST服务的方式定义了与第三方网络驱动交互的机制和管理接口。第三方容器网络方案主要通过这一机制与Docker集成。说到这里,必须要提到OpenStack的容器网络管理项目Kuryr,正是一个Remote驱动的实现,集成Dockers和OpenstackNeutron网络。Kuryr英文的原意是信使的意思,本身也不是网络配置的一个具体实现,而是来自Docker用户操作意图转换为对OpenstackNeutronAPI的操作意图。具体来说,容器管理平台的操作会通过以下方式与Openstack集成:Kubernetes的网络配置管理操作(例如Kubectl命令)会由一个Kubectl操作转换成对Dockers引擎的操作;Dockers引擎的操作转换成对Libnetwork的Remote驱动的操作;对Remote驱动的操作,通过Kuryr转换成对NeutronAPI的操作;对NeutronAPI的操作,通过Neutron插件的机制转换成对具体网络方案驱动的操作。图5OpenStackKuryr调用关系示意图相对于Docker网络驱动,Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务;简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址,并使Docker容器可以互连。基于Flannel网络的组网方案在集成Kubernetes的网络方案中,基于Flannel的网络方案Kubernetes的默认实现也是配置最简单直接的。在Flannel网络中,容器的IP地址和服务节点的IP地址处于不同的网段,例如将10.1.0.0/16网段都用于容器网络,将192.168.0.0/24网段用于服务节点。每个Kubernetes服务节点上的Pod会形成一个独立子网,例如节点192.168.0.100上的容器子网为10.1.15.0/24;容器子网与服务节点的对应关系保存在Etcd上。每个服务节点都会安装flanneld程序,flanneld程序会截获所有发向容器集群网段10.1.0.0/24的数据包。对于发向容器集群网段的数据包,如果是指向其他节点对应的容器地址的,flannel会通过隧道协议封装成指向目的服务节点的数据包;如果是指向本节点对应的容器地址的,flannel将会转发给docker0。Flannel支持不同的隧道封装协议,常用的是FlannelUDP和FlannelVxLan,根据实际测试结果,VxLan封装在吞吐量和网络延时性能上都要好于UDP,因此一般推荐使用VxLan的封装方式。在Kubernetes集群中的Flannel网络非常类似于Docker网络的Overlay驱动,都是基于隧道封装的层叠网络,优势和劣势都是非常明显的。层叠网络的优势1.对底层网络依赖较少,不管底层是物理网络还是虚拟网络,对层叠网络的配置管理影响较少;2.配置简单,逻辑清晰,易于理解和学习,非常适用于开发测试等对网络性能要求不高的场景。层叠网络的劣势1.网络封装是一种传输开销,对网络性能会有影响,不适用于对网络性能要求高的生产场景;2.由于对底层网络结构缺乏了解,无法做到真正有效的流量工程控制,也会对网络性能产生影响;3.某些情况下也不能完全做到与下层网络无关,例如隧道封装会对网络的MTU限制产生影响。图6Flannel网络机制示意图基于Calico网络的组网方案与其他的SDN网络方案相比,Calico有其独特的特点,就是非层叠网络,不需要隧道封装机制,依靠现有的三层路由协议来实现软件定义网络(SDN)。Calico利用iBGP即内部网关协议来实现对数据包转发的控制。在基于隧道封装的网络方案中,网络控制器将宿主机当作隧道封装的网关,来封装来自虚拟机或容器的数据包通过第四层的传输
本文标题:基于OpenStack和Kubernetes构建组合云平台――网络集成方案综述
链接地址:https://www.777doc.com/doc-4262237 .html