应用容器化和与Kubernetes适配的7条军规

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 本文来自于Red Hat咨询顾问Bilgin Ibryam所编写的一篇白皮书,名为《PRINCIPLES OF CONTAINER-BASED APPLICATION DESIGN》。已被被Kubernetes官网转载。

本文来自于Red Hat咨询顾问Bilgin Ibryam所编写的一篇白皮书,名为《PRINCIPLES OF CONTAINER-BASED APPLICATION DESIGN》。已被被Kubernetes官网转载。白皮书在Red Hat官网的下载地址:https://www.redhat.com/en/resources/cloud-native-container-design-whitepaper 本微信文章是我是对这篇文章的学习和整理。


先回顾经典的软件设计原则:

  • 保持简单,愚蠢(KISS)
  • 不要重复自己(DRY)
  • 适可而止 (YAGNI)
  • 关注点分离(SoC)
  • 单一责任, 开放封闭, 里氏替换, 迪米特法则,接口分离, 依赖倒置(SOLID)

然后是Red Hat的云原生容器设计原则:

  1. 单一关注性原则(SCP)
  2. 高度可观测性原则(HOP)
  3. 生命周期一致性原则(LCP)
  4. 镜像不可变性原则(IIP)
  5. 进程可处置性原则(PDP)
  6. 自包含性原则(S-CP)
  7. 运行时约束性原则(RCP)

很多组织都理解云原生的重要性和必要性,但是并不知道从哪里开始。那么请确保:云原生平台和容器化应用能无缝的运行在一起,并且具备抵御故障的能力,甚至在底层的基础架构出现宕机的时候,也能通过过弹性扩展的方式表现出可靠性。本文描述了容器化应用时需要遵循的基本准则,实施这些原则有助于使之与云原生平台Kubernetes更加适配。

1、单一关注性原则

SINGLE CONCERN PRINCIPLE(SCP)

在许多方面,单一关注性原则与来自SOLID的SRP是类似的,它建议一个类应该只有一个责任。SRP背后的动机是每个责任是变更的一个轴心,一个类应该有,且也只有一个需要改变的理由。SCP原则中的“关注”一词强调关注是一种更高层次的抽象的责任,而且它更好地将范围描述为一个容器而不是一个类。虽然SRP的主要动机是变化原因的唯一性,而SCP的主要动机是容器镜像重用和可替换性。如果你创建一个解决单个问题的容器,并且以功能完整的方式来实现,不同应用程序中的容器镜像重用的可能性就会更高。

因此,SCP原则规定每个集容器都应该解决一个问题,并做得很好。 实现这一点,通常比在面向对象的世界中实现SRP更容易,容器通常管理的一个单一的进程,大多数情况下一个进程解决一个问题。

如果你的容器化微服务需要解决多个问题,它可以使用这样的模式,将多个容器用sidecar和init-containers的模式合并成一个部署单元(pod),这样每个容器仍然是处理单个问题。同样,您可以替换处理同样问题的容器。 例如,将Web服务器容器或队列实现容器,更新为更具可扩展性的容器。

2、高度可观测性原则

HIGH OBSERVABILITY PRINCIPLE(HOP)

容器提供了一种统一的方式来打包和运行应用程序,将它们视为一个黑盒子对象。 但任何旨在成为云原生公民的容器都必须提供API支持,要为运行时环境编写接口(API),以观察容器的健康状况和行为。 这是自动化容器更新和生命周期回收的基本先决条件和统一的方式,从而提高系统的弹性和用户体验。

实际上,您的容器化应用程序必须至少为其提供不同类型的健康检查的API–活动和就绪等状态。更好的应用程序的行为则必须提供其他手段来观察容器化应用程序的状态。应用程序应该将重要事件记录到标准错误(STDERR)和标准输出(STDOUT)中,从而通过统一的日志聚合工具(诸如Fluentd和Logstash之类的工具)进行分析,并与跟踪和指标收集库相结合,例如OpenTracing,Prometheus等。

将您的应用程序视为黑盒子,但实施所有必要的API以帮助平台对其进行观测,并以最佳方式管理您的应用程序。

3、生命周期一致性原则

LIFE-CYCLE CONFORMANCE PRINCIPLE(LCP)

HOP规定了你的容器提供供平台观测的API。 LCP则规定:您的应用程序有办法读取来自平台的事件。 此外,除了获得事件以外,容器还应该对这些事件相应地作出反应。这就是此原则名字由来。这几乎就像在应用程序通过一个“写入API”与平台进行交互。

来自管理平台的各种事件都是为了帮助您管理您的容器的生命周期的。决定处理哪些事件取决于您的应用程序 以及是否对这些事件做出反应。

但有些事件比其他事件更重要。例如,任何需要一个干净的关闭进程,这就需要捕获信号:终止(SIGTERM)消息,并尽可能迅速关闭。 这是为了避免通过强制关闭信号:kill(SIGKILL),之后跟随一个SIGTERM。

还有其他事件,例如PostStart和PreStop,可能对您的应用程序生命周期管理也非常重要。 例如,某些应用程序需要在服务之前进行预热请求和一些需要在关闭干净之前释放资源。

4、镜像不可变性原则

IMAGE IMMUTABILITY PRINCIPLE(IIP)

容器化的应用程序是不可变更的,镜像一旦完成了构建,预计在不同的环境中运行都不会改变。这意味着在因外部环境的不同,在需要的时候需要使用外部手法处理所依赖的外部配置数据,而不是每个环境修改或者构建不同的容器。而容器应用程序中的任何变更,都应该因此触发构建新的容器映像,并在所有环境中重用它。相同于这个原理的,不可变服务器和不可变基础架构的概念也很受欢迎,并且对于服务器/主机管理也是如此。

在遵循IIP原则的情况下,应该防止为不同的环境创建相似的容器镜像,要始终坚持为所有环境只配置一个容器映像。 这个原则允许在应用程序更新期间,采用自动回滚和前滚等做法,这是云原生自动化的重要方面。

5、进程可处置性原则

PROCESS DISPOSABILITY PRINCIPLE(PDP)

迁移到容器应用程序的主要动机之一是:容器需要尽可能做到临时性,并做好在任何时候被另一个容器实例替换的准备。需要更换容器的原因有很多,比如:健康检查失败、缩容、应用程序将容器迁移到不同的主机,平台资源匮乏或其它的问题。

这意味着容器化的应用程序必须保持其状态为向外扩展的或分布式和冗余的。这也意味着应用程序应该快速启动和关闭,甚至为彻底的硬件故障做好准备。 实施这一原则的另一个有用的做法是创建小容器。 容器在云原生环境可以自动调度并在不同的主机上启动。较小的容器可以实现更快启动时间,因为在重新启动之前容器镜像需要被物理地复制到主机系统。

6、自包含性原则

SELF-CONTAINMENT PRINCIPLE(S-CP)

这个原则规定一个容器应该在构建时包含所有需要的东西。容器的存在应该仅仅依赖于Linux®内核,在并添加相关额外的库,在容器构建时加入它们。除了库之外,它还应该包含语言运行时,应用程序平台(如果需要),以及运行所需的其他依赖关系,等运行容器化应用所需要的诸如此类的东西。

唯一的例外是:由于不同环境之间差异,并且只能在运行时提供的配置; 例如,通过Kubernetes提供的ConfigMap。

某些应用程序由多个容器组件组成。 例如,容器化的Web应用程序也可能需要数据库容器。 根据这个原则,并不建议合并两个容器。相反,它建议的是数据库容器只包含运行数据库所需的所有内容,Web应用程序容器只包含运行Web应用程序所需的所有内容,如Web服务器。 在运行时,Web应用程序容器将根据需要依赖于并访问数据库容器。

7、运行时约束性原则

RUNTIME CONFINEMENT PRINCIPLE(RCP)

S-CP从构建时的角度查看容器,并关注于生成的二进制文件及其内容。但是容器不仅仅是磁盘上一个只有尺寸大小的单一维度的黑盒子。 容器运行时有多个维度,例如内存使用维度,CPU使用维度等资源消耗维度。

这个RCP原则建议每个容器申报资源需求,并发送信息到平台。它应该分享容器的资源配置文件,从CPU,内存,网络,磁盘的角度声明。这影响到平台如何执行调度,自动扩展,容量 管理以及容器常规的服务级别协议(SLA)等。

除了向平台声明容器的资源需求之外,还有一点也很重要, 应用被约束在使用所声明的资源需求内。如果应用程序对资源的使用保持在约束的范围内,则当资源匮乏发生时,平台不太可能将其终止和迁移。

8、结论

云原生不仅仅是一种最终状态 – 它也是一种工作方式。 本份白皮书描述了一系列容器应用的基本原则,必须遵守才能成为优秀的云原生公民。

除了这些原则之外,创建良好的容器应用程序还需要熟悉其他容器相关的最佳实践和技术。 尽管上述原则非常根本,适用于大多数用例,下面列出的最佳实践在应用和不应用的时候,则需要判断力。以下是一些与容器相关的更常见的最佳实践:

  • 镜像要尽可能的小。 通过清理临时文件,并避免安装不必要的软件包来构建小尺寸镜像。 这减少了容器的尺寸,构建时间和复制容器镜像的网络传输时间。
  • 支持任意用户ID。 避免使用sudo命令或要求特定用户名运行你的容器。
  • 标记重要的端口。 虽然可以在运行时指定端口号,然而使用EXPOSE命令在运行的时候指定,则可以让镜像的使用者更轻松。
  • 为持久数据使用卷。 在容器摧毁之后还需要保存的容器数据的,必须将数据写入一个数据卷。
  • 设置镜像元数据。 以标签和注释形式存在的镜像元数据可以使您的容器镜像更加实用,从而为使用您的容器的开发人员提供了更好的体验。
  • 使主机和镜像同步。 一些容器应用需要容器在某些属性(如时间和机器ID)上与主机同步。

这里是指向各种模式和最佳实践的资源的链接,以帮助您能有效地实现上述目标:

  • https://www.slideshare.net/luebken/container-patterns
  • https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices
  • http://docs.projectatomic.io/container-best-practices
  • https://docs.openshift.com/enterprise/3.0/creating_images/guidelines.html
  • https://www.usenix.org/system/files/conference/hotcloud16/hotcloud16_burns.pdf
  • https://leanpub.com/k8spatterns/
  • https://12factor.net
本文转自kubernetes中文社区-应用容器化和与Kubernetes适配的7条军规
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
11天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
45 2
|
13天前
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
【赵渝强老师】Kubernetes中Pod的基础容器
|
4天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
11天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
11天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
13天前
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
|
13天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Pod中的业务容器
Pod 是 Kubernetes 中的基本调度单元,由一个或多个容器组成。除了业务容器,Pod 还包括基础容器、初始化容器和临时容器。本文通过示例介绍如何创建包含业务容器的 Pod,并提供了一个视频讲解。示例中创建了一个名为 "busybox-container" 的业务容器,并使用 `kubectl create -f firstpod.yaml` 命令部署 Pod。
|
6天前
|
Kubernetes 监控 安全
容器化技术:Docker与Kubernetes的实战应用
容器化技术:Docker与Kubernetes的实战应用
|
7天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
30 1
|
28天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景

相关产品

  • 容器服务Kubernetes版