Kubernetes 放置导致 pods 永远重启

Kubernetes placement causes pods to restart forever

我们有 2 个节点,每个节点有 96 GB RAM。 计划是我们的 pods 将从一个节点获取 90.5 GB RAM,从另一个节点获取 91 GB。 实际发生的是 pods 从其中一个节点占用 93.5 GB,从另一个节点占用 88 GB。 这导致 pods 永远重新启动,应用程序从未达到 运行ning 状态。

背景: 我们是 kubernetes 的新手,在 AWS 上的 eks 集群上使用版本 1.14 (v1.14.9-eks-658790)。 目前,我们有 pods 种不同尺寸的产品,它们加在一起构成我们产品的 1 件。在测试设置中,我们希望使用 1 个单元,而在生产中使用多个单元。 给节点加钱,降低pod limits或者副本数,都是我们的问题。

关于 pods 的详细信息:

+-------------+--------------+-----------+-------------+
|  Pod name   | Mem requests | pod limit | # of copies |
+-------------+--------------+-----------+-------------+
| BIG-OK-POD  | 35           | 46        | 2           |
| OK-POD      | 7.5          | 7.5       | 4           |
| A-OK-POD    | 6            | 6         | 8           |
| WOLF-POD    | 5            | 5         | 1           |
| WOLF-B-POD  | 1            | 1         | 1           |
| SHEEP-POD   | 2            | 2         | 1           |
| SHEEP-B-POD | 2            | 2         | 1           |
| SHEEP-C-POD | 1.5          | 1.5       | 1           |
+-------------+--------------+-----------+-------------+

我们不关心 pods 运行 在哪里,我们只希望节点能够处理内存需求而不会失败。

我重命名了 pods 以便更容易遵循我们的预期。

预期排名:

我们预计狼 pods 会在一个节点上,羊 pods 在另一个节点上,而 OK pods 会在节点之间分开。

Node 1:
+-------------+-----------+-------------+----------------+
|  Pod name   | pod limit | # of copies | combined limit |
+-------------+-----------+-------------+----------------+
| BIG-OK-POD  | 46        | 1           |             46 |
| OK-POD      | 7.5       | 2           |             15 |
| A-OK-POD    | 6         | 4           |             24 |
| WOLF-POD    | 5         | 1           |              5 |
| WOLF-B-POD  | 1         | 1           |              1 |
+-------------+-----------+-------------+----------------+
|                                       | TOTAL: 91      |
+-------------+-----------+-------------+----------------+

Node 2:

+-------------+-----------+-------------+----------------+
|  Pod name   | pod limit | # of copies | combined limit |
+-------------+-----------+-------------+----------------+
| BIG-OK-POD  | 46        | 1           | 46             |
| OK-POD      | 7.5       | 2           | 15             |
| A-OK-POD    | 6         | 4           | 24             |
| SHEEP-POD   | 2         | 1           | 2              |
| SHEEP-B-POD | 2         | 1           | 2              |
| SHEEP-C-POD | 1.5       | 1           | 1.5            |
+-------------+-----------+-------------+----------------+
|                                       | TOTAL: 90.5    |
+-------------+-----------+-------------+----------------+

实际展示位置:

Node 1:
+-------------+-----------+-------------+----------------+
|  Pod name   | pod limit | # of copies | combined limit |
+-------------+-----------+-------------+----------------+
| BIG-OK-POD  | 46        | 1           | 46             |
| OK-POD      | 7.5       | 2           | 15             |
| A-OK-POD    | 6         | 4           | 24             |
| WOLF-POD    | 5         | 1           | 5              |
| SHEEP-B-POD | 2         | 1           | 2              |
| SHEEP-C-POD | 1.5       | 1           | 1.5            |
+-------------+-----------+-------------+----------------+
|                                       | TOTAL: 93.5    |
+-------------+-----------+-------------+----------------+

Node 2:
+-------------+-----------+-------------+----------------+
|  Pod name   | pod limit | # of copies | combined limit |
+-------------+-----------+-------------+----------------+
| BIG-OK-POD  | 46        | 1           | 46             |
| OK-POD      | 7.5       | 2           | 15             |
| A-OK-POD    | 6         | 4           | 24             |
| WOLF-B-POD  | 1         | 1           | 1              |
| SHEEP-POD   | 2         | 1           | 2              |
+-------------+-----------+-------------+----------------+
|                                       | TOTAL: 88      |
+-------------+-----------+-------------+----------------+

有没有办法告诉 kubernetes 节点应该为节点本身留出 4 GB 的内存?

阅读 Marc ABOUCHACRA 的回答后,我们尝试更改 system-reserved=memory(设置为 0.2Gi),但对于高于 0.3Gi 的任何值(0.5Gi、1Gi、2Gi、3Gi 和 4Gi), pods 永远停留在挂起状态。

更新:我们找到了一种方法来减少一些 pods 的限制,现在系统已启动并稳定(即使其中一个节点处于 99%)。我们无法让 K8s 启动预览配置,我们仍然不知道为什么。

每种资源类型都有两个资源说明符。

  1. 资源请求
  2. 资源限制

资源请求指定 pod 应保留的特定资源(CPU 或内存)的数量。 pods 可以使用比请求更多的资源 - 但不能超过资源限制。

根据 Kubernetes 文档:

When you create a Pod, the Kubernetes scheduler selects a node for the Pod to run on. Each node has a maximum capacity for each of the resource types: the amount of CPU and memory it can provide for Pods. The scheduler ensures that, for each resource type, the sum of the resource requests of the scheduled Containers is less than the capacity of the node. Note that although actual memory or CPU resource usage on nodes is very low, the scheduler still refuses to place a Pod on a node if the capacity check fails. This protects against a resource shortage on a node when resource usage later increases, for example, during a daily peak in request rate.

这是资源请求和限制的典型配置。

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

Kubernetes 让您配置服务器以便为系统守护进程预留资源。

为此,您需要配置 kubelet 代理。这是一个 per/node 配置。
所以如果你想在一个节点上预留 4Gb 的内存,你需要在这个节点上配置 kubelet agent,选项如下:

--system-reserved=memory=4Gi

您可以在 official documentation

中找到更多相关信息

您在同一个“堆栈溢出问题”中触及了几个主题。

主题 1.

Is there a way to tell kubernetes that the Node should leave 4 GB of memory to the node itself? background: ... version 1.14 on an eks cluster

Official doc 主题上说它是可配置的,如果你的 Kubernetes 服务器是 1.8 或更高版本。

GiHub 上有一个关于“--kube-reserved 和--system-reserved 不工作 #72762”的旧线程,这也值得检查。

还有一个非常全面的 article,指定了如何防止关键系统和 Kubernetes 服务的资源匮乏。

主题 2。

We expected the the wolf pods will be on one node, and the sheep pods on the other

您可以约束一个 Pod to only be able to run on particular Node(s) , or to prefer to run on particular nodes. There are several ways to do this, and the recommended approaches all use label selectors 来进行选择。

nodeSelector是节点选择约束的最简单推荐形式。 nodeSelector 是 PodSpec 的一个字段。它指定了 key-value 对的映射。为了使 pod 有资格在节点上 运行,节点必须将每个指示的 key-value 对作为标签(它也可以有额外的标签)。最常见的用法是一对 key-value。

while the OK pods will be splitted up between the nodes.

Inter-pod affinity 和 anti-affinity 允许您限制您的 pod 有资格被调度的节点 based on labels on pods that are already running on the node 而不是基于节点上的标签。 规则的形式是“如果 X 已经 运行 一个或多个 pods 满足规则 Y".

主题 3.

It sounds like it could work for the unit of 2 nodes use case I shared in detail, but for production we have many nodes, and we rather not configure them one by one

  • 如果您想自定义放置您的pods(“狼”在奇数节点上,“羊”在偶数节点上,只有一个 OK 实例,A-OK,BIG-OK 每个节点)。
  • “我们宁愿不一个一个地配置它们”- 有很多方法可以管理 infrastructure/labels/deployments 但这是一个单独的问题。