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

简介: 这篇是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搭建和管理企业级网站应用
相关文章
|
5天前
|
存储 Kubernetes 对象存储
部署DeepSeek但GPU不足,ACK One注册集群助力解决IDC GPU资源不足
借助阿里云ACK One注册集群,充分利用阿里云强大ACS GPU算力,实现DeepSeek推理模型高效部署。
|
1月前
|
弹性计算 运维 Kubernetes
使用ACK Edge统一管理多地域的ECS资源
本文介绍如何使用ACK Edge来管理分布在多个地域的ECS资源。
|
1月前
|
人工智能 运维 监控
容器服务Kubernetes场景下可观测体系生产级最佳实践
阿里云容器服务团队在2024年继续蝉联Gartner亚洲唯一全球领导者象限,其可观测体系是运维的核心能力之一。该体系涵盖重保运维、大规模集群稳定性、业务异常诊断等场景,特别是在AI和GPU场景下提供了全面的观测解决方案。通过Tracing、Metric和Log等技术,阿里云增强了对容器网络、存储及多集群架构的监控能力,帮助客户实现高效运维和成本优化。未来,结合AI助手,将进一步提升问题定位和解决效率,缩短MTTR,助力构建智能运维体系。
|
2月前
|
Kubernetes 算法 调度
阿里云 ACK FinOps成本优化最佳实践
本文源自2024云栖大会梁成昊演讲,讨论了成本优化策略的选择与实施。文章首先介绍了成本优化的基本思路,包括优化购买方式、调整资源配置等基础策略,以及使用弹性、资源混部等高级策略。接着,文章详细探讨了集群优化和应用优化的具体方法,如使用抢占式实例降低成本、通过资源画像识别并优化资源配置,以及利用智能应用弹性策略提高资源利用效率。
|
2月前
|
Kubernetes 容灾 调度
阿里云 ACK 高可用稳定性最佳实践
本文整理自2024云栖大会刘佳旭的演讲,主题为《ACK高可用稳定性最佳实践》。文章探讨了云原生高可用架构的重要性,通过Kubernetes的高可用案例分析,介绍了ACK在单集群高可用架构设计、产品能力和最佳实践方面的方法,包括控制面和数据面的高可用策略、工作负载高可用配置、企业版容器镜像服务高可用配置等内容,旨在帮助企业构建更加可靠和高效的应用运行环境。
|
3月前
|
Kubernetes 监控 API
深入解析Kubernetes及其在生产环境中的最佳实践
深入解析Kubernetes及其在生产环境中的最佳实践
121 1
|
3月前
|
存储 运维 Kubernetes
K8s业务迁移最佳实践: 灵活管理资源备份与调整策略,实现高效简便的应用恢复
在当今快速变化的云原生领域,Kubernetes(K8s)集群的运维面临着诸多挑战,其中灾备与业务迁移尤为关键。ACK备份中心支持丰富的资源调整策略,在数据恢复阶段即可自动适配目标集群环境,确保业务无缝重启。
|
3月前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
4月前
|
JSON 运维 Kubernetes
|
4月前
|
NoSQL 关系型数据库 Redis
高可用和性能:基于ACK部署Dify的最佳实践
本文介绍了基于阿里云容器服务ACK,部署高可用、可伸缩且具备高SLA的生产可用的Dify服务的详细解决方案。

热门文章

最新文章