容器的来临
要部署一个软件,您不仅需要软件本身,还需要其依赖性。这意味着库,解释器,子包,编译器,扩展等。您还需要其配置。设置,站点特定的详细信息,许可证密钥,数据库密码:将原始软件转换为可用服务的所有内容。最先进的解决此问题的早期尝试包括使用配置管理系统,例如Puppet或Ansible,其中包含用于安装,运行,配置和更新运输软件的代码。 或者,有些语言提供了自己的打包机制,如Java的JAR文件,Python等或Ruby的gems。但是,这些是特定于语言的,并不能完全解决依赖性问题:例如,在运行JAR文件之前,仍需要安装Java运行时。
另一种解决方案是omnibus软件包,顾名思义,它试图将应用程序所需的所有内容塞入单个文件中。 omnibus软件包包含软件,其配置,相关软件组件,其配置,依赖关系等。 (例如,Java omnibus包将包含Java运行时以及应用程序的所有JAR文件。)一些供应商甚至更进一步,包括运行它所需的整个计算机系统,作为虚拟机映像,但这些是庞大而笨拙的,构建和维护耗时,操作易碎,下载和部署速度慢,并且在性能和资源足迹方面效率极低。从操作的角度来看,您不仅需要管理这些不同类型的软件包,还需要管理一组服务器来运行它们。服务器需要进行配置,联网,部署,配置,保持最新的安全补丁,监控,管理等。
这一切都需要大量的时间,技能和精力,只需提供一个运行软件的平台。有没有更好的方法?在盒子里面思考为解决这些问题,科技行业借鉴了航运业的一个想法:集装箱。在20世纪50年代,一位名叫马尔科姆·麦克莱恩的卡车司机提出,不是费力地将货物单独地从卡车拖车上卸下来,而是将货物运到港口并装上船只,卡车本身就可以装上船 - 或者更确切地说,卡车车身。
卡车拖车本质上是车轮上的大金属箱。如果您可以将箱子 - 容器 - 与用于运输它的轮子和底盘分开,那么您可以很容易地抬起,装载,堆叠和卸载,并且可以直接进入另一艘船上或另一辆卡车上。航程结束(1-3)。
放入软件至容器
软件容器的概念完全相同:标准的包装和分发格式,通用且广泛,可大大提高承载能力,降低成本,实现规模经济,易于处理。容器格式包含应用程序运行所需的所有内容,并将其烘焙到可由容器运行时执行的映像文件中。这与虚拟机映像有何不同?这也包含应用程序需要运行的所有内容 - 但除此之外还有很多内容。典型的虚拟机映像大约为1 GiB.1另一方面,精心设计的容器映像可能要小一百倍。
由于虚拟机包含许多不相关的程序,库以及应用程序永远不会使用的东西,因此大部分空间都被浪费了。通过网络传输VM映像远比优化容器慢。更糟糕的是,虚拟机是虚拟的:底层物理CPU有效地实现了虚拟机运行的模拟CPU。虚拟化层对性能产生了巨大的负面影响:在测试中,虚拟化工作负载比同等容器慢约30%。
相比之下,容器直接在真实CPU上运行,没有虚拟化开销,就像普通的二进制可执行文件一样。而且因为容器只保存他们需要的文件,所以它们比VM图像小得多。他们还使用了一种聪明的可寻址文件系统层技术,可以在容器之间共享和重用。
例如,如果你有两个容器,每个容器都来自相同的Debian Linux基础映像,那么基本映像只需要下载一次,每个容器都可以简单地引用它。容器运行时将汇集所有必需的层,如果尚未在本地缓存,则只下载一个层。这样可以非常有效地利用磁盘空间和网络带宽。
即插即用应用程序
容器不仅是部署单位和包装单位; 它也是重用的单元(相同的容器映像可以用作许多不同服务的组件),扩展单元和资源分配单元(容器可以在任何可用于其自身特定需求的足够资源的情况下运行)。
开发人员不再需要担心维护不同版本的软件以在不同的Linux发行版上运行,针对不同的库和语言版本,等等。 容器唯一依赖的是操作系统内核(例如Linux)。只需在容器映像中提供应用程序,它就可以在任何支持标准容器格式并具有兼容内核的平台上运行。
Kubernetes开发人员Brendan Burns和David Oppenheimer在他们的论文“基于容器的分布式系统的设计模式”中采用了这种方式:
通过密封,携带它们的依赖关系,并提供原子部署信号(“成功”/“失败”),[容器]显着改进了在数据中心或云中部署软件的先前技术水平。 但容器有可能不仅仅是一个更好的部署工具 - 我们相信它们注定会变得类似于面向对象软件系统中的对象,因此将能够开发分布式系统设计模式。带宽。
容器管弦乐队
运营团队也发现容器大大简化了他们的工作量。他们所要做的就是运行一个容器协调器,而不是必须维护各种机器,体系结构和操作系统的庞大空间,这是一个旨在将许多不同机器连接到一个集群中的软件:一种统一的计算基板,在用户看来是一个非常强大的计算机,容器可以在其上运行。
术语编排和调度通常作为同义词松散地使用。但是,严格地说,在这种情况下,编排意味着协调和排序不同的活动以服务于共同目标(如管弦乐队中的音乐家)。调度意味着管理可用资源并分配可以最有效地运行的工作负载。 (不要与在预设时间执行的预定作业意义上的计划混淆。)
第三个重要的活动是集群管理:将多个物理或虚拟服务器连接成一个统一,可靠,容错,明显无缝的组。术语容器协调器通常指的是负责调度,编排和集群管理的单个服务。
集装箱化(使用容器作为部署和运行软件的标准方法)提供明显的优势,事实上的标准容器格式使各种规模经济成为可能。但是容器的广泛采用仍然存在一个问题:缺乏标准的容器编排系统。
只要用于调度和编排容器的几种不同工具在市场上竞争,企业就不愿意对使用哪种技术进行昂贵的投注。但所有这一切都将改变。
Kubernetes
谷歌长期以来一直在为生产工作负载运行容器。 几乎所有Google服务都以容器形式运行:Gmail,Google搜索,Google地图,Google App Engine等。 由于当时没有合适的容器编排系统,谷歌被迫发明一个。 从博格到Kubernetes
为了解决在数百万台服务器上全球范围内运行大量服务的问题,Google开发了一个名为Borg的私有内部容器编排系统。Borg本质上是一个集中管理系统,它分配和调度容器以在服务器池上运行。虽然非常强大,但博格与谷歌自己的内部和专有技术紧密相连,难以扩展,不可能向公众发布。
2014年,Google根据从博格及其继任者欧米茄获得的经验教训,创建了一个名为Kubernetes的开源项目(来自希腊语,意思是“舵手,飞行员”),该项目将开发一个每个人都可以使用的容器协调器。Kubernetes的崛起是昙花一现。虽然其他容器编排系统在Kubernetes之前就已存在,但它们是与供应商相关的商业产品,这一直是其广泛采用的障碍。随着真正的免费和开源容器协调器的出现,容器和Kubernetes的采用开始以惊人的速度增长。
到2017年底,管弦乐队战争结束了,Kubernetes赢了。虽然其他系统仍在使用,但从现在开始,希望将基础设施转移到容器的公司只需要针对一个平台:Kubernetes。
是什么让Kubernetes如此宝贵?
Kelsey Hightower是Google的员工开发人员,Kubernetes Up&Running(O'Reilly)的合着者,以及Kubernetes社区的全能传奇人物,他这样做:Kubernetes完成了最好的系统管理员所做的事情:自动化,故障转移,集中式日志记录,监控。它需要我们在DevOps社区中学到的东西,并使其成为默认的,开箱即用。
凯尔西海托尔许多传统的系统管理员任务(如升级服务器,安装安全补丁,配置网络和运行备份)都不是云本地世界关注的问题。 Kubernetes可以为您自动执行这些操作,以便您的团队可以集中精力完成其核心工作。
其中一些功能(如负载平衡和自动扩展)内置于Kubernetes核心中;其他由附加组件,扩展程序和使用Kubernetes API的第三方工具提供。 Kubernetes生态系统很大,并且一直在增长。
Kubernetes让部署变得简单
由于这些原因,Ops工作人员喜欢Kubernetes,但开发人员也有一些显着的优势。 Kubernetes大大减少了部署所需的时间和精力。零停机部署很常见,因为Kubernetes默认会进行滚动更新(使用新版本启动容器,等待它们变得健康,然后关闭旧版本)。
Kubernetes还提供了一些工具来帮助您实施持续部署实践,例如canary部署:逐个推出一个服务器的更新,以便及早发现问题(请参阅“Canary Deployments”)。另一种常见的做法是蓝绿色部署:并行启动新版本的系统,并在流量完全启动并运行后将流量切换到它(请参阅“蓝/绿部署”)。
需求高峰将不再降低您的服务,因为Kubernetes支持自动缩放。例如,如果容器的CPU利用率达到一定水平,Kubernetes可以继续添加容器的新副本,直到利用率低于阈值。当需求下降时,Kubernetes将再次缩减副本,释放群集容量以运行其他工作负载。
由于Kubernetes内置了冗余和故障转移功能,因此您的应用程序将更加可靠和灵活。一些托管服务甚至可以根据需求上下调整Kubernetes集群本身,这样您就不会为任何特定时刻所需的集群付费(参见“自动调节”)。
该公司也会喜欢Kubernetes,因为它可以降低基础设施成本并更好地利用一组资源。传统服务器,甚至是云服务器,大多数时候都处于空闲状态。处理需求高峰所需的过剩产能在正常情况下基本上被浪费了。
Kubernetes利用浪费的容量并使用它来运行工作负载,因此您可以实现更高的机器利用率 - 并且您也可以免费获得扩展,负载平衡和故障转移。虽然其中一些功能(如自动扩展)在Kubernetes之前可用,但它们始终与特定的云提供商或服务相关联。 Kubernetes与提供程序无关:一旦定义了您使用的资源,就可以在任何Kubernetes集群上运行它们,而不管底层云提供程序如何。
这并不意味着Kubernetes将你限制在最低的标准。 Kubernetes将您的资源映射到适当的供应商特定功能:例如,Google Cloud上的负载均衡,Kubernetes服务将创建Google Cloud负载均衡器,在Amazon上它将创建AWS负载平衡
正如容器是一种定义软件的可移植方式一样,Kubernetes资源提供了该软件应如何运行的可移植定义。
Kubernetes会消失吗?
奇怪的是,尽管Kubernetes目前令人兴奋,但在未来几年我们可能不会谈论它。曾经是新的和革命性的许多东西现在都是计算结构的一部分,我们并没有真正考虑它们:微处理器,鼠标,互联网。
Kubernetes也可能会消失并成为管道的一部分。这很无聊:一旦你了解了将你的应用程序部署到Kubernetes需要了解的内容,你或多或少都会完成。Kubernetes的未来很可能主要在于托管服务领域。虚拟化曾经是一项令人兴奋的新技术,现在已经成为一种实用工具。大多数人从云提供商处租用虚拟机,而不是运行自己的虚拟化平台,例如vSphere或Hyper-V。
同样地,我们认为Kubernetes将成为管道的标准部分,你不会再知道它了。Kubernetes并不是全部,未来的基础设施是否完全基于Kubernetes?可能不是。首先,有些东西不适合 Kubernetes(例如数据库):在容器中编排软件涉及启动新的可互换实例,而无需在它们之间进行协调。但数据库副本不可互换;它们每个都具有唯一的状态,部署数据库副本需要与其他节点协调,以确保模式更改等同时发生在任何地方:Sean Loiselle(蟑螂实验室)
尽管在Kubernetes中运行具有企业级可靠性的数据库等状态工作负载是完全可能的,但它需要大量的时间和工程投入,这对您的公司来说可能没有意义(参见“运行较少的软件”)。相反,使用托管服务通常更具成本效益。其次,有些东西实际上并不需要Kubernetes,并且可以运行在有时称为无服务器平台,更好的命名功能即服务或FaaS平台上。
云功能和全功能
例如,AWS Lambda是一个FaaS平台,允许您运行用Go,Python,Java,Node.js,C#和其他语言编写的代码,而无需编译或部署应用程序。亚马逊为您做到了这一切。因为您需要以100毫秒的增量为执行时间付费,所以FaaS模型非常适合仅在您需要时运行的计算,而不是支付云服务器,无论您是否正在使用它,它都会一直运行或不。在某些方面,这些云功能比容器更方便(尽管一些FaaS平台也可以运行容器)。但它们最适合于简短的独立作业(例如AWS Lambda将功能限制为运行时间的15分钟,以及大约50 MiB的已部署文件),尤其是那些与现有云计算服务集成的服务,例如Microsoft Cognitive Services或Google Cloud Vision API。
为什么我们不喜欢将此模型称为无服务器?嗯,它不是:它只是别人的服务器。关键是您不必配置和维护该服务器;云提供商会为您处理。
并非所有工作负载都适合在FaaS平台上运行,但它仍然可能成为未来云原生应用程序的关键技术。云功能也不限于Lambda或Azure功能等公共FaaS平台:如果您已经拥有Kubernetes集群并希望在其上运行FaaS应用程序,OpenFaaS和其他开源项目就可以实现这一点。这种功能和容器的混合有时被称为funtainers,我们觉得这个名字很有吸引力。
Kubernetes的一个更复杂的软件交付平台,包括容器和云功能,称为Knative,目前正在积极开发中(参见“Knative”)。这是一个非常有前途的项目,这可能意味着将来容器和功能之间的区别可能会模糊或消失。