如何为 PostgreSQL 设置 Kubernetes CPU 和内存

Sal*_*elo 1 postgresql kubernetes

我有一个带有 Patroni 的三个节点的 PostgreSQL 集群。该集群管理着非常高的工作负载,因此,它在生产环境中运行在裸机上。我们需要将此基础设施迁移到 Kubernetes(出于多种原因),我正在使用 PgBench 执行一些性能测试。首先,我比较了裸机和虚拟机,发现性能下降非常小。然后我比较了 VSI 和 Kubernetes,以了解 K8s 增加的开销。

现在我正在尝试微调CPU和内存。K8s 在具有 48 个 vCPU 和 192 Gb 的工作节点上运行。然而,部署 PostgreSQL 后我仍然看到:

NAME                                     CPU(cores)   MEMORY(bytes)   
postgresql-deployment-5c98f5c949-q758d   2m           243Mi           
Run Code Online (Sandbox Code Playgroud)

即使我将以下内容分配给 PostgreSQL 容器:

resources:
  requests:
    memory: 64Gi
  limits:
    memory: 64Gi
Run Code Online (Sandbox Code Playgroud)

如果我跑:

kubectl top pod <pod name> -n <namespace>

我得到以下信息:

NAME                                     CPU(cores)   MEMORY(bytes)   
postgresql-deployment-5c98f5c949-q758d   2m           244Mi           
Run Code Online (Sandbox Code Playgroud)

即使结果如下,K8s 仪表板也会出现相同的情况:

kubectl describe pod <pod name> -n <namespace>
Run Code Online (Sandbox Code Playgroud)

显示 Pod 在保证 QoS 和 64Gi RAM 的情况下运行以用于请求和限制。

这应该如何运作?

我不明白的另一件事是CPUlimitrequested. 我希望输入这样的内容:

resources:
  requests:
    cpu: 40
    memory: 64Gi
  limits:
    cpu: 40
    memory: 64Gi
Run Code Online (Sandbox Code Playgroud)

我预计为我的容器保留 40 个 vCPU,但在部署过程中,当我运行 时,我发现节点上的 CPU 不足kubectl describe pod <pod name> -n <namespace>。我可以使用的最大值是 1。

这应该如何运作?

显然,我阅读了文档并搜索了不同的示例,但是当我将其付诸实践时,我看到的测试结果与理论不同。我知道我错过了一些东西。

Luk*_*jun 5

这是一个很好的问题,今年早些时候我也花了一些时间才根据经验找到答案。

重要的是要理解请求对容器的资源使用没有实际影响。您可以通过连接到您的服务器并运行htopkubectl top像您所做的那样进行检查,您会看到即使您定义requests: memory: 64Gi只使用了 244Mi 。

请求的主要目的是影响调度行为。当 Kubernetes Scheduler 寻找合适的 Node 来在其上放置新 Pod 时,它会检查节点当前请求的 CPU 和内存。您可以通过运行以下命令自行检查节点的当前状态。

$ kubectl describe node worker01
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                200m (10%)   1100m (55%)
  memory             506Mi (13%)  2098Mi (54%)
  ephemeral-storage  0 (0%)       0 (0%)
  hugepages-1Gi      0 (0%)       0 (0%)
  hugepages-2Mi      0 (0%)       0 (0%) 
Run Code Online (Sandbox Code Playgroud)

如果请求(CPU 或内存)超过 100%,则 Pod 无法被调度并进入 Pending 状态。

设置正确的请求可能非常棘手,如果将它们设置为高,您将无法有效地使用节点的资源,因为您无法调度那么多 Pod,如果将它们设置为低,您将面临应用程序不断崩溃或在性能峰值期间节流。

限制的主要目的是控制 Pod 的最大资源使用量。

由于 CPU 可以被压缩,Kubernetes 将确保您的容器获得它们请求的 CPU,并限制其余的 CPU。内存无法压缩,因此 Kubernetes 需要开始决定在节点内存不足时终止哪些容器[1]

因此,如果容器超过其限制,它将被终止或限制。这导致我公司的最佳实践是不对集群中的数据库施加限制。

引用的博客文章帮助我获得了一些很好的见解:
[1] https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits
[2] https ://sysdig.com/blog/kubernetes-limits-requests/