其他
导读:本文为架构师的角色阅读,也是作者对它的理解,希望对大家有帮助。Kubernetes是什么,为什么上手这么难?Kubernetes是一个基于容器技术的分布式集群管理系统。它是谷歌在大规模应用容器技术方面数十年经验的实际成果。因此,支持大规模的集群管理承载着非常多的组件,分布式本身的复杂度非常高。Kubernetes到底有什么?接下来我们一步步来看看Kubernetes到底有什么?首先,既然是分布式系统,那么肯定有多个Node节点(物理主机或者虚拟机),它们共同构成了一个分布式集群,而这些节点之间会有一个Master节点,统一管理Node节点。如图所示:问题1:Master节点和Worker节点如何通信?首先,当Master节点启动时,会运行一个Kube-apiserver进程,它提供了集群管理的API接口,是集群中各个功能模块之间进行数据交互和通信的中心枢纽,同时也提供了一个完善的集群安全机制。在Node节点上,利用Kubernetes中的kubelet组件,每个Node节点上都会运行一个kubelet进程,负责向Master汇报本节点的运行状态,如Node节点注册、终止、定期健康报告等等,并接收来自Master的命令并创建相应的Pod。在Kubernetes中,Pod是最基本的运行单元。它与Docker容器略有不同,因为Pod中可能包含一个或多个容器(可以是Docker容器),这些容器内部共享网络资源,即可以通过localhost相互访问。关于如何在Pod中实现网络共享,每个Pod启动,内部都会启动一个pause容器(谷歌的image)。它使用默认的网络模式,其他容器的网络设置为它,完成网络共享问题。如图所示:问题2:Master如何将Pod调度到指定的Node上?这项工作由Kube-scheduler完成。整个调度过程通过执行一系列复杂的算法,最终为每个Pod计算出一个最优的目标Node,这是由Kube-scheduler进程自动完成的。最常见的是循环调度(RR)。当然也有可能我们需要将Pod调度到指定的Node上。我们可以通过将节点的标签(Label)与Pod的节点选择器属性进行匹配来达到指定的效果。如图所示:问题3:各个节点和Pod的信息统一在哪里维护,谁来维护?从上面的Pod调度来看,我们必须有一个存储中心来存储每个节点的每个Pod的资源使用情况、健康状态和基本信息,这样Pod调度才能正常进行。在Kubernetes中,etcd组件被用作高可用和一致的存储库。该组件可以内置在Kubernetes中,也可以外部构建供Kubernetes使用。集群上的所有配置信息都存储在etcd中。考虑到各个组件的相对独立性和整体的可维护性,这些存储的数据的增删改查都是统一由Kube-apiserver来调用的,并且apiserver还提供了REST支持,不仅为各个内部组件提供服务但也向集群外的用户公开服务。外部用户可以通过REST接口或kubectl命令行工具管理集群,该工具内部与apiserver通信。如图所示:问题4:外部用户如何访问集群中运行的Pod?前面我们讲了外部用户如何管理Kubernetes,但我们更关心的是内部运行的Pod如何对外访问。用过Docker的同学应该都知道,如果使用bridge模式,在创建容器的时候会分配一个虚拟IP,外部无法访问该IP。我们需要做一层端口映射,将容器中的端口映射到宿主机的端口Map并绑定,这样外部就可以通过访问宿主机的指定端口来访问容器内部的端口。那么,Kubernetes的外部访问也是这样实现的吗?答案是否定的,Kubernetes中的情况更加复杂。因为上面说的Docker是单机模式,一个容器对外暴露一个服务。在分布式集群中,服务往往由多个应用提供,以分担访问压力,而这些应用可能分布在多个节点上,这就涉及到跨主机通信。这里Kubernetes引入了Service的概念,将多个相同的Pod包装成一个完整的服务,对外提供服务。至于获取这些相同的Pod,每个Pod在启动时都会设置labels为attribute。在服务中,我们传递选择器Selector,选择与整体服务具有相同Name标签属性的Pod,将服务信息通过Apiserver存储到etcd中,由Service