tanzhe0 2020-01-13
你可能经常在公司听说Kubernetes,这项源自于Google的容器编排技术现在非常火,似乎不论是Devops还是CTO,不论他们是否完全理解这项技术,他们都在谈论它。读了这篇文章可能会使您更加困惑,有可能您无法完全理解。有人寄希望于Kubernetes可以帮助他解决所有问题,但是事实并非如此。在这篇文章中,我会重点介绍几个关键因素,来帮助您决定是否采用Kubernetes以及采用到何种程度。我还将为您提供一个方法对Kubernetes进行一步步的评估并逐步引入到您的组织之中, Kubernetes是一项伟大的技术,如果使用得当,它会带来很大益处。
> 过去服务就像宠物一样,需要管理员一个个管理维护,现在服务器更像是羊群,管理员通过简单的命令或者配置就可以管理大量的服务器。
曾几何时,系统管理员用主机名和便签来管理服务器,如今,我们并不知道我们的工作负载运行在哪种类型的服务器上,因为这些本来应该躺在机房以及数据中心的机器已经让位给像是 亚马逊,微软以及谷歌这些公有云提供商了。系统管理员的确像以前一样为运行在公共云上的虚拟机命名,就像他们养宠物一样。但在过去如果销售人员需要服务器时,系统管理员可能需要花费数周的时间,然后通过电话或电子邮件与销售人员交谈以进行配置。但是随着高性能虚拟化和公有云API的出现,一个简单的API调用可以在几秒钟内启动机器。聪明的技术人员意识到公有云不仅提供了对计算的快速访问,而且还能通过提供易用的RESTful API来提供了自动化的能力。这真是太美好了。
随着Chef, Puppet, Ansible以及SaltStack技术的出现,开发和运维之简的界限越来越模糊。以前系统管理员很少冒险使用除了Shell脚本之外的语言,而Chef,Puppet以及Ansible都是发展成熟的系统编排框架。Puppet使用了特定于域的语言(DSL: Domain Specified Language)来让系统管理员定义其基础架构设置的最终状态,而Chef使用的是基于Ruby语言的DSL,可以充分发挥Ruby语言的表达能力来定义基础架构的最终状态。这些技术使我们直接进入声明式以及命令式架构的时代,我们可以通过文件中的代码来定义服务器基础架构的最终状态,因此可以像管理源代码一样对架构进行版本控制。这和手动设置服务器并登入安装各种软件,设置硬件资源(如网络,存储等)非常不同,尽管管理员可能会运行一些脚本使这个过程更加高效,但是现在,使用Chef以及Puppet可以集中化管理系统配置,并且通过他们功能强大的API,可以轻松的管理大量服务器。
Docker并不是一项容器技术,它是一个强大的利用linux原始特性来轻松管理和组合容器的工具,Linux容器是使用Linux的操作系统的原始特性(CGroups即Control Groups和Namespaces)来构建的。Docker只是使构建和管理容器变得容易。使用Docker,可以轻松的打包应用程序及其所有依赖关系。就像一个真正的容器一样,“运送”变得十分容易。之后这个容器可以运行在任意Linux机器之上,而不用预先安装其依赖项(其中一些可能是特定的Linux发行版)。通过容器技术,我们可以运行来自Debian Linux的Nginx,以及来自Ubuntu的Python Flask框架,与此同时,还可以运行来自 Alpine的MySQL, 这些软件一起构成了用户的应用,所有这些软件包都在同一Linux服务器上运行。总而言之,Docker,提供了声明式构建容器的标准,并提供了在Linux服务器上运行和管理容器的生命周期的工具,成功驾驭了Linux的容器技术并且提供了巨大的便利。
尽管 Puppet和Chef擅长管理物理机和虚拟机的配置,Devops更喜欢用容器来部署应用,容器很快成为了标准,并且容器可以包含很多应用部署的逻辑,从而使业务流程的其余部分变得更加简单,是时候使用一种更现代的以容器为中心的编排系统了。
与此同时,另一种快速发展的方法使得运维人员越来越深入到开发者的领域之中,Devops,工程师发现,运维人员希望系统稳定,而开发人员希望随时发布新的功能,这给稳定性的带来了巨大的挑战。这两个目标相互矛盾,致使团队互相争执,直接影响了产品的交付速度。并且开发团队的人员在没有意识到他们的代码会在生产环境中引起何种问题之前,他们是不会花费力气去修复它的。因为生产环境通常是由运维团队来处理的。为了解决这些问题。团队开始尝试一种新的方法:Devops,这个方法很简单,谁写代码,谁负责发布到生产环境。同时也将负责之后的值班。如果开发人员想要更加频繁的发布新功能,那么他们需要了解作为运维人员需要做哪些事情来支持发布。云和容器技术以及其强大的API和工具链,使得这种方式可以被并入云操作中。快速发展的DevOps团队会构建由微服务组成的大型应用程序,每个微服务都可以独立开发和发布,而无需测试和发布整个大型应用程序。尝试DevOps的团队会使用微服务架构,他们喜欢云和容器的可塑性和灵活性,程序员可以通过可编写脚本的工具和API轻松控制。
当Devops和微服务遇到了容器,一个新的,原生的编排框架应运而生,受Google Borg系统的启发,Kubernetes是一个开源容器编排系统,最初由Google的工程师构建,现在由CNCF(Cloud Native Computing Foundation,云原生计算基金会)维护。作为容器编排平台,Kubernetes可以实现自动化应用程序部署,扩展和管理。尽管像Docker这样的系统也可以管理服务器中的容器,但Kubernetes的功能更强大,其主要功能之一是可以管理运行容器的服务器或节点的集群。与此类似的框架有Apache Mesos和Docker Swarm。但到目前为止,显然,Kubernetes已经成为赢家。现在,选择Kubernetes作为容器编排框架是一个非常安全的选择。
4.1不仅仅是Docker
值得注意的是,Kubernetes可以编排不仅由Docker管理的容器。它还可以编排由类似于Docker的系统管理的容器,例如ContainerD,Cri-O和RktLet。尽管您可以创建和管理这些系统的容器,但在本文中,我们将用“ Docker”来指代“容器管理”。现在,让我们看一下Kubernetes的一些最重要的功能。
4.2 为什么选择Kubernetes
要想知道为什么Kubernets如此重要,首先要了解Docker的边界在哪,尽管Docker可以轻松管理一个服务器内容器的生命周期,但是Kubernets可以轻松管理多个运行Docker容器的服务器(即集群)。另一方面,现在,微服务应用常常由几个容器构成,Kubernets提供了“应用程序部署”这个概念,指的是组成应用程序的一组容器,在集群上以分布式方式运行。当您要运行由一组容器组成的应用程序时,只需告诉Kubernetes,它便可以找出集群中的哪些节点具有足够的计算资源来运行容器,并在其中调度它们。Kubernetes会在容器出现故障时重启容器,甚至可以根据某些参数来扩展你的应用,如增加容器的数量以应对激增流量。这就是Kubernetes的本质,这也就是人们所谈论的“容器编排”。
在集群上运行多个应用时,Kubernets还提供了其他的功能来简化管理,它使管理应用程序的配置和证书变得更加容易,Kubernetes还管理其他基础架构,例如存储和网络,计算,这是构成任何基础架构的最基本三个组成部分。
4.3 是否托管
尽管你可以在私有云上从头开始搭建Kubernetes,但在扩展kubernetes基础架构之前您最好还是选择OpenShift的Kubernetes发行版,它提供付费支持。当然,您也可以选择在AWS,Azure或GCP的集群上搭建Kubernetes。Kubernetes是由多个组件构成,这些组件一起运行一个集群(称为计算节点),每个计算节点也会运行Kubernetes。当您选择任何公有云提供的托管Kubernetes产品时,您可以选择他们提供的任何类型的计算节点来组成Kubernets集群,这些可以用于容器部署,但是Kubernetes的主要主组件(也称为“控制平面”)是由云服务提供商管理。
这取决一系列因素。
5.1 公有云还是私有云
Kubernetes可以部署在公有云和私有云上。在私有云上,虽然理论上您可以自己安装和维护Kubernetes,但最好是运行诸如OpenShift之类提供的Kubernetes发行版,该发行版可以获得供应商技术支持。 Kubernetes诞生于云中,是一种所谓的“云原生”技术,它是管理计算集群的绝佳选择。实际上,Kubernetes也是管理私有云的绝佳选择。
对于像是AWS,Azure以及GCP这类公有云,你可以在一组计算节点上运行Kubernetes,例如,你可以使用Kops(一种流行的解决方案)在AWS的EC2实例上部署Kubernetes,但是,我强烈建议您选择使用托管的Kubernetes产品,从而将维护Kubernetes控制平面的工作移交给云服务提供商,以便您可以专注于如何在Kubernetes上运行工作负载。
5.2 您项目中目前对Docker的采用程度如何?
Kubernets并不是入门级产品,它是一个容器编排平台。如果您准备运行在Kubernets的应用还没有容器化,您首先必须确保这些应用程序已在生产中的Docker上经过了良好的测试。稍后,我们将提出一个简单的策略,说明如何逐步实施这个步骤。 Docker已被广泛采用,工具已经非常成熟,可以肯定地说,Docker已经远远超出了炒作阶段。无论您的组织有多么“谨慎”的IT策略,采用Docker是没有太大风险的。如果将Docker与Kubernetes以合适的方式结合,可以真正提高服务器利用率。因此,这件事值得考虑。
5.3 组织中的DevOps文化有多成熟?
一个强大的Devops文化意味着开发者需要负责在生产环境中运行他们开发的服务,他们会始终寻找一些自动化操作来提高他们的生产力。尤其是当应用或者服务是以微服务的架构为基础,意味着不同的团队需要独立运行不同的微服务,Kubernetes非常适合这种情况,并且能很快被内部采用。不过另一方面,Kubernetes也可以很好的运行单体的工作负载。这里的关键点在于,如果有两个独立的团队,开发和运维,如果运维团队以一种全新的部署方式工作,然后让开发团队努力适应一种用于容器化和应用程序配置的构建系统,那么两个团队可能都不会付出太大的努力来促成这件事。
5.4 组织中是否有足够的了解Kubernetes的员工
Kubernetes需要花费一定的时间去学习,而且只有当你学习了容器化之后再去学Kubernetes才有意义。如果您确信Kubernetes适合您的组织并且已经考虑了以上列出的几个要点,那么您可能需要几个有能力和信心在生产中使用Kubernetes的拥护者,如果您的组织中只有刚接触Kubernetes的人员,我们会提供一条路径帮助你们积累经验,与此同时,降低再生产中使用Kubernetes的风险。稍后我将介绍如何实现。
如果有人将Kubernetes称为灵丹妙药,那么他们可能还停留在初级阶段。这是您需要注意的一些事情。
6.1 托管的Kubernetes不是万能药
Kubernetes是一个由许多协同工作的软件组成的系统。无论您是直接管理它还是选择托管Kubernetes,都可能遇到问题。就算是托管的Kubernetes,它的各个组成部分也可能出现问题。不要仅仅因为Kubernetes控制平面是由您的云服务提供商管理的,就觉得它不会出错。您可以在Github上找到几个特定于云提供商的Kubernetes问题。当出现问题时,您可能仍需要联系支持人员并进行处理。这可能涉及停机时间。因为控制平面中的Kubernetes组件仅创建和监视容器,所以如果它们出现故障,它们通常不会影响已经在运行的容器。但是,控制平面出问题可能会影响您创建新容器以及自动调整容器数量等操作。
6.2 Kubernetes上的有状态应用仍在不断发展
Kubernetes适用于创建和销毁(短期存在)容器的应用。为了应对流量激增,可以临时创建很多容器,一旦情况恢复正常,这些容器将被终止。跟后台作业运行器一样。这意味着它将是一个非常动态的环境,服务器被当做一个整体而不是个体。这意味着,像数据库这样有状态的应用似乎没有被考虑到。实际上,数据库这块领域的开发一直非常活跃,现在这个功能也比较稳定了。不过Kubernetes的有状态的应用的功能仍在快速变化中。
Kuberntes本身就支持在有状态的应用中使用持久卷,当然你可以以云提供商的方式来分配持久卷给有状态的应用。
如果您想使用由基础云提供商管理的有状态服务(例如RDS,DynamoDB等),您需要使用Kubernetes的服务目录(Service Catalog,),那么kubernetes就可以消费云提供商托管的服务。
6.3 Kubernetes升级
您可能会害怕Kubernetes集群升级会带来严重的后果,导致您更希望维持现有的集群设置。那么最好的方法可能是使用和生产集群相同版本的Kubernetes和配置来创建一个新集群,安装所有关键应用程序并升级该集群,检查一切是否正常,如果正常,再升级生产中的集群。如果您对Kubernetes及其带来的好处持认真态度,那么集群升级是您无法避免的的。因此,计划并执行是最好的解决办法。
6.4 许多灵活的部件
说到虚拟化技术,这已经是我们习以为常的抽象化技术了。实际上,当某人引用“计算机”或“服务器”时,他们很可能指的是虚拟机。对于应用来说,Kubernetes很有可能成为新的标准底层。一个新的抽象级别,成为新的常态。对于虚拟机而言,由于大多数大型系统都采用Linux的KVM技术进行标准化,因此它是操作系统层的组成部分,尽管还涉及其他组件,但是它们是相当底层的。它与Kubernetes截然不同,Kubernetes上有十几个服务在不同机器之间相互通信,在计算,存储,网络和自动扩展方面进行相当复杂的操作。
当问题出现时,您可能不得不袖手旁观。我们只能在某种程度上假设Kubernetes使用的这些组件的所有不同版本在某种程度上是相互协调的。至少云服务提供商希望我们相信这一点。
6.5 保留Kubernetes人才
如果您希望采用Kubernetes,但是只有一个人在后面支撑你,您将独自承担风险。虽然Kubernetes在您的项目中证明了自己的价值,但正如我们将要看到的,让整个DevOps团队接受Kubernetes的培训或者自学。毕竟,谁都想接受一次培训的机会,来研究一项炙手可热的技术?另一方面,您需要一群熟悉Kubernetes的DevOps团队而不是一两个人,以便在未来也能保持Kubernetes执行的连续性。相信我,随着Kubernetes在LinkedIn页面上被列为一项技能,人们很容易跳槽,不能只依赖一两个人来执行这项任务。
7.将Kubernetes引入您的组织
至此,如果您确信可以从在组织中部署Kubernetes受益,您可以按照以下步骤,让您的团队逐步了解Kubernetes以及采用它来管理生产工作负载。
您需要DevOps团队里具有Kubernetes知识和实操能力的人员来执行您的计划。鉴于官网提供了高质量的培训材料,他们可以自学,也可以通过更正式的培训计划。您应该咨询您的云提供商,看他们是否可以为您的组织专门培训,或者他们有什么培训可以让您的团队参加。在您所在的地区可能还有其他付费选择。
雇用Kubernetes人才是另一种选择。寻找使用过Kubernetes来运行生产工作负载的人员。雇用他们时,您可能需要跟他们讨论之前投入生产的方式以及在Kubernetes上运行生产工作负载时面临的挑战。询问他们是否运行任何有状态的工作负载。通过这些讨论,您应该能够确定他们是否适合您的项目。
7.2将工作负载迁移到Docker
首先您需要将您的工作负载迁移至Docker,然后再从Dodcker迁移至kubernetes,如果您的应用程序没有运行在docker上,而您想要直接迁移到Kubernetes,那么遇到问题时,您将无法准确指出是由构建时,运行时或配置问题引起的。另一方面,如果您的团队花时间在容器化工作负载,并在生产环境中使用Docker运行它们,你遇到的问题,需要考虑的问题就会变少了。
7.3 在Kubernetes上运行非生产的工作负载
现在您的工作负载已被容器化,您可以将一些非生产型工作负载(例如开发和临时的工作负载)迁移到Kubernetes。这样,您的大型团队可以先适应新环境,将Kubernetes集成到您的持续部署管道中,等等。
7.4 把无状态工作负载的迁移放在前面
在将生产工作负载转移到Kubernetes时,可以从无状态工作负载开始:无状态的工作负载指的是只提供请求服务但不直接保留任何数据的容器。在Kubernetes上运行有状态工作负载需要更深的Kubernetes专业知识。对于有状态的工作负载,您需要做一些更仔细的计划,以了解在节点发生故障时如何管理。例如,对于像Elasticsearch这样的分布式有状态应用程序,这将尤其复杂。
7.5 迁移非关键性工作负载
一开始只将非关键工作负载转移到Kubernetes上,并让您的团队在上运行生产工作负载以积累相关经验。例如,在生产中运行工作负载需要的监控,警报和应用程序升级等。
7.6 大飞跃
从以上步骤我们看到了如何以一种既可以建立专业知识又可以降低风险的方式在组织中采用Kubernetes。我们还从工程角度讨论了如何做好准备以进行容器化并将生产工作负载缓慢引入Kubernetes。您只需要判断何时是最佳时机。每个组织的采用率与风险率都不相同,因此您应该做出最佳判断。我的建议是您使用Terraform之类的工具来自动化Kubernetes集群本身的部署。
最好的计划总是会考虑最差的情况,这就是本文的主要思想:告诉您潜在的问题以及如何减轻采用Kubernetes风险。 Kubernetes是伟大的技术。在很多方面,它肯定会为您提供帮助。但是,与打算使用生产工作负载的任何技术一样,您将需要权衡风险,看看收益是否大于风险。查看Kubernetes的失败案例对于找出最常见的问题以及如何解决这些问题很有用。