k8s cpu、memory如何进行资源限制(如何避免OOMKilled?)
阿里云上万个 Kubernetes 集群大规模管理实践
Kubernetes超分与资源管理
k8s 集群容量管理 – kluster capacity
部分信息涉及机密信息,已隐藏

一、Kubernetes集群与容量管理?

Kubernetes集群是一种用于管理容器化应用程序的开源平台。它允许用户在多个主机上运行、扩展和管理容器,以便应用程序可以以高可用性和可伸缩性的方式运行。如今,数百家常设和技术社区共同构建了非常强大的云原生生态,市面上几乎所有提供云基础设施的公司都以原生形式将Kubernetes作为底层平台。阿里云ACK容器服务Kubernetes版ACK(Alibaba Cloud Container Service for Kubernetes)就是全球首批通过Kubernetes一致性认证的服务平台,也是目前交通银行行内使用的主要平台。此外腾讯自研的TKE、TCS容器平台、华为云的容器引擎CCE也都基于Kubernetes实现。

使用容器平台的理由很多,其中稳定性、效率、成本三个重要价值的实现都离不开容量管理,是Kubernetes 集群管理中非常重要的一部分。它可以确保系统中的资源得到合理的分配和使用,避免了因资源不足或浪费导致的系统运行异常或效率低下的问题。通过容量管理,可以更好地控制和优化系统资源的利用,保证Kubernetes集群的稳定性和可靠性。容量管理还可以帮助管理员对系统进行更好的规划和预测,避免因资源不足而需要紧急扩容的情况出现,从而提高了系统的可维护性和可靠性。

二、基础篇——Kubernetes的资源管理

2.1 资源分类

在 Kubernetes 中,有两个基础但是非常重要的概念:Node 和 Pod。Node 是对集群资源的抽象;Pod 是对容器的封装,是应用运行的实体。Node 提供资源,而 Pod 使用资源。资源包括计算(CPU、Memory、GPU)、存储(Disk、SSD)、网络(Network Bandwidth、IP、Ports)等资源。

这些资源可以被分为可压缩资源和不可压缩资源两类。对于可压缩资源,比如 CPU 时间片,即使 Pod 使用的 CPU 资源很多,CPU 使用也可以按照权重分配给所有 Pod 使用,虽然每个人使用的时间片减少,但不会影响程序的逻辑。而不可压缩资源,如果资源不足,也就无法继续申请资源(内存用完就是用完了),并且会导致 Pod 的运行产生无法预测的错误。

2.2 cgroup

cgroup(Control Group)是Linux内核提供的一种机制,用于对进程组进行资源限制、账户和控制。它允许管理员为一组进程分配、控制和监视系统资源,例如CPU、内存、磁盘IO和网络带宽等。因为其可以做到对 cpu,内存等资源实现精细化的控制,Kubernetes中的pod就使用了 cgroups 提供的资源限制能力来完成cpu,内存等部分的资源控制。

实现 cgroups 的主要目的是为不同用户层面的资源管理提供一个统一化的接口。从单个任务的资源控制到操作系统层面的虚拟化,cgroups 提供了四大功能:

  • 资源限制:cgroups 可以对任务是要的资源总额进行限制。比如设定任务运行时使用的内存上限,一旦超出就发 OOM。
  • 优先级分配:通过分配的 CPU 时间片数量和磁盘 IO 带宽,实际上就等同于控制了任务运行的优先级。
  • 资源统计:cgoups 可以统计系统的资源使用量,比如 CPU 使用时长、内存用量等。这个功能非常适合当前云端产品按使用量计费的方式。
  • 任务控制:cgroups 可以对任务执行挂起、恢复等操作。

2.3 超分

超分指是指在物理资源有限的情况下,通过将多个虚拟资源分配给单个容器或Pod,实现对资源的超额使用。这样可以更充分地利用可用的计算资源,提高系统的性能和容量。这一做法认为容器不会在同一时刻都处于高峰期,利用超分来达到资源在进行限制的同时又能最大化的提高资源利用率。

作为本文关注的重点,CPU是可压缩资源, 因为CPU是按时间片来轮流使用的, 而内存是不可压缩资源, 所以一般内存不超分, CPU如果使用超过Limits, cgroup会对其限流, 如果内存超了会被杀掉。

2.4 资源限制与QoS

Kubernetes围绕RequestsLimits这两个参数来进行资源的调度和QoS。

  • Requests: Pod需要的最小的资源, 注意不代表实际占用的最小的资源, 可以理解为最小预分配资源
  • Limits: Pod所能占的最大的资源

当Pod试图请求超过Limits限制的资源时,此进程会被Kubernetes杀掉。而Requests不代表实际资源, 例如PodA设置的Requests的MEM为500M, 但是实际可能启动时候只占100M内存, Requests只是预分配最小资源, 比如宿主机可以给容器用的内存有8G, 建Requests为1G内存的容器, 只能创建8个, 即 Requests <= 节点可用资源

在缺少资源导致Pod不能进入Running态, 可以通过kubectl describe命名查看Pod, 可以看到事件中有报错信息:
0/1 nodes are available: 1 Insufficient cpu

因此,Kubernetes引入三个QoS等级来应对在资源紧张,Pod负载波动时杀掉Pod的优先级:

  • Guaranteed: 如果Pod中所有Container的所有Resource的limit和request都相等且不为0
  • Burstable: 不符合Guaranteed和Best-Effort的Pod
  • Best-Effort: 如果Pod中所有容器的所有Resource的request和limit都没有赋值

这三个等级的重要程度依次降低, 即Best-Effort优先级最低, 资源不足时候最先杀掉, 而尽量保证Guaranteed。因此,对重要pod指定limit和request且都相等可以避免在资源紧张时被杀掉。

对于特定的namespace,可以使用LimitRange进行全局设置,创建一个LimitRange资源然后把其应用的某一个namespace里面:

kubectl create -f limitsrange.yaml --namespace=limittest

2.5 交通银行当前现状

理想情况下,CPU超分应控制在1:5而内存应保持1:1不进行超分较为健康,目前行内使用量较大的XX集群CPU超分比例已达到1:XX,XX集群内存超分比例已达到,尤其内存的超分较为严重,存在隐患,需要改进:

首先是内存资源,由于内存资源不应有超分行为,应尽快进行扩容保证内存分配比例的健康。这一点与目前设备资源紧张产生了较为强烈的冲突,因此引出了第三章动态资源调度的内容。
其次在超分计算方式上,为保证各项目组滚动发版需求,会留出一定冗余资源,这部分资源理论上不会与与其他资源同时达到高利用率,可以不计入超分的计算范围。

三、进阶篇——资源动态调度

3.1 思想与概念

提高计算资源分配效率:

  1. AI弹性容量
  2. 云原生分时调度
  3. 在离线混合部署

资源管理->云原生弹性伸缩(T+1day)->AI数据智能(T+10mins)->绿色计算

3.2 FinOps方法论

  1. 告知:容量智能画像、应用基线、流量驱动容量、时许预测
  2. 优化:可控弹性伸缩、最佳规格推进、集群整理、分时调度
  3. 运营:变更生命周期、优化生命周期、容量风险

3.3 AIC产品

阿里云AIC(Autonomous Intellgent Cloud)产品是一款高性能的人工智能计算实例,可以帮助用户快速构建人工智能模型和加速人工智能应用的开发和部署。基于AIC的云原生容量管理平台是一种可以实现动态扩缩容的管理平台,通过大数据学习,帮助用户根据业务负载情况自动扩展或缩减计算资源。AIC云原生容量管理平台的动态扩缩容是通过阿里云的弹性伸缩(ECS)和容器服务实现的。
以交行现在使用的阿里ACK产品为例,通过采集容器的监控数据(CPU、内存、磁盘和网络等)来实现资源使用的实时监控。根据监控数据,ACK集群能够实时了解容器的资源使用情况,通过AIC产品,对容器资源使用的历史数据进行分析和预测,从而及时采取措施优化调整资源分配:

  1. 动态扩容:在流量真正到达峰值之前,先将需要的资源准备好,避免由于资源不足造成系统崩溃和资源下降。此方案在阿里的xxx案例中运行良好,弥补了人工干预的滞后性和复杂性。
  2. 动态缩容:先摘流再缩容,保证了灰度空间,可以较好的实现无损缩容,在周期性流量升降中,避免了过度分配和浪费资源。考虑到行内实际情况,动态缩容还是存在一定风险性,不建议实行。
  3. 容量风控:AIC云原生容量管理平台还对动态扩缩容过程进行了风险控制,(增加详细介绍?)最大程度保证了扩缩容无损和业务连续性。
    考虑到生产环境的复杂性,动态扩缩容仍需要大量的历史数据和经验托底,扩缩容规则不合理可能会导致资源的浪费或不足。此外,对于需要长时间运行的应用,扩缩容可能会带来额外的成本。

四、总结

作者 Assaultcore

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注