Kubernetes集群多租户资源管理

微信公众号:运维开发故事,作者:double冬

1.概述

先讲解Pod的两个重要参数:CPU Request与Memory Request。在大多数情况下我们在定义Pod时并没有定义这两个参数,此时Kubernetes会认为该Pod所需的资源很少,并可以将其调度到任何可用的Node上。这样一来,当集群中的计算资源不很充足时,如果集群中的Pod负载突然加大,就会使某个Node的资源严重不足。
为了避免系统挂掉,该Node会选择“清理”某些Pod来释放资源,此时每个Pod都可能成为牺牲品。但有些Pod担负着更重要的职责,比其他Pod更重要,比如与数据存储相关的、与登录相关的、与查询余额相关的,即使系统资源严重不足,也需要保障这些Pod的存活,Kubernetes中该保障机制的核心如下。

  • 通过资源限额来确保不同的Pod只能占用指定的资源
  • 允许集群的资源被超额分配,以提高集群的资源利用率
  • 为Pod划分等级,确保不同等级的Pod有不同的服务质量(QoS),资源不足时,低等级的Pod会被清理,以确保高等级的Pod稳定运行

Kubernetes集群里的节点提供的资源主要是计算资源,计算资源是可计量的能被申请、分配和使用的基础资源,这使之区别于API资源(API Resources,例如Pod和Services等)。当前Kubernetes集群中的计算资源主要包括CPU、GPU及Memory,绝大多数常规应用是用不到GPU的,因此这里重点介绍CPU与Memory的资源管理问题
CPU与Memory是被Pod使用的,因此在配置Pod时可以通过参数CPU Request及Memory Request为其中的每个容器指定所需使用的CPU与Memory量,Kubernetes会根据Request的值去查找有足够资源的Node来调度此Pod,如果没有,则调度失败。

2.Pod资源使用规范

我们知道,一个pod所使用的CPU与Memory是一个动态的量,确切地说,是一个范围,跟它的负载密切相关:负载增加时,CPU和Memory的使用量也会增加。因此最准确的说法是,某个进程的CPU使用量为0.1个CPU~1个CPU,内存占用则为500MB~1GB。对应到Kubernetes的Pod容器上,cpu和Memory 分别有两个限制:

  • Requests 表示业务正常运行所需要资源 属于预留资源
  • Limit 表示业务最大使用资源 该值为不保障资源 资源足够情况下最大使用资源值

其中CPU 为可压缩资源 按照时间片进行调度,Memory 为不可压缩资源 属于硬限制资源类型,limits对应资源量的上限,即最多允许使用这个上限的资源量。由于CPU资源是可压缩的,进程无论如何也不可能突破上限,因此设置起来比较容易。对于Memory这种不可压缩资源来说,它的Limit设置就是一个问题了,如果设置得小了,当进程在业务繁忙期试图请求超过Limit限制的Memory时,此进程就会被Kubernetes杀掉。因此,Memory的Request与Limit的值需要结合进程的实际需求谨慎设置。如果不设置CPU或Memory的Limit值,会怎样呢?在这种情况下,该Pod的资源使用量有一个弹性范围,我们不用绞尽脑汁去思考这两个Limit的合理值,但问题也来了,考虑下面的例子:
Pod A的Memory Request被设置为1GB,Node A当时空闲的Memory为1.2GB,符合Pod A的需求,因此Pod A被调度到Node A上。运行3天后,Pod A的访问请求大增,内存需要增加到1.5GB,此时Node A的剩余内存只有200MB,由于PodA新增的内存已经超出系统资源,所以在这种情况下,Pod A就会被Kubernetes杀掉。
没有设置Limit的Pod,或者只设置了CPU Limit或者Memory Limit两者之一的Pod,表面看都是很有弹性的,但实际上,相对于4个参数都被设置的Pod,是处于一种相对不稳定的状态的,它们与4个参数都没设置的Pod相比,只是稳定一点而已。理解了这一点,就很容易理解Resource QoS问题了。
如果我们有成百上千个不同的Pod,那么先手动设置每个Pod的这4个参数,再检查并确保这些参数的设置,都是合理的。比如不能出现内存超过2GB或者CPU占据2个核心的Pod。最后还得手工检查不同租户(Namespace)下的Pod的资源使用量是否超过限额。为此,Kubernetes提供了另外两个相关对象:LimitRange及ResourceQuota,前者解决request与limit参数的默认值和合法取值范围等问题,后者则解决约束租户的资源配额问题。

  • CPU 相关规则如下:

单位m,10m=0.01核,1核=1000m

Requests 根据业务实际使用量进行预估填写

Limits = Requests * 20% + Requests

  • Memory 相关规则如下:

单位Mi 1024Mi=1G内存

Requests 根据业务实际使用量进行预估填写

Limits = Requests * 20% + Requests

3.Namespace资源管理规范

业务实际Requests Limit 不超过整体80% 防止业务滚动更新无足够资源创建Pod

3.1 多租户资源使用策略

通过ResourceQuota限制对应项目组资源用量

![image.png](https://www.icode9.com/i/ll/?i=img_convert/474a4cb2e0e9a7f4b6ae82301a444a02.png#clientId=u36d536b9-7e10-4&from=paste&height=282&id=u1a93447b&margin=[object Object]&name=image.png&originHeight=564&originWidth=1242&originalType=binary&ratio=1&size=82895&status=done&style=none&taskId=u3e400703-5479-4048-9788-975ceb2a474&width=621)

3.2 资源用量变更流程

![image.png](https://www.icode9.com/i/ll/?i=img_convert/770b4e74efd2495a7878b79bbbead74f.png#clientId=u36d536b9-7e10-4&from=paste&height=133&id=uc527a8bc&margin=[object Object]&name=image.png&originHeight=266&originWidth=1014&originalType=binary&ratio=1&size=69926&status=done&style=none&taskId=u07661404-7b56-435b-b5f4-832de2f1bc8&width=507)

4.资源监控及检查

4.1 资源使用监控

  • Namespace Reuqests资源使用率
sum (kube_resourcequota{type="used",resource="requests.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.cpu"}) by (resource,namespace) * 100

sum (kube_resourcequota{type="used",resource="requests.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.memory"}) by (resource,namespace) * 100
  • Namespace Limit资源使用率
sum (kube_resourcequota{type="used",resource="limits.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.cpu"}) by (resource,namespace) * 100

sum (kube_resourcequota{type="used",resource="limits.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.memory"}) by (resource,namespace) * 100

4.2 通过Grafana 进行查看

![image.png](https://www.icode9.com/i/ll/?i=img_convert/60fc1ffab409e11bd8ff36c58d946a61.png#clientId=u36d536b9-7e10-4&from=paste&height=155&id=u09b8b5e9&margin=[object Object]&name=image.png&originHeight=310&originWidth=1558&originalType=binary&ratio=1&size=121527&status=done&style=none&taskId=u81163135-8e23-4ef8-8230-561e529246f&width=779)

  • CPU请求率
sum (kube_resourcequota{type="used",resource="requests.cpu",namespace=~"$NameSpace"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.cpu",namespace=~"$NameSpace"}) by (resource,namespace)
  • 内存请求率
sum (kube_resourcequota{type="used",resource="requests.memory",namespace=~"$NameSpace"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.memory",namespace=~"$NameSpace"}) by (resource,namespace)
  • CPU限制率
sum (kube_resourcequota{type="used",resource="limits.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.cpu"}) by (resource,namespace)
  • 内存限制率
sum (kube_resourcequota{type="used",resource="limits.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.memory"}) by (resource,namespace)

4.3 集群内查看资源使用

  • 查看资源使用量
[root@k8s-dev-slave04 yaml]# kubectl describe resourcequotas -n cloudchain--staging

Name:            mem-cpu-demo

Namespace:       cloudchain--staging

Resource         Used   Hard

--------         ----   ----

limits.cpu       200m   500m

limits.memory    200Mi  500Mi

requests.cpu     150m   250m

requests.memory  150Mi  250Mi
  • 查看event事件 判断是否正常创建
[root@kevin ~]# kubectl get event -n default

LAST SEEN   TYPE      REASON         OBJECT                          MESSAGE

46m         Warning   FailedCreate   replicaset/hpatest-57965d8c84   Error creating: pods "hpatest-57965d8c84-s78x6" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi

29m         Warning   FailedCreate   replicaset/hpatest-57965d8c84   Error creating: pods "hpatest-57965d8c84-5w6lk" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi

13m         Warning   FailedCreate   replicaset/hpatest-57965d8c84   Error creating: pods "hpatest-57965d8c84-w2qvz" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi
上一篇:论文解读(node2vec)《node2vec Scalable Feature Learning for Networks》


下一篇:微积分基本定理的例子——曲面积分