有关云可移植性的三个考量:一云原生和容器

市面上的云服务平台丰富各异,如何选择最适合自己的?这往往需要慎重考虑。然而更重要的是,您考虑过云的可移植性问题吗?您在今年根据具体需求选择的云平台,能否满足以后的需求?如果不能满足,是否可以方便快捷地将应用移植到其他平台去?

在这一系列文章中,我们将从架构、设计等不同方面来探讨,在云的可移植性方面,具体都需要考虑哪些细节问题,如何最大限度避免云时代的技术锁定,充分发挥云的灵活性优势。

下文将简要探讨云原生和容器技术。

在云时代,诸如容器和无服务器计算这样的云原生技术是构建高可移植性应用程序时不可或缺的。在这些技术的帮助下,我们可以设计出更具弹性和扩展性,同时适应性也更强的应用程序,从而适应不断变化的环境。实际上,我们可以用一个词来解释所有这些好处:可移植性。

与日渐繁琐并且几乎无法管理的单体(Monolithic)模型不同,云原生微服务架构是模块化(Modular)的。这种方法使得我们可以自由地为工作选择适合的工具,用一个服务来执行一种特定功能,通过“专精”获得更好的效果。云原生方法就是在这种情况下开始大放异彩的,它提供了一种有效的流程,方便我们更新和替换应用程序中的单个组件,而不会对整个工作负载产生影响。使用云原生思维进行开发,这会催生出一种声明性(Declarative)的部署方法:分别部署应用程序、为其提供支撑的软件栈,以及配套的系统配置。

为何使用容器?

我们可以把容器想像成一种专为执行某一种特定任务而设计的超轻量级虚拟机。容器的寿命往往很短暂,前一分钟可能还在运行,下一分钟就消失了,因此缺乏持久性。实际上,所需的持久性是通过绑定主机文件系统中的块存储或所挂载的其他存储服务来实现的,并非通过与容器本身的绑定来实现。

通过对应用程序进行容器化改造,即可使其具备可移植性!只需准备好一个容器镜像,就能将其部署到不同架构CPU上运行的不同操作系统中,并顺序运行该容器。由于容器化应用程序是一种自包含(Self-contained)的独立单元,其中包括了所有必须的依赖项、库以及配置文件,因此在不同云环境中运行时完全无需更改代码。

简单来说,在云原生设计中,容器是通过下列方式实现可移植性的:

  • 轻量级虚拟化:容器为应用程序的运行提供了一种隔离的环境,虽然共享主机操作系统内核,但会对进程、文件系统以及网络资源进行隔离。
  • 可移植且一致:容器将应用程序及其依赖项打包在一起,确保无论在开发还是生产环境中,应用程序都可以一致地运行。
  • 资源效率:容器比虚拟机消耗的资源更少,因为容器会隔离进程并共享主机操作系统的内核;同时容器不需要在主机操作系统之上运行一个单独的“来宾”操作系统,这进一步降低了开销。
  • 快速启动和部署:容器启动速度飞快,因为它并不需要引导完整的操作系统,因此容器成了快速部署、扩展和恢复等场景中的理想选择。
  • 不可变的基础架构:容器在设计上是不可变(Immutable)的,这意味着容器在构建完成之后就不会再产生任何变化,这种特性简化了容器的部署、版本控制和回滚流程,同时还有助于确保在不同环境中实现一致的行为。

何时应当考虑使用容器?

容器可以帮助我们维持一致性,同时有助于省略开发过程中的某些暂存和投产环节,例如Verbose调试输出。开发过程中所发布的代码将在整个测试和部署周期中保持完整。

容器在资源的使用方面非常高效,并且本身就非常轻巧。虽然上文提到容器类似于虚拟机,但容器一般只有数十MB大小,不像虚拟机那么庞大(往往有数GB大小,虽然也有更小的,但资源浪费情况更严重)。容器越轻巧,启动速度就越快,从而越容易在动态的云计算环境中实现弹性和高性能的横向扩展。容器在设计上还是不可变的。如果有什么东西需要变更,我们并不需要将变更嵌入到容器中,此时只需要销毁旧容器,创建新容器就行了。

除此之外,在决定是否将容器作为云原生模型的一部分时,还需要注意下列因素:

  • 提高部署的一致性:容器会将应用程序及其依赖项打包在一起,确保在不同环境中运行时产生一致的行为,这还有助于简化部署过程,降低与配置相关问题所造成的风险。
  • 增强可扩展性:容器可通过快速启动新实例来应对激增的需求,借此帮助应用程序实现快速扩展,同时还可优化资源使用,改善系统整体性能。
  • 经济高效的资源利用率:容器的资源用量远少于传统虚拟机,企业可以在相同硬件上运行更多实例,从而节约云基础设施的成本。
  • 为开发和测试周期提速:容器促进了开发、测试和生产环境之间的无缝过渡,简化了开发过程,加快了新功能和Bug修复的发布速度。
  • 简化应用程序管理:容器编排平台负责管理容器化应用程序的部署、扩展和维护,可自动实现大部分运维任务,降低IT团队的负担。

有关容器的最佳实践

运行容器的方法有很多,这些方法都是可以互操作的。例如,在从其他公有云平台迁移时,只需将自己的容器镜像重新部署到新环境即可,借此即可快速迁移工作负载。此外,我们还可以使用不同的工具和引擎来运行容器。这些方式有着不同的资源利用率和价格点。如果通过Linode(Akamai的云计算服务)进行托管,用户可以使用Linode Kubernetes Engine(LKE)运行自己的容器,或者也可以通过虚拟机来运行Podman、HashiCorp Nomad、Docker Swarm以及Compose。

这些符合开放标准的工具可以帮助大家快速完成开发和测试工作,并且在使用LKE这样的服务时,还可以通过简化管理为用户带来更多附加值。Kubernetes会成为用户的控制平面。用户可将其视作一个控制台,通过上面的各种按钮和旋钮控制自己的容器,并使用各种基于开放标准的工具。此外,如果决定使用各种特定平台原生的产品,例如AWS Elastic Container Service (ECS),则需要为不同类型的利用率付费。

容器的另一个重点在于需要理解该用什么来存储和访问自己的容器镜像(这个东西也被称为容器注册表)。通常我们会建议使用Harbor。作为一个CNCF项目,Harbor可以帮助我们运行专用的容器注册表,从而控制相关的安全设置。

请始终记得进行测试,并准备好足够深入的回归测试套件,以确保自己的代码符合最高的性能和安全性要求。容器还应该具备失败计划。如果一个容器失败,此时的重试机制应该是怎样的?该如何重新启动?这会产生怎样的影响?应用程序又该如何恢复?有状态数据是否持久保留在映射卷或已绑定的挂载卷上?

在云原生开发模型中使用容器时,还需要注意下列最佳实践:

  • 使用轻量级基础镜像:从轻量级基础镜像(例如Alpine Linux或BusyBox)着手,这有助于减小容器的整体大小并最大限度减小攻击面。
  • 使用容器编排工具:使用容器编排工具(例如Kubernetes、HashiCorp Nomad、Docker Swarm或Apache Mesos)来跨越多台主机管理和扩展容器。
  • 使用容器注册表:使用容器注册表(例如Docker Hub、GitHub Packages registry、GitLab Container registry、Harbor等)来存储和访问容器镜像。这有助于跨越多台主机和计算环境共享和部署容器镜像。
  • 限制容器特权:限制容器所获的的特权,只为容器提供完成预期目的所必须的特权。尽可能部署无Root容器,从而降低容器遭到破坏被滥用后所造成的风险。
  • 实施资源约束:针对CPU和内存等资源设置限制约束,防止容器使用太多资源并影响到系统整体性能。
  • 确保容器处于最新状态:通过最新安全补丁和更新让容器镜像始终处于最新状态,最大限度降低漏洞所造成的风险。
  • 充分测试容器:在部署到生产环境前,确保容器能够按照预期工作且不包含漏洞。使用CI管道在每个阶段进行自动化测试,从而减少人为错误。
  • 为容器实施备份和恢复机制:为容器访问的持久数据实施备份和恢复策略,以确保在出现故障或灾难后,工作负载依然可以快速恢复。

你可能感兴趣的:(云计算,云计算)