云原生时代(五):Kubernetes与容器编排之战

上文我们主要介绍了容器和Docker,第五部分我们来讲Kubernetes与容器编排之战。


容器编排与Kubernetes

在单机上运行容器,无法发挥它的最大效能,只有形成集群,才能最大程度发挥容器的良好隔离、资源分配与编排管理的优势。所以企业需要一套管理系统,对Docker及容器进行更高级更灵活的管理,按照用户的意愿和整个系统的规则,完全自动化的处理好容器之间的各种关系,这叫做编排(Orchestration)。

Orchestration这个词来自于音乐领域,是指一种将不同乐器、音色加以合理的编排等手法营造出一个听感交融、平衡的艺术,它完美地描述了容器编排的含义:为单个应用程序(乐队中的每种乐器)提供协同工作的模式。

在IT领域编排可以理解为一种工作流,它能把整个IT系统都串接起来,然后自动化运作。在云原生时代,整体式的应用早已成为过去时,应用一般由单独容器化的组件即微服务组成,而这些组件需要通过相互间的协同合作,才能使既定的应用按照设计运作。

2014年6月,IT基础设施领域的领先者Google发布了Kubernetes(简写为K8S)(https://kubernetes.io)。编排概念并不是由Kubernetes第一个提出的,Kubernetes这个单词来自于希腊语,含义是舵手或领航员。

Kubernetes是基于Docker的开源容器集群管理系统,为容器化的应用提供资源调度、部署运行、服务发现、扩容缩容等整一套功能,因为容器本身可移植,所以Kubernetes容器集群能跑在私有云、公有云或者混合云上。

Kubernetes属于主从的分布式集群架构,包含Master和Nodes。Master作为控制节点,调度管理整个系统;Nodes是运行节点,负责运行应用。Pod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(Container)、存储资源(Volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。

Kubernetes的主要功能包括:

• 资源调度:资源调度是一套分布式系统最基本的核心指标

• 资源管理:控制Pod对计算资源、网络资源、存储资源的使用

• 服务发现:管理外在的程序或者内部的程序如何访问Kubernetes里面的某个Pod

• 健康检查:监控检测服务是否正常运行非常重要

• 自动伸缩:因为涉及到环境的快速迁移和复制,虚拟机时代之前都非常难实现。容器化时代很自然的解决了这个问题,Kubernetes保证了资源的按需扩容

• 更新升级:Kubernetes为服务的滚动和平滑升级提供了很好的机制


Kubernetes使用案例:滚动发布

下面我们举一个Kubernetes的应用场景,帮助大家更好的理解Kubernetes的用途。

应用程序升级面临最大挑战是新旧业务切换,将软件从测试的最后阶段带到生产环境,同时要保证系统不间断提供服务。长期以来,业务升级渐渐形成了几个发布策略:蓝绿发布、灰度发布(金丝雀发布)和滚动发布,目的是尽可能避免因发布导致的流量丢失或服务不可用问题。

在微服务架构盛行的时代,用户希望应用程序时时刻刻可用,为了满足不断变化的新业务,需要不断升级更新应用程序,有时可能需要频繁的发布版本。实现"零停机"、“零感知”的持续集成和持续交付/部署应用程序,一直都是软件升级换代必须面对的难题和追求的理想方式,也是DevOps诞生的目的。

滚动发布/滚动更新(Rolling Update Deployment)是指每次只升级一个或多个服务,升级完成后加入生产环境,不断执行这个过程,直到集群中的全部旧版本升级成为新版本。在整个滚动发布期间,保证始终有可用的副本在运行,从而平滑的发布新版本,实现零停机、用户零感知,是云原生时代非常主流的发布方式。

下图是滚动发布的流程示意图,Load Balance是前端的负载均衡器,橙色是正在运行旧版本服务的节点,紫色是正在更新及更新完毕新版本服务的节点。

滚动发布流程示意图

可以看到,滚动发布开始后(Step 2),负载均衡器将服务器A从集群里摘除,服务器A进行新版本的发布,由服务器B和服务器C对外提供版本1.0的服务;Step 3,服务器A更新完毕,部署验证成功,负载均衡器将其加入集群,开始和服务器C一起对外提供不同版本的服务,同时服务器B开始发布;直至服务器ABC全部发布完成(Step 5),服务都更新到最新的2.0版本。

滚动发布的优点是用户无感知,平滑过渡,同时不需要冗余服务器,节省资源。不足是部署时间慢,取决于每阶段的更新时间;发布策略较复杂;同时涉及自动化的更新策略、部署验证、回滚机制等等,自动化程度比较高,通常需要复杂的发布工具支撑,而Kubernetes正好可以完美的支持这个任务。

Kubernetes通用的编排模式是控制循环,用伪代码表示如下:

解释一下,Kubernetes集群本身状态就是实际状态,而期望状态来自于用户提交的配置文件。滚动发布的时候,Kubernetes将会根据这个控制循环,使用一个叫做Deployment的控制器,通过创建新的集群(下图中的v2版本ReplicaSet复制集)将其控制的Pod副本从0个逐渐变成3个,与此同时旧的集群(下图中v1版本的ReplicaSet)管理的Pod副本数则从3个逐渐变成0个,以此将一个集群中正在运行的多个Pod交替的逐一升级,实现滚动发布的效果。

如果在发布刚开始的时候,集群里只有1个新版本的Pod,这个Pod有问题启动不起来,那么滚动发布就会停止,开发和运维可以及时介入解决问题。而应用本身还有旧版本的集群和Pod在线,所以服务不会受到任何影响。关于滚动发布的详细介绍和互动教程可以阅读这里

下面这张图展示了使用Kubernetes,配合代码仓库GitLab、Docker镜像仓库Harbor、构建工具Jenkins,实现自动化的CI/CD流程。

 上一部分结束时我们提到,传统IT架构好比传统工厂,容器化好比现代化工厂,而Kubernetes则是智能化的无人工厂,让容器和应用能够高效自动、井然有序的被控制和管理;Kubernetes还实现了服务的抽象、解耦、高扩展、统一调度与集中化管理,例如用户可以专注用同样的方式在不同硬件上的应用,比如GPU节点池和低优先级的CPU节点池。Kubernetes不仅解决了容器的编排问题,让容器应用进入大规模工业生产,更进一步对云原生应用提供了定义规范,CNCF整个技术栈都是围绕Kubernetes建立,所以Kubernetes是云原生生态最重要的基石,可以说“Kubernetes是云原生时代的Linux”,即云原生应用的操作系统。

高扩展的Kubernetes:兼容不同的硬件节点
Kubernetes:云原生应用的大规模工业生产

回到本文第一部分,我们曾经用集装箱革命比喻云原生。现在大家已经理解,货船可以类比操作系统,集装箱类比容器,里面装的货物则是一个个的微服务,吊臂、吊桥、起重机等自动化操作设备是Kubernetes,而一整套集装箱的操作方法和流程则是DevOps。所有这些加起来构成了现代PaaS所具备的能力:操作系统、集群管理、应用编排、应用发布、持续集成等等。


容器编排之战

意识到容器编排的重要性,Docker在2014年发布了Docker Swarm(Swarm是蜂群的意思),以一个整体来对外提供集群管理功能,最大的亮点就是全部使用Docker项目原来的容器管理API来完成集群管理。

同时从2014年底开始,Docker收购了最先提出容器编排概念的Fig项目,并改名为Compose(Compose是作曲的意思),它可以用来组装多容器的应用,并在Swarm集群中部署分布式应用。

2014年Kubernetes发布之后,为了与Swarm竞争,在容器编排地位取得绝对的优势,Google、RedHat等开源基础设施公司共同发起了CNCF基金会,希望以Kubernetes为基础,建立一个由开源基础设施领域厂商主导、按照独立基金会方式运营的平台社区,来对抗以Docker公司为核心的容器商业生态。

一方面Kubernetes脱胎于Google内部久负盛名的大规模集群管理系统Borg,是Google在容器化基础设施领域十余年实践经验的沉淀和升华,Google利用Kubernetes的架构和设计思想成功将其所有应用(搜索、地图、视频、金融、社交、人工智能)运行在超过100万台服务器、超过80个数据中心,每周的20亿个容器上,所以Kubernetes是唯一具有超过10年以上大规模容器生产使用的技术经验和积淀的开源项目。并且Kubernetes采用了非常优雅的软件工程设计和开源开放的态度,使得用户可以根据自己的使用场景、通过灵活插拔的方式,采用自定义的网络、存储、调度、监控、日志等模块,所以在Github上的各项指标一路飙升,将较为简单、并且生态自闭的Swarm项目远远地甩在了后边。CNCF社区也迅速增加了一系列容器生态的知名工具和项目,大量的公司和初创团队将注意力投向CNCF社区而不再是Docker,CNCF本质上成为了以Kubernetes为核心的生态系统。

企业服务大厂也纷纷加入Kubernetes平台战局,在公有云或者私有PaaS平台上来发展自己的Kubernetes产品。像微软直接找来Kubernetes联合创始人Brendan Burns负责领导Azure容器服务团队,自身的混合云产品Azure Stack也大力支持Kubernetes。IBM同样也靠以Kubernetes为核心的PaaS软件IBM Cloud Private来抢占企业私有云容器平台市场,尤其是微服务的管理需求。很早就支持Kubernetes的Redhat,在2015年推出的OpenShift 3.0版中,不惜放弃自己的容器调度工具,开始支持Kubernetes,现在更成为了支持跨多云、混合云架构,以及裸机、容器和虚拟机的企业级通用应用管理平台。而虚拟化龙头VMware也改为力推主打通吃多家IaaS和Kubernetes集群管理的容器服务软件,甲骨文也在旗下云端服务支持Kubernetes。

在用户、社区和大厂的支持中,Kubernetes逐步成为企业基础架构的部署标准和新一代的应用服务层。

2016年,面对CNCF的竞争优势,Docker公司宣布放弃现有的Swarm项目,将容器编排和集群管理功能转到Docker项目当中。然而这种改变带来的技术复杂度和维护难度,给Docker项目造成了非常不利的局面。不同于Docker,Kubernetes推进的民主化架构从API到容器运行的每一层,都给开发者暴露出了可扩展的插件机制,鼓励用户通过代码的方式介入每一个阶段。Kubernetes的变革非常有效,很快在整个容器社区中催生出了大量的、基于Kubernetes API和扩展接口的二次创新产品,例如前文提到的Istio等等。Docker公司在Kubernetes社区崛起和壮大后,败下阵来。

2017年,Docker公司将容器运行时部分Containerd捐献给CNCF社区,并在自己主打产品Docker企业版中内置Kubernetes项目,持续了两年的容器编排之争终于落下帷幕,Kubernetes成为了最后的胜利者,而Docker输掉了最关键的一仗,失去了成为云原生时代操作系统的机会。

Docker在最重要的容器编排之战中失败,带给我们的教训包括:

• 开源不等于免费,开源是一种商业模式,一个开源组织和开源项目要想生存下去,最重要的基础就是普遍被使用,不然很快就会被竞争者替代

• 开源技术终将走向商业,包括Docker,必然面临企业市场的挑战

• Docker进入企业级市场,有优势也有劣势,优势是挟Docker的大量开发者,劣势是没有做过企业级市场,开发者市场和企业级市场的做法完全不同

• Docker在竞争中失利,看起来是时机和生态构建的问题,但归根结底是基因和能力问题

此系列文章的前五部分,我们详细介绍了云原生的各种理念和技术。在最后一部分,我们将展开总结和思考,分析云原生时代的机遇与挑战。

下一期内容为《云原生时代(六):机会与思考》。

参考文档:

本文的部分内容参考或者引用以下文章,在此表示感谢,如果有涉及知识产权的问题,请联系我及时修改。

一文搞懂蓝绿发布、灰度发布和滚动发布

深入剖析Kubernetes学习笔记:“控制器”模型(16)

技术专栏 | 云原生应用之路

极简Docker和Kubernetes发展史

Docker生态到底会不会重蹈Hadoop的覆辙

金丝雀发布、滚动发布、蓝绿发布到底有什么差别?关键点是什么?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章