Kubernetes最佳实践(四):资源请求和限制

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 这篇是Google Developer Advocate Sandeep Dinesh关于如何充分利用Kubernetes环境的七部分视频和博客系列的第四部分。当Kubernetes调度Pod时,容器是否有足够的资源来实际运行是很重要的。
这篇是Google Developer Advocate Sandeep Dinesh 关于如何充分利用Kubernetes环境的七部分视频和博客系列的第四部分。

当Kubernetes调度Pod时,容器是否有足够的资源来实际运行是很重要的。 如果大型应用程序被调度到资源有限的节点上,则节点可能会耗尽内存或CPU资源,并且可能会停止工作!

应用程序有可能占用比其应占有的资源更多的资源。 这可能是因为一个团队调整了更多的副本,而不是人工减少延迟(嘿,调整更多副本比让你的代码更高效容易得多!),或者一个错误的配置修改使CPU占用100%,进而导致程序失去控制。 无论问题是由糟糕的开发人员,或者糟糕的代码,亦或是运气不好引起的,重要的是你能掌控你自己。

在本篇Kubernetes最佳实践中,让我们来看看如何使用资源请求和限制来解决这些问题。

请求和限制


请求和限制是Kubernetes用于控制CPU和内存等资源的机制。 请求是保证容器能够得到的资源。 如果容器请求资源,Kubernetes会将其调度到可以为其提供该资源的节点上。 另一方面,限制则是确保容器的资源请求永远不会超过某个值。 容器只允许达到限制设定的资源值,无法获得更多资源。


重要的是要记住,限制永远不会低于请求。 如果你试试这个,Kubernetes将抛出一个错误,不会让你运行容器。

请求和限制基于单个容器。 虽然Pod通常包含一个容器,但通常也会看到Pods包含多个容器。 Pod中的每个容器都有自己的限制和请求,但由于Pod总是被认为是一个组,因此您需要将组内每个容器的限制和请求加在一起以获取Pod的聚合值。

要控制容器可以拥有的请求和限制,可以在Container级别和Namespace级别设置配额。 如果您想了解有关命名空间的更多信息,请参阅我们博客系列中的 上一篇文章

让我们看看这些是如何工作的。

容器设置

有两种类型的资源:CPU和内存。 Kubernetes调度程序使用这些来确定运行Pod的位置(即哪个节点)。

请点击这里获取这些内容介绍的相关文档

如果您是在 Google Kubernetes Engine 中运行,则默认名称空间已经为您设置了一些请求和限制。
1.png

这些默认设置仅仅适用于 Hello World 应用,更改成适合您的应用非常重要。

资源的典型 Pod spec 可能看起来像这样。 这个Pod有两个容器:
2.png

Pod中的每个容器都可以设置自己的请求和限制,这些都是附加的设置。 因此在上面的示例中,Pod的总请求为 500 mCPU ,内存为 128 MiB ,总需求为 1 CPU 256MiB

CPU

CPU资源以毫秒定义。 如果您的容器需要运行两个完整的核心,那么您将设置值 2000m 。 如果您的容器只需要 1/4 的核心,那么您将设置一个 250m 的值。

关于CPU请求要记住的一件事是,如果您输入的值大于最大节点的核心数,则永远不会调度您的Pod。 假设您有一个需要四个核心的Pod,但您的Kubernetes群集由双核VM组成——您的Pod将永远不会被调度!

除非您的应用程序专门用于利用多个核心(科学计算和某些数据库),否则通常最好将CPU请求保持在 1 或更低,并运行更多副本以扩展它。 这为系统提供了更大的灵活性和可靠性。

就CPU限制而言,事情其实很有趣。 CPU被认为是 可压缩 资源。 如果您的应用程序开始达到您的CPU限制,Kubernetes会开始限制您的容器。 这意味着CPU将受到人为限制,使您的应用程序性能可能更差! 但是,它不会被终止或退出。 您可以使用 Liveness 探针的运行状况检查来确保性能未受影响。

内存

内存资源以字节为单位定义。 通常,你给内存一个 mebibyte 值(这基本上与兆字节相同),实际上你可以提供从字节到PB的任何单位。

和CPU一样,如果您输入的内存请求大于节点上的内存量,则你的Pod永远不会被调度。

与CPU资源不同,内存无法压缩。 因为没有办法限制内存使用量,如果容器超过其内存限制,它将被终止。 如果您的Pod由 Deployment StatefulSet DaemonSet 或其他类型的控制器管理,则控制器会轮转替换。

节点

请务必记住,您无法设置大于节点提供的资源的请求。 例如,如果您拥有一个双核群集,具有 2.5 核心请求的Pod则永远不会被调度到这里! 您可以在 此处 找到 Kubernetes Engine VM 相关的文档资源。

命名空间设置

在一个理想的世界里,Kubernetes的容器设置足以照顾好一切,但这个世界是一个黑暗而可怕的地方。 人们很容易忘记设置资源限制,或者流氓团队可以设置非常高的请求和限制,并占用超过他们公平份额的群集。

要防止出现这些情况,可以在命名空间级别设置 ResourceQuotas LimitRanges

ResourceQuotas

创建命名空间后,可以使用 ResourceQuotas 将其锁定。ResourceQuotas非常强大,但我们只看看如何使用它们来限制CPU和内存资源的使用。

资源配额可能如下所示:
3.png

看一下这个例子,你可以看到有四个部分。 配置每个部分都是可选的。

requests.cpu 是命名空间中所有容器的最大组合CPU请求(以毫秒为单位)。 在上面的示例中,您可以拥有50个具有 10m 请求的容器,5个具有 100m 请求的容器,甚至一个具有 500m 请求的容器。 只要命名空间中请求的总CPU和小于 500m

requests.memory 是命名空间中所有容器的最大组合内存请求。 在上面的示例中,您可以拥有50个具有 2MiB 请求的容器,5个具有 20MiB 请求的容器,甚至是具有 100MiB 请求的单个容器。 只要命名空间中请求的总内存小于 100MiB

limits.cpu 是命名空间中所有容器的最大组合CPU限制。 它就像 requests.cpu ,但是这里指的是限制。

limits.memory 是命名空间中所有容器的最大组合内存限制。 它就像 requests.memory ,但是同样地这里指的是限制。

如果您使用的是生产和开发命名空间(与每个团队或服务的命名空间不同),则常见的模式是在生产命名空间上没有配额,在开发命名空间上则是没有严格的配额。 这使得生产能够在流量激增的情况下获取所需的所有资源。

LimitRange

您还可以在命名空间中创建 LimitRange 。 与命名空间作为整体查看的配额不同, LimitRange 适用于单个容器。 这有助于防止人们在命名空间内创建超小容器或超大容器。

LimitRange 可能如下所示:
4.png

看一下这个例子,你可以看到有四个部分。 同样,设置每个部分都是可选的。

default section 设置容器中容器的默认限制。 如果在 limitRange 中设置这些值,则任何未明确设置这些值的容器都将被分配默认值。

defaultRequest section 设置Pod中容器的默认请求。 如果在 limitRange 中设置这些值,则任何未明确设置这些值的容器都将被分配默认值。

max section 将设置Pod中容器可以设置的最大限制。 默认部分不能高于此值。 同样,在容器上设置的限制不能高于此值。 请务必注意,如果设置了此值且默认部分未设置,则任何未自行显式设置这些值的容器都将被指定为最大值作为限制。

min section 设置Pod中容器可以设置的最小请求。 defaultRequest 部分不能低于此值。 同样,在容器上设置的请求也不能低于此值。 请务必注意,如果设置了此值且 defaultRequest 部分未设置,则min值也将成为 defaultRequest 值。

Kubernetes Pod的生命周期

Kubernetes调度程序使用这些资源请求来运行您的工作负载。 了解其工作原理非常重要,这样您才能正确调整容器。

假设您想要在群集上运行Pod。 假设 Pod Spec 有效,Kubernetes调度程序将使用 round-robin 负载平衡来选择节点来运行您的工作负载。

注意 :例外情况是,如果使用 nodeSelector 或类似机制强制Kubernetes在特定位置安排Pod。 使用 nodeSelector 时仍会发生资源检查,但Kubernetes只会检查具有所需标签的节点。

然后Kubernetes检查节点是否有足够的资源来满足Pod容器上的资源请求。 如果没有,则移动到下一个节点。

如果系统中的所有节点都没有剩余资源来填充请求,那么Pod将进入“挂起”状态。 通过使用节点自动缩放器( Node Autoscaler )等Kubernetes Engine功能,Kubernetes Engine可以自动检测此状态并自动创建更多节点。 如果有多余的容量,自动缩放器( autoscaler )也可以减少和删除节点,以节省您的钱!

但限制怎么处理? 如您所知,限制必须高于请求。 如果您有一个节点,其中所有容器限制的总和实际上高于机器上可用的资源,该怎么办?

在这一点上,Kubernetes进入了一种被称为“过度使用状态”( overcommitted state )的状态。这是事情变得有趣的地方。 由于CPU可以被压缩,因此Kubernetes将确保您的容器获得他们请求的CPU并且将限制其余部分。 内存无法压缩,因此如果Node耗尽内存,Kubernetes需要开始决定终止哪些容器。

让我们想象一下我们有一台机器内存不足的情况。 Kubernetes会做什么?

注意:Kubernetes 1.9及以上版本如下。 在以前的版本中,它使用稍微不同的过程。 请参阅 此文档 以获得深入的解释。

Kubernetes寻找使用比他们要求的更多资源的Pod。 如果您的Pod的容器没有请求,那么默认情况下它们使用的数量超过了他们的要求,因此这些是终止的主要候选者。 其他主要候选人是已经超过他们的要求但仍然在他们的限制之下的容器。

如果Kubernetes发现多个已经超过其请求的Pod,则它将按Pod的优先级对这些进行排名,并首先终止最低优先级的Pod。 如果所有Pod具有相同的优先级,Kubernetes将终止最多资源请求的Pod。

在非常罕见的情况下,Kubernetes可能会被迫终止仍在其请求范围内的Pod。 当关键系统组件(如kubelet或Docker)开始占用比为它们保留的资源更多的资源时,就会发生这种情况。

结论

虽然您的Kubernetes集群可以在不设置资源请求和限制的情况下正常工作,但随着团队和项目的增长,您将开始遇到稳定性问题。 添加对您的Pod和命名空间的请求和限制只需要一点额外的努力,并且可以避免您遇到许多令人头疼的问题!

本文转自DockOne-Kubernetes最佳实践(四):资源请求和限制

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
20天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
3月前
|
Kubernetes 监控 调度
在K8S中,DaemonSet类型资源特性?
在K8S中,DaemonSet类型资源特性?
|
1月前
|
JSON 运维 Kubernetes
|
1月前
|
NoSQL 关系型数据库 Redis
高可用和性能:基于ACK部署Dify的最佳实践
本文介绍了基于阿里云容器服务ACK,部署高可用、可伸缩且具备高SLA的生产可用的Dify服务的详细解决方案。
|
2月前
|
Kubernetes Docker 微服务
构建高效的微服务架构:基于Docker和Kubernetes的最佳实践
在现代软件开发中,微服务架构因其灵活性和可扩展性而受到广泛青睐。本文探讨了如何利用Docker和Kubernetes来构建高效的微服务架构。我们将深入分析Docker容器的优势、Kubernetes的编排能力,以及它们如何结合实现高可用性、自动扩展和持续部署。通过具体的最佳实践和实际案例,读者将能够理解如何优化微服务的管理和部署过程,从而提高开发效率和系统稳定性。
|
3月前
|
Kubernetes 安全 数据安全/隐私保护
Kubernetes 安全性最佳实践
【8月更文第29天】随着容器化和微服务架构的普及,Kubernetes 已成为管理容器化应用的标准平台。然而,随着 Kubernetes 的广泛采用,其安全性问题也日益受到关注。本文将深入探讨 Kubernetes 的安全最佳实践,并通过具体的代码示例来展示如何保护 Kubernetes 集群免受攻击。
175 2
|
3月前
|
Kubernetes jenkins 持续交付
Kubernetes CI/CD 集成:持续交付的最佳实践
【8月更文第29天】随着微服务架构和容器化的普及,Kubernetes 成为了运行容器化应用的事实标准。为了确保应用能够快速迭代并稳定发布,持续集成/持续部署(CI/CD)流程变得至关重要。本文将介绍如何将 Kubernetes 集成到 CI/CD 流程中,并提供一些最佳实践。
271 1
|
3月前
|
存储 Kubernetes 数据中心
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
|
3月前
|
边缘计算 人工智能 Kubernetes
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
32 1
|
3月前
|
存储 Kubernetes API