在很多项目的发展初期,都是小型或者大型的单体项目,部署在单台或者多台服务器上,以单个进程的方式来运行。这些项目随着需求的递增,发布周期逐渐增长,迭代速度明显下降。传统的发布方式是:开发人员将项目打包发给运维人员,运维人员进行部署、资源分配等操作。
随着软件行业架构方式的改变,这些大型的单体应用按照业务或者其他维度逐渐被分解为可独立运行的组件,我们称之为微服务。微服务彼此之间被独立开发、部署、升级、扩容,真正实现了大型应用的解耦工作。关于微服务的介绍,大家可以去撸一下菜菜之前的文章:
程序员修神之路--为什么我会了SOA,你们还要逼我学微服务?
软件开发行业就是这样奇葩,每一个问题被解决之后总是伴随着另外的问题出现,就像程序员改bug,为什么总有改不完的bug,真的很令人头大!!!
微服务虽然解决了一些问题,但是随着微服务数量的增多,配置、管理、扩容、高可用等要求的实现变的越来越困难,包括运维团队如何更好的利用硬件资源并降低服务器成本,以及部署的自动化和故障处理等问题变得原来越棘手。
以上问题正是kubernetes要解决并且擅长的领域,它可以让开发者自主部署应用,自主控制迭代的频率,完全解放运维团队。而运维团队的工作重心从以往的服务器资源管理转移到了kubernetes的资源管理。kubernetes最厉害之处是对硬件基础设施进行了封装和抽象,使得开发人员完全不用去了解硬件的基础原理,不用去关注底层服务器。kubernetes内部把设置的服务器抽象为资源池,在部署应用的时候,它会自动给应用分配合适合理的服务器资源,并且能够保证这些应用能正常的和其他应用进行通信。一个kubernetes集群的大体结构如下:
kubernetes优势
微服务虽好,但是数量多了就会有量带来的问题。随着系统组件的不断增长,这些组件的管理问题逐渐浮出水面。首先我们要明白kubernetes是一个软件系统,它依赖于linux容器的特性来管理组件(kubernetes和容器并非一个概念,请不要混淆)。通过kubernetes部署应用程序时候,你的集群无论包含多少个节点,对于kubernetes来说不会有什么差异,这完全得益于它对底层基础设置的抽象,使得数个节点运行的时候表现的好像一个节点一样。自动扩容
在kubernetes系统中,它可以对每个应用进行实时的监控,并能根据策略来应对突发的流量做出反应。例如:在流量高峰期间,kubernetes可以根据各个节点的资源利用情况,进行自动的增加节点或者减少节点操作,这在以前的传统应用部署方式中是不容易做到的。
简化部署流程
以往的传统应用发布的时候,需要开发人员把项目打包,并检查项目的配置文件是否正确,然后发给运维人员,运维人员然后把线上的应用版本备份,然后停止服务进行更新。在kubernetes中,我们多数情况下只需要一条指令或者点击一个按钮,就可以把应用升级到最新版本,而且升级的过程中还可做做到不间断服务。当然整个的流程还涉及到容器的操作,本次这里不再做过多介绍。
但是这里有一个意外情况,如果kubernetes集群中存在不同架构CPU的服务器,而你的应用程序是针对特定CPU架构的软件,可能需要在kubernetes中指定节点去运行你的应用程
提高服务器资源的利用率
传统应用部署的时候,多数情况下总会把资源留有一定的比例来作为资源的缓冲,来应对流量的峰值,很少有人把单个服务器资源利用率提高到90%以上,从服务器故障的概率来说,服务器资源使用率在90%要比50%高很多,而且服务器一旦出现故障,都是运维人员来解决问题和背锅,所以传统的物理机或者虚拟机部署应用的方式,硬件的资源利用率相比较来说是比较低的。
而kubernetes对集群的管理由于抽象了底层硬件设施,所以已经将应用程序和基础设施分离开来。当你告诉kubernetes运行你 应用程序时,它会根据程序的资源需求和集群内每隔节点的可用资源情况选择合适的节点来运行。而且通过容器的技术,可以让应用程序在任何时间迁移到集群中的任何机器上。而对于服务器选择的最优的组合,kubernetes比人工做的更好,它会根据集群中每台服务器的负载情况来把硬件利用率提高到最高。
自动修复
在传统的应用架构中,如果一台服务器发生故障,那么这台服务器上的应用将会全部down掉,多数情况下需要运维人员去处理,这也是为什么运维人员需要7*24小时随时待命的一个重要原因。相信你也曾看到过因为半夜故障运维人员骂娘的情景。在kubernetes中,它监视并管理着所有的节点和应用,在节点出现故障的时候,kubernetes可以自动将该节点上的应用迁移到其他健康节点,并将故障节点在资源池中排除。如果你的kubernetes集群基础设施有足够的备用资源来支撑系统的正常运行,运维人员完全可以拖延到正常的工作时间再处理故障,让程序员和运维人员过一下965的工作节奏。
这点有点像Actor模型的设计理论,提倡的是任其崩溃原理。一致的运行环境
无论你是开发还是运维人员,在传统的部署方案中,总会有运行环境差异性的烦恼,这样的差异性大到每个服务器的差异,小到开发环境、仿真环境、生产环境,而且每个环境的服务器都会随着时间的推移而变化。我相信你一定遇到过开发环境程序运行正常,生产环境却异常的情况。这种差异性不仅仅是因为生产环境由运维团队管理,开发环境由开发者管理,更重要的这两组人对系统的要求是不同的,运维团队会对线上生产环境定时的打补丁,做安全监测等操作,而开发者可能根本就不会吊这些问题。除此之外,应用系统依赖的第三方库可能在开发、仿真、生产环境中版本不同,这样的问题反正我是遇到过。
而kubernetes采用的容器技术,在把应用打包的时候,运行环境也一起被打入包中,这就保证了相同版本的容器包(镜像)在任何服务器上都有相同的运行环境