Kubernetes资源配额与QoS

Pod资源配额

为了防止一些应用程序无限地掠夺资源,导致机器资源被无故消耗。此时就需要对其进行资源配额,限制它所分配到的资源量

官方定义:

当多个用户或团队共享具有固定节点数目的集群时,人们会担心有人使用超过其基于公平原则所分配到的资源量。

资源配额,由 ResourceQuota 对象定义, 提供了限制每个命名空间的资源总消耗的约束。 资源配额还可以限制在命名空间中可以创建的对象数量(按 API 类型计算), 以及该命名空间中存在的 API 对象可能消耗的基础设施资源的总量。

不同的资源争用,或者资源配额的更改不会影响已经创建的资源

说白了就是,去限制一些应用程序的资源消耗量,最大只能分配多少CPU、内存等资源给它们

配额(requests)与限额(limits)

资源请求(request)

容器启动时,Pod向集群申请的最小资源量。调度器会根据该值的大小决定将它分配到哪个资源充足节点上。

---
kind: Pod
apiVersion: v1
metadata:
  name: app
spec:
  containers:
    - name: web
      image: plugins/httpd:2.4
      resources:            # 资源配额关键字
        requests:           # 资源分配
          cpu: 1500m        # CPU仅分配1500毫核
          memory: 800Mi     # 内存分配800Mi(1Mi = 1024k,1M = 1000k)
status: {}
资源限额(limits)

容器在运行时,所允许的最大资源使用量,容器使用的资源无法超过这个值:

...
      resources:            # 资源配额关键字
        limits:           # 资源分配
          cpu: 600m        # CPU仅分配1500毫核
          memory: 800Mi     # 内存分配800Mi(1Mi = 1024k,1M = 1000k)
简单地说:
  • requests是最少能拿到多少资源,是Pod的下限

  • limits是最多能拿到多少资源,是Pod的上限

注意:在设置配额和限额的时候,必须保证 limitsrequests,即下限不能超过上限,否则会报错

QoS(服务质量等级)

根据 Pod 的资源设置来决定在节点资源紧张时,哪些 Pod 应该被优先保障,哪些可能最先被限制或终止。QoS 本质上是为 Pod 分配不同的优先级,以确保关键工作负载的稳定性

Kubernetes 主要根据 Pod 中容器设置的 requests(资源请求)和 limits(资源限制)参数,自动将 Pod 划分为三个 QoS 等级。
按优先级从高到低排列为:Guaranteed(保证级)>Burstable(突发级)​ > BestEffort(尽力而为级)

就相当于高铁商务座、二等座和站票,分别对应这三个级别…

保证级(Guaranteed )

优先级最高的服务等级,就像高铁商务座一样,享受贵宾服务。

在节点资源不足的时候,这个级别会收到最高级别的保护,且不容易被消灭

配置要点:Pod 中的每一个容器都必须为 CPU 和内存同时设置 limitsrequests,并且两者的值必须完全相等

---
kind: Pod
apiVersion: v1
metadata:
  name: app1
spec:
  containers:
  - name: web
    image: plugins/nginx:1.27.5
    resources:
      requests:            # 同时设置requests和limits,并且数值完全相等...
        cpu: 200m
        memory: 200Mi
      limits:
        cpu: 200m
        memory: 200Mi

突发级(Brustable)

优先级中等,最常见的等级,跟高铁二等坐一样常见,让你有位置坐,但不给你更多的保证。这是一种弹性的资源使用模式,Pod有一个基本的requests资源保障。

在突发情况下,节点如果有更多的空闲资源,Pod可以使用这些空闲资源,但最大不能超过limits的限制

配置要点:Pod 中至少有一个容器设置了 CPU 或内存的 requestslimits

---
kind: Pod
apiVersion: v1
metadata:
  name: app1
spec:
  containers:
  - name: web
    image: plugins/nginx:1.27.5
    resources:
      requests:            # 二者至少设置一个
        cpu: 200m
        memory: 200Mi
      limits:
        cpu: 400m
        memory: 400Mi

尽力而为级(BestEffort)

优先级最低,跟坐高铁买了站票似的,有位置你就坐,没位置你只能站着。

设置了这个级别的Pod 可以尝试使用节点上任何空闲的资源,但在资源不足时,它会第一个被终止,且没有任何保证

配置要点:Pod 中的所有容器都没有指定任何 CPU 和内存的 requests和 limits

---
kind: Pod
apiVersion: v1
metadata:
  name: app1
spec:
  containers:
  - name: web
    image: plugins/nginx:1.27.5

查询QoS等级:

kubectl describe pods <Pod名称> | grep "QoS Class"

全局资源配额

全局资源配额是一种通过为集群中的每一个名称空间配置资源配额(ResourceQuota)的策略,从全局视角实现对集群资源进行总量控制和分配。

作用:防止在多人/多团队共享的集群中,因个别用户过度消耗资源导致“资源饥饿”,从而保障系统整体稳定性和资源平等分配

配置Pods数量资源配额:

---
kind: ResourceQuota
apiVersion: v1
metadata:
  name: myquotal
  namespace: default      # 资源配额作用的名称空间,使用默认命名空间
spec:
  hard:
    pods: 3               # 最多允许该名称空间有几个pod
  scopes:                 # 作用域,
  - BestEffort
关键参数:
  • spec.hard:全局资源配额的关键字段,定义各种资源使用量的上限,作用等同于limits

  • spec.scopes:作用域,定义了该资源配额的作用范围。其四种作用域如下:

    - BestEffort:仅作用于 QoS 等级为 BestEffort 的 Pod。此作用域下通常只能限制 Pod 的数量。
    - NotBestEffort:与 BestEffort相反,作用于 Burstable 和 Guaranteed 等级。此作用域下可以限制 CPU、内存等计算资源。
    
    - Terminating:仅作用于那些在配置中明确设置了 activeDeadlineSeconds字段的 Pod(即有计划生命周期的 Pod)。
    - NotTerminating:作用于那些没有设置 activeDeadlineSeconds的 Pod(通常是长期运行的服务)。
    
查看设置好的资源配额:
[root@master ~]# kubectl get resourcequota
NAME       AGE   REQUEST     LIMIT
myquotal   50s   pods: 3/3  
[root@master ~]# kubectl describe namespace default 
Name:         default
Labels:       kubernetes.io/metadata.name=default
Annotations:  <none>
Status:       Active

Resource Quotas
  Name:    myquotal
  Scopes:  BestEffort
  * Matches all pods that do not have resource requirements set. These pods have a best effort quality of service.
  Resource  Used  Hard
  --------  ---   ---
  pods      3     3

现在,所有的default命名空间下的所有QoS为BestEffort级的Pod都被设置了限额

设置内存和CPU资源限额:

---
kind: ResourceQuota
apiVersion: v1
metadata:
  name: myquotal2
  namespace: default      
spec:
  hard:
    pods: 3               
    cpu: 2300             # CPU限制最大2300毫核(1000毫核=1核)
    memory: 3Gi           # 内存限制最大使用3Gi
  scopes:                 # 注意作用域是NotBestEffort,这个作用域才能对CPU和内存起到限制作用
  - NotBestEffort

查看配额策略:

[root@master ~]# kubectl get resourcequota
NAME       AGE   REQUEST                                 LIMIT
myquota2   31s   cpu: 0/2300, memory: 0/3Gi, pods: 0/3   
myquotal   44m   pods: 3/3                               
[root@master ~]# kubectl describe namespaces default 
Name:         default
Labels:       kubernetes.io/metadata.name=default
Annotations:  <none>
Status:       Active

Resource Quotas
  Name:    myquota2
  Scopes:  NotBestEffort
  * Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
  Resource  Used  Hard
  --------  ---   ---
  cpu       0     2300
  memory    0     3Gi
  pods      0     3
  Name:     myquotal
  Scopes:   BestEffort
  * Matches all pods that do not have resource requirements set. These pods have a best effort quality of service.
  Resource  Used  Hard
  --------  ---   ---
  pods      3     3

No LimitRange resource.

可以发现,增加了对cpu和内存的限制

更多推荐