云原生漫游指南(2)丨从CI&CD到计算存储分离
之前在《云原生漫游指南(1)丨先从构建一个容器起步》中,我们详细介绍了企业在云原生转型路径中必经的前两个站点:容器化、镜像&运行时,即将应用开发的产出物构建成容器镜像,并存放和运行镜像。有人可能会问,这一过程中有什么提升效率的方式吗?   答案是肯定的,本文就将从解决这个问题开始,继续介绍云原生路径中接下来的几个关键站点。

第三站 

CI&CD:自动化构建与部署

 

容器化过程细粒度拆分了应用的部署单元,因此开发者可以更加频繁和便捷地对每个容器版本进行变更以支持敏捷研发。 但如果每次变更都需要手工构建镜像并将新版本部署到运行时,显然会大大影响效率。所以云原生中非常重要的一环,就是实现自动化的容器镜像集成和部署,也就是我们常常听到的 CI&CD(Continuous Integration, Delivery & Deployment)。   实现容器CI&CD的工具很多,如业内最流行的开源CI&CD工具Jenkins,就为容器构建和部署提供了丰富的插件支持。 利用这些CI&CD工具,开发者不仅可以实现自动化的镜像构建和部署,还能在这个过程中插入一些更为复杂的逻辑,以满足不同场景的业务需求,其中最为常见的就是灰度发布。 灰度发布意味着每次部署新版本镜像时,承载业务的所有容器不会同时被更新到新版本,而是根据用户设定的策略分批更新,同时在此期间业务流量会被平滑的逐渐切换到新的版本。在灰度发布的过程中,开发者可以随时观察新老版本之间的流量切换和健康状况,一旦出现故障可以随时中断发布过程并将已经更新的部分实例回滚。   在百度智能云上,用户可以直接利用容器镜像服务中的自动构建和部署功能实现简单的CI&CD流程,应用于一些测试场景或者简单的业务中。如果需要编排更加复杂的CI&CD流水线,引入更多的权限管理和自动化测试等能力,也可以选择百度效率云所提供的完整CI&CD工具链。

第四站 

容器编排:高效的管理、调度与调整

经过前面的三个站点,应用已经可以通过容器化的方式,持续上线发布到生产环境当中。但是随着应用以及容器的数量逐渐增多,运维人员也会面临更多的问题:

 

  • 如何把容器合理调度到不同的计算资源上?

  • 如何动态调整容器的实例数量?

  • 如何区别管理不同类型应用的容器生命周期?

 

容器编排系统的目的就是帮助运维人员解决这些问题,而Kubernetes则是容器编排领域最为成功的项目。 通过定义一套标准易用的模型,Kubernetes将容器和容器相关的资源包装成为多种面向不同场景的工作负载类型,如部署(deployment)、任务(Job)、守护进程(daemonset)、有状态任务(statefulset)等。 用户只需要用Kubernetes的语法将待部署的业务描述为这些不同工作负载,Kubernetes将会根据计算资源的实际情况自动完成容器的调度和生命周期管理,比如自动维持部署的副本数在用户指定的规模、将守护进程部署到集群中所有节点中、保障有状态任务中每个实例的ID不变等。   实施一个基于Kubernetes的容器编排系统并不复杂,社区中有多种工具可以帮助开发者快速创建一个Kubernetes集群,比如kubeadmin、kubeoperator等。但真正把Kubernetes投入生产中使用还有很多问题需要考虑,这些问题主要体现在3个方面: 1.Kubernetes与IaaS的适配问题。不同的基础架构提供的计算、网络和存储方案是不一样的,在公有云上这种差异尤其显著,比如公有云不同的授权机制、网络和存储实现方案等。Kubernetes为与IaaS层的适配提供了一个叫做cloud-controller-manager的组件,抽象出面向IaaS平台的接口,而具体的实现交给各云厂商来做。 2.Kubernetes本身的维护成本。Kubernetes虽然为容器编排管理带来了极大的便利,但是对Kubernetes本身的稳定性维护会增加额外的成本。当容器规模增大时,需要对Kubernetes的核心组件有完善的监控和容灾方案,才能真正投入到生产环境中。 3.开源组件的集成管理。Kubernetes作为容器编排生态的底座,在社区中发展出了大量面向Kubernetes的组件,进而提供监控、日志、网络管理、持续集成等能力。那么如何在众多开源组件中选型、如何管理大量开源组件的版本和适配问题、如何让不同开源组件提供统一的使用界面。这些问题在生产环境中都需要考虑。   在百度智能云上,用户可以选择 云容器引擎CCE产品,从而满足Kubernetes集群托管的需求,在云上轻松创建、管理和运维专属的Kubernetes集群,能够大大降低搭建容器基础设施的成本,更快达成容器编排这一云原生关键路径。

第五站 

计算存储分离:提升灵活性

我们将应用容器交给Kubernetes进行编排调度后,并不意味着这些容器就已经可以开始在集群中灵活迁移了。虽然容器化让应用可以跨节点快速启停,但是应用所依赖的数据如果依然保存在本地磁盘中,那么容器的灵活性就会大大受到限制。 接下来我们需要做的就是拆分系统中的计算与存储,并且用分布式的远程存储方案来替代本地存储,从而让容器的调度不再受限于存储资源所在的位置。   云磁盘是一种最直观的远程存储方式,它提供了可以通过网络路径挂载到容器宿主机上的块存储设备。云磁盘的优势在于提供了与本地磁盘几乎一致的使用体验,因此可以作为最低成本的本地存储迁移方案。但是云磁盘的使用场景依然受限于它所挂载的宿主机,因此在频繁迁移的场景或者分布式读写的场景中就不那么适用了。   NFS(网络文件系统)则是针对这两种场景的解决方案之一,它可以为多个宿主机提供共享的文件系统,支持分布式系统同时进行读写。不过相比之下NFS牺牲了一定的IO性能,因此并不适用于对性能要求较高的业务。   对象存储是另一种存储方式,它在支持分布式远程访问的同时提供了更强的性能。对象存储中不再有文件系统中的层级结构,每个存储对象都存在于存储池的扁平地址空间中,并且都具有各自的唯一标识符,应用程序需要访问对象存储系统提供的接口,并通过唯一标识符对存储对象进行读写等操作。 相比起云磁盘或NFS,对象存储的使用通常会对业务代码的开发有所侵入,但是对象存储在分布式、高并发的场景下,却有其不可替代的优势。   为了满足对这些不同类型的存储灵活使用,Kubernetes提供了一种叫做PV(Persistent Volume)的对象用来对存储资源进行统一管理。云服务商通过向Kubernetes提供插件的方式来支持各自对三种不同存储类型的不同实现,从而让开发者通过统一的方式选择所需存储类型并挂载到容器。 百度智能云容器引擎CCE支持用户通过PV的方式使用云磁盘CDS、云文件系统CFS和云对象存储BOS三种存储类型,从而满足不同场景下的业务需求。   下一期,我们将继续介绍云原生漫游之旅的关键站点,敬请期待。