了解 Kubernetes 如何改变计算机集群

让我们仔细看看当您在服务器上部署 Kubernetes 时,对数据中心的看法会发生怎样的变化。

Kubernetes 就像计算机集群的操作系统

可以将 Kubernetes 想象成集群的操作系统。下图说明了在计算机上运行的操作系统与在计算机集群上运行的 Kubernetes 之间的类比。
image.png
正如操作系统支持计算机的基本功能,例如将进程调度到 CPU 上并充当应用程序和计算机硬件之间的接口,Kubernetes 将分布式应用程序的组件调度到底层计算机集群中的各个计算机上,并充当应用程序和集群之间的接口。

它使应用程序开发人员无需在其应用程序中实现与基础设施相关的机制;相反,他们依靠 Kubernetes 来提供它们。这包括以下内容:

  • 服务发现 - 一种允许应用程序找到其他应用程序并使用它们提供的服务的机制,
  • 水平扩展 - 复制您的应用程序以适应负载波动,
  • 负载均衡 - 在所有应用程序副本之间分配负载,
  • 自我修复 - 通过自动重新启动失败的应用程序并在节点失败后将它们移动到健康节点来保持系统健康,
  • 领袖选举 - 一种机制,它决定应用的哪个实例应该处于活动状态,而其他实例保持空闲但准备好在活动实例失败时接管。

通过依赖 Kubernetes 提供这些功能,应用程序开发人员可以专注于实现核心业务逻辑,而不是浪费时间将应用程序与基础设施集成。

Kubernetes 如何融入计算机集群

要获得 Kubernetes 如何部署到计算机集群上的具体示例,请看下图。
image.png
您从一组机器开始,这些机器分为两组 - 主节点和工作节点。主节点将运行 Kubernetes 控制平面,它代表系统的大脑并控制集群,而其余节点将运行您的应用程序 - 您的工作负载 - 因此将代表工作负载平面。

非生产集群可以使用单个主节点,但高可用性集群使用至少三个物理主节点来托管控制平面。工作节点的数量取决于您将部署的应用程序的数量。

所有集群节点如何成为一个大的部署区域

在计算机上安装 Kubernetes 后,您在部署应用程序时不再需要考虑单个计算机。无论集群中有多少工作节点,它们都将成为您部署应用程序的单一空间。您可以使用 Kubernetes 控制平面提供的 Kubernetes API 来执行此操作。
image.png
当我说所有工作节点成为一个空间时,我不希望您认为您可以部署一个非常大的应用程序,该应用程序分布在几台小型机器上。 Kubernetes 不会做这样的魔术。每个应用程序必须足够小以适合其中一个工作节点。

我的意思是,在部署应用程序时,它们最终在哪个工作节点上并不重要。 Kubernetes 甚至可能稍后将应用程序从一个节点移动到另一个节点。当这种情况发生时,您甚至可能都没有注意到,您也不应该在意。

使用 Kubernetes 的好处

您已经了解了为什么世界各地的许多组织都欢迎 Kubernetes 进入他们的数据中心。现在,让我们仔细看看它为开发和 IT 运营团队带来的具体好处。

应用程序的自助部署

因为 Kubernetes 将其所有工作节点呈现为单个部署表面,所以将应用程序部署到哪个节点不再重要。这意味着开发人员现在可以自行部署应用程序,即使他们对节点数量或每个节点的特性一无所知。

过去,系统管理员负责决定每个应用程序的放置位置。这个任务现在留给了 Kubernetes。这允许开发人员部署应用程序,而不必依赖其他人这样做。当开发人员部署应用程序时,Kubernetes 会根据应用程序的资源需求和每个节点上可用的资源来选择运行应用程序的最佳节点。

通过更好地利用基础设施来降低成本

如果您不关心您的应用程序位于哪个节点,这也意味着它可以随时移动到任何其他节点而无需您担心。 Kubernetes 可能需要这样做,以便为某人想要部署的更大的应用程序腾出空间。这种移动应用程序的能力允许将应用程序紧密地打包在一起,以便可以以最佳方式利用节点的资源。

找到最佳组合可能具有挑战性且耗时,尤其是当所有可能选项的数量很大时,例如当您有许多应用程序组件和许多可以部署它们的服务器节点时。计算机可以比人类更好、更快地完成这项任务。 Kubernetes 做得很好。通过在同一台机器上组合不同的应用程序,Kubernetes 提高了硬件基础设施的利用率,因此您可以在更少的服务器上运行更多的应用程序。

自动适应变化的负载

使用 Kubernetes 管理您部署的应用程序还意味着运营团队不必持续监控每个应用程序的负载以响应突然的负载峰值。 Kubernetes 也负责这一点。它可以监控每个应用程序消耗的资源和其他指标,并调整每个应用程序的运行实例数以应对增加的负载或资源使用情况。

当您在云基础设施上运行 Kubernetes 时,它甚至可以通过云提供商的 API 配置额外的节点来增加集群的大小。这样,您永远不会在运行新的应用时发行空间用完了。

保持应用程序平稳运行

Kubernetes 还尽一切努力确保您的应用程序顺利运行。如果您的应用程序崩溃,Kubernetes 会自动重启它。因此,即使您有一个Bug程序在运行几个小时后因内存不足崩溃了,Kubernetes 也会在这种情况下通过自动重启来确保您的应用程序继续为其用户提供服务。

Kubernetes 是一个自我修复系统,因为它可以处理刚刚描述的软件错误,但它也可以处理硬件故障。随着集群规模的扩大,节点故障的频率也会增加。例如,在具有一百个节点且每个节点的 MTBF(平均故障间隔时间)为 100 天的集群中,您可以预期每天有一个节点发生故障。

当一个节点发生故障时,Kubernetes 会自动将应用程序移动到剩余的健康节点。运营团队不再需要手动移动应用程序,而是可以专注于修复节点本身并将其返回到可用硬件资源池中。

如果您的基础架构有足够的可用资源来允许在没有故障节点的情况下正常运行系统,那么运营团队甚至不必立即对故障做出反应。如果它发生在半夜,运营团队的任何人都不必醒来。他们可以在正常工作时间内安然入睡并处理故障节点。

简化应用程序开发

上一节中描述的改进主要涉及应用程序部署。但是应用程序开发的过程呢? Kubernetes 会给他们带来什么吗?

如前所述,Kubernetes 提供了与基础设施相关的服务,否则这些服务必须在您的应用程序中实现。这包括发现分布式应用程序中的服务发现、领导者选举、集中式应用程序配置等。 Kubernetes 提供了这一点,同时保持应用程序与 Kubernetes 无关,但在需要时,应用程序还可以查询 Kubernetes API 以获取有关其环境的详细信息。他们还可以使用 API 来改变环境。

Kubernetes 集群的架构

正如您已经了解到的,Kubernetes 集群由分为两组的节点组成:

  • 一组构成控制平面的主节点,这些组件是系统的大脑,因为它们控制整个集群。
  • 一组构成工作负载平面的工作节点,这是您的工作负载(或应用程序)运行的地方。

下图显示了这两个平面以及它们所组成的不同节点。
image.png
这两个平面以及两种类型的节点运行不同的 Kubernetes 组件。本书接下来的两节将介绍它们并总结它们的功能,但不做详细介绍。这些组件将在本书的下一部分中多次提及,我将在其中解释 Kubernetes 的基本概念。本书第三部分对组件及其内部结构进行了深入了解。

控制平面的组成

控制平面是控制集群的部分。它由多个组件组成,这些组件在单个主节点上运行或跨多个主节点复制以确保高可用性。控制平面的组件如下图所示。
image.png
组件功能如下:

  • Kubernetes API Server 提供 RESTful Kubernetes API。使用集群和其他 Kubernetes 组件的工程师通过此 API 创建对象。
  • etcd 分布式数据存储持久化您通过 API 创建的对象,因为 API 服务器本身是无状态的。Kubernetes API Server 是唯一与 etcd 交互的组件。
  • 调度程序 Scheduler 决定每个应用程序实例应该在哪个工作节点上运行。
  • 控制器 Controllers 使您通过 API 创建的对象具有运行的能力,它们中的大多数只是简单地创建其他对象,但有些还与外部系统通信(例如,云厂商会调用控制器的 API)。

控制平面的组件保持和控制集群的状态,但它们不运行您的应用程序,运行应用的工作是由(工作)节点完成的。

工作节点的组成

工作节点是运行应用程序的计算机,它们构成集群的工作负载平面。除了应用程序之外,一些 Kubernetes 组件也在这些节点上运行。它们执行运行、监控和提供应用程序之间连接的任务。它们如下图所示。
image.png

  • Kubelet,一个与 API 服务器对话并管理在其节点上运行的应用程序的代理。它通过 API 报告这些应用程序和节点的状态。
  • 容器运行时(Container Runtime),可以是 Docker 或任何其他与 Kubernetes 兼容的运行时。它按照 Kubelet 的指示在容器中运行您的应用程序。
  • Kubernetes Service Proxy (Kube Proxy) 对应用程序之间的网络流量进行负载平衡。它的名字暗示着流量流经它,但现在已经不是这样了。您将在第 14 章中了解原因。

    附加组件

    大多数 Kubernetes 集群还包含其他几个组件。这包括 DNS 服务器(DNS server)、网络插件、日志代理等。它们通常在工作节点上运行,但也可以配置为在主节点上运行。

Kubernetes 如何运行一个应用

通过对组成 Kubernetes 的组件的总体概述,我终于可以解释如何在 Kubernetes 中部署应用程序了。

定义你的应用

Kubernetes 中的一切都由一个对象表示。您可以通过 Kubernetes API 创建和检索这些对象。您的应用程序由这些对象的几种类型组成 - 一种类型表示整个应用程序部署,另一种表示应用程序的运行实例,另一种表示由一组这些实例提供的服务,并允许通过单个 IP 地址访问它们,还有很多其他的。

所有这些类型都在本书的第二部分详细解释。目前,知道您通过几种类型的对象定义您的应用程序就足够了。这些对象通常以 YAML 或 JSON 格式在一个或多个清单文件中定义。

下图显示了通过创建清单来部署应用程序的示例,其中包含两个 services 暴露的两个 deployments。
image.png
这些操作在您部署应用程序时发生:

  • 您将应用程序清单提交给 Kubernetes API。 API Server 将 manifest 中定义的对象写入 etcd。
  • 控制器注意到新创建的对象并创建几个新对象 - 每个应用程序实例对应一个对象。
  • 调度程序为每个实例分配一个节点。
  • Kubelet 注意到一个实例已分配给 Kubelet 的节点。它通过容器运行时运行应用程序实例。
  • Kube Proxy 注意到应用程序实例已准备好接受来自客户端的连接并为它们配置负载均衡器。
  • Kubelet 和 Controllers 监控系统并保持应用程序运行。

该过程将在以下各节中更详细地解释,但在您熟悉所有涉及的对象和控制器之后,第 14 章会给出完整的解释。

向 API 提交应用程序

创建 YAML 或 JSON 文件后,通常通过名为 kubectl 的 Kubernetes 命令行工具将文件提交给 API。

Kubectl 将文件拆分为单独的对象,并通过向 API 发送 HTTP PUT 或 POST 请求来创建每个对象,这与 RESTful API 的情况一样。 API Server 验证对象并将它们存储在 etcd 数据存储中。此外,它会通知所有相关的组件这些对象已创建,控制器是其这些组件之一。

关于 controllers

大多数对象类型都有一个关联的控制器。每个控制器对应一个特定的对象类型。它等待 API 服务器通知它已经创建了一个新对象,然后执行操作以使该对象生效。通常,控制器只是通过相同的 Kubernetes API 创建其他对象。例如,负责应用程序部署的控制器创建一个或多个表示应用程序各个实例的对象。控制器创建的对象数量取决于应用程序部署对象中指定的副本数量。

关于 Scheduler

调度器是一种特殊类型的控制器,它的唯一任务是将应用程序实例调度到工作节点上。它为每个新的应用程序实例对象选择最佳工作节点并将其分配给实例 - 通过 API 修改对象。

关于 Kubelet 和 the Container Runtime

在每个工作节点上运行的 Kubelet 也是一种控制器。它的任务是等待应用程序实例被分配给它所在的节点并运行应用程序。这是通过指示容器运行时启动应用程序的容器来完成的。

关于 Kube Proxy

由于应用程序部署可以包含多个应用程序实例,因此需要负载均衡器将它们公开在单个 IP 地址上。 Kube 代理是与 Kubelet 一起运行的另一个控制器,负责设置负载均衡器。

保持应用程序健康

一旦应用程序启动并运行,Kubelet 通过在应用程序终止时重新启动它来保持应用程序的健康。它还通过更新表示应用程序实例的对象来报告应用程序的状态。其他控制器监视这些对象,并确保在其节点发生故障时将应用程序移至健康节点。

您现在已经大致熟悉了 Kubernetes 的架构和功能。你现在不需要理解或记住所有细节,因为当你在本书的第二部分了解每个单独的对象类型和使它们生效的控制器时,内化这些信息会更容易。