如何访问Kubernetes Pod资源

如何访问Kubernetes Pod资源托哈德的奖励

开始使用 Kubernetes 时,通常会忘记设置容器资源。 至此,足以保证Docker镜像能够工作并且可以部署到Kubernetes集群中。

但后来该应用程序需要与其他应用程序一起部署在生产集群中。 为此,您需要为容器分配资源,并确保有足够的资源来启动和运行应用程序,并且其他正在运行的应用程序不会遇到问题。

团队 Mail.ru 的 Kubernetes aaS 翻译了一篇关于容器资源(CPU & MEM)、请求和资源限制的文章。 您将了解这些设置的好处以及如果不设置它们会发生什么。

计算资源

我们有两种类型的资源,具有以下单位:

  • 中央处理器 (CPU) - 核心;
  • 内存 (MEM) - 字节。

为每个容器指定资源。 在以下 Pod YAML 文件中,您将看到一个资源部分,其中包含请求的资源和限制的资源:

  • 请求的 Pod 资源 = 所有容器请求的资源之和;
  • Pod 资源限制 = 所有 Pod 资源限制的总和。

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

请求的资源和有限的资源示例

领域 resources.requested 根据规范,Pod 是用于查找所需节点的元素之一。 您已经可以为其规划 Pod 部署。 如何找到合适的节点?

Kubernetes 由多个组件组成,包括主节点或主节点(Kubernetes Control Plane)。 主节点有几个进程:kube-apiserver、kube-controller-manager 和 kube-scheduler。

kube-scheduler 进程负责检查新创建的 Pod 并查找与所有 Pod 请求匹配的可能工作节点,包括请求的资源数量。 kube-scheduler 找到的节点列表已排序。 Pod 被调度到分数最高的节点上。

如何访问Kubernetes Pod资源紫色 Pod 将放置在哪里?

在图中您可以看到 kube-scheduler 应该调度一个新的紫色 Pod。 Kubernetes 集群包含两个节点:A 和 B。如您所见,kube-scheduler 无法在节点 A 上调度 Pod - 可用(未请求)资源与紫色 Pod 的请求不匹配。 因此,紫色 Pod 请求的 1 GB 内存在节点 A 上不适合,因为可用内存为 0,5 GB。 但节点B有足够的资源。 因此,kube-scheduler 判定紫色 Pod 的目的地是节点 B。

现在我们知道请求的资源如何影响运行 Pod 的节点的选择。 但边际资源的影响是什么呢?

资源限制是CPU/MEM无法跨越的边界。 但是,CPU 资源是灵活的,因此达到 CPU 限制的容器不会导致 Pod 退出。 相反,CPU 限制将开始。 如果达到 MEM 使用限制,容器将因 OOM-Killer 而停止,并在 RestartPolicy 设置允许的情况下重新启动。

请求的资源和最大资源的详细信息

如何访问Kubernetes Pod资源Docker与Kubernetes之间的资源通信

解释资源请求和资源限制如何工作的最好方法是介绍 Kubernetes 和 Docker 之间的关系。 在上图中,您可以看到 Kubernetes 字段和 Docker 启动标志是如何关联的。

记忆:要求和限制

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

如上所述,内存以字节为单位。 基于 Kubernetes 文档,我们可以将内存指定为一个数字。 通常它是一个整数,例如2678——即2678字节。 您还可以使用后缀 G и Gi,最重要的是要记住它们并不等同。 第一个是十进制,第二个是二进制。 就像k8s文档中提到的例子: 128974848, 129e6, 129M, 123Mi - 它们实际上是等效的。

库伯内特选项 limits.memory 与旗帜相匹配 --memory 来自 Docker。 的情况下 request.memory Docker 没有箭头,因为 Docker 不使用该字段。 你可能会问,这还有必要吗? 是的,需要。 正如我之前所说,这个领域对于 Kubernetes 来说很重要。 根据其中的信息,kube-scheduler 决定在哪个节点上调度 Pod。

如果为请求设置的内存不足会发生什么情况?

如果容器已达到请求内存的限制,则 Pod 会被放置在一组 Pod 中,当节点中内存不足时,这些 Pod 会停止。

如果您将内存限制设置得太低会发生什么情况?

如果容器超过内存限制,它将因 OOM-Killed 而终止。 如果可能的话,将根据 RestartPolicy 重新启动,默认值为 Always.

如果不指定请求的内存会发生什么?

Kubernetes 将采用该限制值并将其设置为默认值。

如果不指定内存限制会发生什么?

容器没有任何限制;它可以使用任意多的内存。 如果他开始使用节点的所有可用内存,那么 OOM 将杀死他。 如果可能的话,容器将根据 RestartPolicy 重新启动。

如果不指定内存限制会发生什么?

这是最坏的情况:调度程序不知道容器需要多少资源,这可能会导致节点出现严重问题。 在这种情况下,最好对命名空间设置默认限制(由 LimitRange 设置)。 没有默认限制 - Pod 没有限制,它可以使用任意多的内存。

如果请求的内存超过节点可以提供的内存,Pod 将不会被调度。 重要的是要记住这一点 Requests.memory - 不是最小值。 这是对足以保持容器持续运行的内存量的描述。

通常建议设置相同的值 request.memory и limit.memory。 这可以确保 Kubernetes 不会将 Pod 调度到有足够内存运行 Pod 但又不足以运行它的节点上。 请记住:Kubernetes Pod 规划仅考虑 requests.memorylimits.memory 不考虑。

CPU:请求和限制

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

对于CPU来说,一切都有点复杂。 回到 Kubernetes 和 Docker 的关系图,可以看到 request.cpu 对应于 --cpu-shares,而 limit.cpu 与旗帜相匹配 cpus 在 Docker 中。

Kubernetes 请求的 CPU 乘以 1024,即 CPU 周期的比例。 如果您想请求 1 个完整核心,则必须添加 cpu: 1如上图所示。

请求完整的内核(比例 = 1024)并不意味着您的容器会收到它。 如果您的主机只有一个核心,并且您正在运行多个容器,那么所有容器必须在它们之间共享可用的 CPU。 这是怎么发生的? 让我们看一下图片。

如何访问Kubernetes Pod资源
CPU 请求 - 单核系统

让我们假设您有一个运行容器的单核主机系统。 妈妈(Kubernetes)烤了一个馅饼(CPU)并想把它分给孩子(容器)。 三个孩子想要整个馅饼(比例 = 1024),另一个孩子想要半个馅饼(512)。 妈妈为了公平起见,做了一个简单的计算。

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

据计算,三个孩子将获得核心的28%,而不是全部核心。 第四个孩子将获得完整内核的 14%,而不是一半。 但如果你有一个多核系统,情况就会有所不同。

如何访问Kubernetes Pod资源
CPU 请求 - 多核 (4) 系统

在上图中,您可以看到三个孩子想要一整个馅饼,一个想要半个。 由于妈妈烤了四个馅饼,所以她的每个孩子都想吃多少就吃多少。 在多核系统中,处理器资源分布在所有可用的处理器核心上。 如果一个容器被限制为少于一个完整的 CPU 核心,它仍然可以 100% 使用它。

简化上述计算可以理解 CPU 如何在容器之间分配。 当然,除了容器本身之外,还有其他进程也会使用CPU资源。 当一个容器中的进程空闲时,其他容器可以使用其资源。 CPU: "200m" 对应于 CPU: 0,2,这意味着一个核心的大约 20%。

现在让我们谈谈 limit.cpu。 Kubernetes 限制的 CPU 乘以 100。结果是容器每 100 µs 可以使用的时间量(cpu-period).

limit.cpu 匹配 Docker 标志 --cpus。 这是旧的新组合 --cpu-period и --cpu-quota。 通过设置它,我们指示在限制开始之前容器可以最大使用多少可用CPU资源:

  • CPU的 - 组合 cpu-period и cpu-quota. cpus = 1.5 相当于设置 cpu-period = 100000 и cpu-quota = 150000;
  • CPU周期 - 时期 CPU CFS调度器,默认100微秒;
  • CPU配额 - 内部的微秒数 cpu-period,它以容器为界。

如果安装的 CPU 不足,会发生什么情况?

如果容器需要的数量超过其已安装的数量,它将从其他进程中窃取 CPU。

如果您将 CPU 限制设置得太低会发生什么情况?

由于CPU资源是可调的,因此会开启节流。

如果不指定 CPU 请求会发生什么?

与内存一样,请求值等于限制。

如果不指定 CPU 限制会发生什么?

容器将根据需要使用尽可能多的 CPU。 如果命名空间中定义了默认 CPU 策略 (LimitRange),则此限制也适用于容器。

如果您不指定请求或 CPU 限制,会发生什么情况?

与内存一样,这是最坏的情况。 调度程序不知道您的容器需要多少资源,这可能会导致节点出现严重问题。 为了避免这种情况,您需要为命名空间设置默认限制(LimitRange)。

请记住:如果您请求的 CPU 多于节点可以提供的 CPU,则 Pod 将不会被调度。 Requests.cpu - 不是最小值,而是足以启动 Pod 并正常工作的值。 如果应用程序不执行复杂的计算,最好的选择是安装 request.cpu <= 1 并根据需要启动尽可能多的副本。

请求的资源的理想数量或资源限制

我们了解到计算资源的限制。 现在是时候回答这个问题了:“我的 Pod 需要多少资源才能运行应用程序而不出现任何问题? 理想的量是多少?

不幸的是,这些问题没有明确的答案。 如果您不知道应用程序如何工作或需要多少 CPU 或内存,最好的选择是为应用程序提供大量内存和 CPU,然后运行性能测试。

除了性能测试之外,还要在一周的监控中监控应用程序的行为。 如果图表表明您的应用程序消耗的资源少于您请求的资源,您可以减少请求的 CPU 或内存量。

举个例子看看这个 Grafana 仪表板。 它显示请求的资源或资源限制与当前资源使用情况之间的差异。

结论

请求和限制资源有助于保持 Kubernetes 集群的健康运行。 正确的限制配置可以最大限度地降低成本并保持应用程序始终运行。

简而言之,有以下几点需要牢记:

  1. 请求的资源是在启动时(当 Kubernetes 计划托管应用程序时)考虑的配置。 相反,限制资源在运行时非常重要——当应用程序已经在节点上运行时。
  2. 与内存相比,CPU 是一种受管制的资源。 如果没有足够的CPU,你的Pod将不会关闭并且节流机制将打开。
  3. 请求的资源和资源限制不是最小值和最大值! 通过定义所请求的资源,您可以确保应用程序运行时不会出现问题。
  4. 一个好的做法是将内存请求设置为等于内存限制。
  5. 好的安装请求 CPU <=1,如果应用程序不执行复杂的计算。
  6. 如果您请求的资源多于节点上可用的资源,则 Pod 将永远不会被调度到该节点。
  7. 要确定请求的资源/资源限制的正确数量,请使用负载测试和监控。

我希望这篇文章可以帮助您理解资源限制的基本概念。 您将能够将这些知识应用到您的工作中。

祝你好运!

还有什么要读的:

  1. SRE 可观察性:命名空间和指标结构.
  2. 90 多种 Kubernetes 有用工具:部署、管理、监控、安全等.
  3. 我们在 Telegram 中围绕 Kubernetes 的频道.

来源: habr.com

添加评论