容器的来临
要部署一个软件,您不只须要软件自己,还须要其依赖性。这意味着库,解释器,子包,编译器,扩展等。您还须要其配置。设置,站点特定的详细信息,许可证密钥,数据库密码:将原始软件转换为可用服务的全部内容。最早进的解决此问题的早期尝试包括使用配置管理系统,例如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”)。这是一个很是有前途的项目,这可能意味着未来容器和功能之间的区别可能会模糊或消失。