Kubernetes 中的自动扩展和资源管理(评论和视频报告)

27月XNUMX日 会议 2019年罢工作为“DevOps”部分的一部分,给出了“Kubernetes 中的自动扩展和资源管理”报告。 它讨论了如何使用 K8s 来确保应用程序的高可用性并确保峰值性能。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

按照传统,我们很高兴向您展示 报告视频 (44 分钟,比文章内容丰富得多)和文本形式的主要摘要。 去!

我们逐字分析一下报告的主题,从最后开始。

Kubernetes

假设我们的主机上有 Docker 容器。 为了什么? 为了确保可重复性和隔离性,进而实现简单且良好的部署,CI/CD。 我们有很多这样的带有集装箱的车辆。

在这种情况下 Kubernetes 提供了什么?

  1. 我们不再考虑这些机器,而是开始使用“云” 容器集群 或 pod(容器组)。
  2. 此外,我们甚至不考虑单个 pod,而是管理更多о更大的群体。 这样的 高级原语 允许我们说有一个用于运行特定工作负载的模板,这里是运行它所需的实例数量。 如果我们随后更改模板,所有实例都会更改。
  3. 声明式API 我们不是执行一系列特定命令,而是描述由 Kubernetes 创建的“世界结构”(在 YAML 中)。 再说一遍:当描述发生变化时,其实际显示也会发生变化。

资源管理

中央处理器

让我们在服务器上运行 nginx、php-fpm 和 mysql。 这些服务实际上会运行更多的进程,每个进程都需要计算资源:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)
(幻灯片上的数字是“鹦鹉”,每个进程对计算能力的抽象需求)

为了更容易地使用它,将进程组合成组是合乎逻辑的(例如,将所有 nginx 进程合并为一组“nginx”)。 一个简单而明显的方法是将每个组放入一个容器中:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

要继续,您需要记住容器是什么(在 Linux 中)。 它们的出现得益于内核中很久以前就实现的三个关键功能: 能力, 命名空间 и 小组。 其他技术(包括像 Docker 这样方便的“shell”)促进了进一步的开发:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

在报告中,我们只感兴趣 小组,因为控制组是容器(Docker等)实现资源管理的功能的一部分。 正如我们所希望的,组合成组的进程是对照组。

让我们回到这些进程以及进程组的 CPU 要求:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)
(我再说一遍,所有数字都是对资源需求的抽象表达)

同时CPU本身具有一定的有限资源 (在示例中为 1000),每个人都可能缺乏(所有群体的需求总和是150+850+460=1460)。 在这种情况下会发生什么?

内核开始分配资源并“公平”地进行,为每个组提供相同数量的资源。 但在第一种情况下,它们的数量超出了需要的数量(333>150),因此多余的(333-150=183)仍然保留,这也平均分配在其他两个容器之间:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

结果是:第一个容器有足够的资源,第二个容器没有足够的资源,第三个容器没有足够的资源。 这是行动的结果 Linux 中的“诚实”调度程序 - 中心。 可以使用分配来调整其操作 重量 每个容器。 例如,像这样:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

我们来看看第二个容器(php-fpm)资源不足的情况。 所有容器资源在进程之间平均分配。 结果,主进程运行良好,但所有工作进程都变慢了,收到的数据还不到他们需要的一半:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

这就是 CFS 调度程序的工作原理。 我们将进一步调用分配给容器的权重 要求。 为什么会这样 - 进一步了解。

让我们从另一面来看整个情况。 如您所知,条条大路通罗马,对于计算机而言,则通向 CPU。 一个 CPU,许多任务 - 你需要一个红绿灯。 管理资源的最简单方法是“红绿灯”:它们为一个进程提供了固定的 CPU 访问时间,然后是下一个进程,依此类推。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

这种方法称为硬配额 (硬限制)。 让我们简单地记住它 范围。 但是,如果将限制分配给所有容器,则会出现一个问题:mysql 正在沿路行驶,在某个时刻它对 CPU 的需求结束,但所有其他进程都被迫等待,直到 CPU 耗尽 闲置的.

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

让我们回到Linux内核以及它与CPU的交互——整体情况如下:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

cgroup 有两个设置 - 本质上这是两个简单的“扭曲”,允许您确定:

  1. 集装箱重量(请求)是 股份;
  2. 用于处理容器任务的总 CPU 时间的百分比(限制)为 配额.

如何测量CPU?

有不同的方法:

  1. 什么是 鹦鹉,没有人知道——你每次都需要谈判。
  2. 兴趣 更清楚,但相对而言:50 核服务器和 4 核服务器的 20% 是完全不同的东西。
  3. 您可以使用已经提到的那些 重量,Linux 知道,但它们也是相对的。
  4. 最合适的选择是测量计算资源 。 那些。 以相对于实时秒数的处理器时间秒数为单位:每 1 实际秒给出 1 秒处理器时间 - 这是一个完整的 CPU 核心。

为了让说话更容易,他们开始直接测量 内核,这意味着它们与真实的 CPU 时间相同。 由于 Linux 理解权重,但不理解那么多 CPU 时间/内核,因此需要一种机制来从一个权重转换为另一个权重。

让我们考虑一个具有 3 个 CPU 核心的服务器的简单示例,其中三个 Pod 将被赋予权重(500、1000 和 1500),这些权重可以轻松转换为分配给它们的核心的相应部分(0,5、1 和 1,5)。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

如果您使用第二台服务器,其中的核心数量是两倍 (6),并在那里放置相同的 Pod,只需乘以 2(分别为 1、2 和 3)即可轻松计算核心的分布。 但是,当第四个 Pod 出现在该服务器上时,一个重要的时刻发生了,为了方便起见,其权重为 3000。它占用了部分 CPU 资源(一半核心),并且对于剩余的 Pod,它们被重新计算(减半):

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

Kubernetes 和 CPU 资源

在 Kubernetes 中,CPU 资源通常以 米利亚德拉克斯, IE。 以0,001芯为基重。 (Linux/cgroups 术语中的同一事物称为 CPU 份额,但更准确地说,1000 毫核 = 1024 个 CPU 份额。) K8s 确保服务器上放置的 pod 数量不会超过所有 pod 权重总和的 CPU 资源数量。

这是怎么发生的? 当您将服务器添加到 Kubernetes 集群时,会报告它有多少个可用 CPU 核心。 当创建一个新的 Pod 时,Kubernetes 调度程序知道这个 Pod 需要多少个核心。 因此,Pod 将被分配到有足够核心的服务器。

如果会发生什么 没有 请求已指定(即 Pod 没有定义所需的核心数量)? 我们先了解一下 Kubernetes 一般是如何统计资源的。

对于 pod,您可以指定请求(CFS 调度程序)和限制(还记得交通信号灯吗?):

  • 如果指定它们相等,则为 pod 分配一个 QoS 类别 保证。 始终可用的核心数量是有保证的。
  • 如果请求小于限制 - QoS 等级 可爆裂的。 那些。 例如,我们期望 pod 始终使用 1 个核心,但该值并不是对其的限制: 有时 pod 可以使用更多(当服务器有可用资源时)。
  • 还有一个 QoS 等级 尽力而为 — 它包括那些未指定请求的 pod。 资源最后才提供给他们。

Память

对于内存来说,情况类似,但略有不同——毕竟这些资源的性质不同。 一般来说,类比如下:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

让我们看看请求在内存中是如何实现的。 让 Pod 驻留在服务器上,改变内存消耗,直到其中一个 Pod 变得太大而耗尽内存。 在这种情况下,OOM杀手出现并杀死最大的进程:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

这并不总是适合我们,因此可以调节哪些进程对我们很重要并且不应该被杀死。 为此,请使用参数 oom_score_adj.

让我们回到 CPU 的 QoS 等级,并与决定 pod 内存消耗优先级的 oom_score_adj 值进行类比:

  • pod 的最低 oom_score_adj 值 - -998 - 意味着这样的 pod 应该最后被杀死,这 保证.
  • 最高的 - 1000 - 是 尽力而为,这样的豆荚首先被杀死。
  • 计算剩余值(可爆裂的)有一个公式,其本质可以归结为一个事实:Pod 请求的资源越多,它被杀死的可能性就越小。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

第二个“转折”—— 限制字节数 - 用于限制。 有了它,一切都变得更简单:我们只需分配最大的已发行内存量,并且这里(与CPU不同)不存在如何测量它(内存)的问题。

在总

Kubernetes 中的每个 pod 都是给定的 requests и limits - CPU 和内存的参数:

  1. Kubernetes 调度程序根据请求工作,在服务器之间分配 Pod;
  2. 根据所有参数,确定 pod 的 QoS 等级;
  3. 根据CPU请求计算相对权重;
  4. CFS调度程序根据CPU请求进行配置;
  5. OOM Killer根据内存请求进行配置;
  6. 根据 CPU 限制配置“红绿灯”;
  7. 根据内存限制,为 cgroup 配置限制。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

总的来说,这张图回答了有关 Kubernetes 中资源管理的主要部分如何发生的所有问题。

自动缩放

K8s集群自动缩放器

假设整个集群已经被占用,需要创建一个新的 Pod。 虽然 pod 无法出现,但它处于挂起状态 待审批。 为了让它出现,我们可以将一台新服务器连接到集群或...安装 cluster-autoscaler,这将为我们完成:从云提供商订购虚拟机(使用 API 请求)并将其连接到集群,之后将添加 pod。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

这是 Kubernetes 集群的自动缩放,效果很好(根据我们的经验)。 然而,与其他地方一样,这里也存在一些细微差别......

只要我们增加簇大小,一切都很好,但是当簇大小增加时会发生什么? 开始释放自己? 问题在于,迁移 Pod(以释放主机)在技术上非常困难,而且在资源方面也非常昂贵。 Kubernetes 使用完全不同的方法。

考虑具有 Deployment 的 3 个服务器的集群。 它有 6 个 pod:现在每台服务器有 2 个 pod。 由于某种原因,我们想关闭其中一台服务器。 为此,我们将使用命令 kubectl drain, 哪个:

  • 将禁止向该服务器发送新的 Pod;
  • 将删除服务器上现有的 Pod。

由于 Kubernetes 负责维护 pod 的数量(6),因此它只是 将重新创建 它们位于其他节点上,但不在被禁用的节点上,因为它已被标记为无法托管新的 Pod。 这是 Kubernetes 的基本机制。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

然而,这里也有一个细微差别。 类似的情况,对于StatefulSet(而不是Deployment),操作会有所不同。 现在我们已经有了一个有状态的应用程序 - 例如,三个带有 MongoDB 的 Pod,其中一个存在某种问题(数据已损坏或另一个错误导致 Pod 无法正确启动)。 我们再次决定禁用一台服务器。 会发生什么?

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

MongoDB的 可能 因为它需要法定人数而死亡:对于三个安装的集群,至少有两个必须运行。 然而,这 没有发生 - 谢谢 Pod中断预算。 该参数决定了所需的最小工作 Pod 数量。 知道其中一个 MongoDB Pod 不再工作,并看到为 MongoDB 设置了 PodDisruptionBudget minAvailable: 2,Kubernetes 不会允许你删除 pod。

底线:为了在集群释放时 Pod 的移动(实际上是重新创建)能够正常工作,有必要配置 PodDisruptionBudget。

水平缩放

让我们考虑另一种情况。 Kubernetes 中有一个作为 Deployment 运行的应用程序。 用户流量来到它的 pod(例如,有 XNUMX 个),我们测量其中的某个指标(例如 CPU 负载)。 当负载增加时,我们将其记录在计划中并增加 pod 数量来分发请求。

如今,在 Kubernetes 中,这不需要手动完成:根据测量的负载指标的值配置自动增加/减少 pod 数量。

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

这里的主要问题是: 到底要测量什么 и 如何解释 获得的值(用于做出更改 pod 数量的决定)。 你可以测量很多:

Kubernetes 中的自动扩展和资源管理(评论和视频报告)

如何从技术上做到这一点 - 收集指标等。 ——我在报告中详细谈到了 监控和 Kubernetes。 选择最佳参数的主要建议是 实验!

使用方法 (利用率饱和度和误差),其含义如下。 扩展(例如 php-fpm)的基础是什么? 基于工人即将耗尽的事实,这是 采用。 如果工人结束了并且不接受新的连接,这已经是 饱和。 必须测量这两个参数,并根据这些值进行缩放。

取而代之的是结论

该报告还有一个延续部分:关于垂直扩展以及如何选择正确的资源。 我将在以后的视频中讨论这一点 我们的 YouTube - 订阅,这样您就不会错过!

视频和幻灯片

表演视频(44分钟):

报告介绍:

PS

我们博客上有关 Kubernetes 的其他报道:

来源: habr.com

添加评论