QoS服务质量等级Limits与Requests

1.简介

QoS(Quality of Service),大部分译为“服务质量等级”,又译作“服务质量保证”,是作用在 Pod 上的一个配置,当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS 等级,可以是以下等级之一:

  • Guaranteed:Pod 里的每个容器都必须有内存/CPU 限制和请求,而且值必须相等。
  • Burstable:Pod 里至少有一个容器有内存或者 CPU 请求且不满足 Guarantee 等级的要求,即内存/CPU 的值设置的不同。
  • BestEffort:容器必须没有任何内存或者 CPU 的限制或请求。

该配置不是通过一个配置项来配置的,而是通过配置 CPU/内存的 limits 与 requests 值的大小来确认服务质量等级的。使用 kubectl get pod -o yaml 可以看到 pod 的配置输出中有 qosClass 一项。该配置的作用是为了给资源调度提供策略支持,调度算法根据不同的服务质量等级可以确定将 pod 调度到哪些节点上。

Limits和Requests是重要的配置,主要包含CPU和内存的配置。

Kubernetes将Limits定义为一个容器使用的最大资源量,这意味着容器的消耗量永远不能超过所显示的内存量或CPU量。

另一方面,Requests是指为容器保留的资源的最小保证量。

例如,下面这个 YAML 配置中的 Pod 资源配置部分设置的服务质量等级就是 Guarantee

spec:
  containers:
    ...
    resources:
      limits:
        cpu: 100m
        memory: 128Mi
      requests:
        cpu: 100m
        memory: 128Mi

下面的 YAML 配置的 Pod 的服务质量等级是 Burstable

spec:
  containers:
    ...
    resources:
      limits:
        memory: "180Mi"
      requests:
        memory: "100Mi"

1.1 QoS 优先级

三种 QoS 优先级,从高到低(从左往右)

Guaranteed --> Burstable --> BestEffort

1.2 Kubernetes 资源回收策略

Kubernetes 资源回收策略:当集群监控到 node 节点内存或者CPU资源耗尽时,为了保护node正常工作,就会启动资源回收策略,通过驱逐节点上Pod来减少资源占用。

三种 QoS 策略被驱逐优先级,从高到低(从左往右)

BestEffort --> Burstable --> Guaranteed

使用建议

  • 如果资源充足,可以将 pod QoS 设置为 Guaranteed
  • 不是很关键的服务 pod QoS 设置为 Burstable 或者 BestEffort。比如 filebeat、logstash、fluentd等。

2.案例

下面这个deployment,我们需要为两个不同的容器在CPU和内存上设置Limits和Requests:

kind: Deployment
apiVersion: apps/v1
…
template:
  spec:
    containers:
      - name: redis
        image: redis:5.0.9
        resources:
          limits:
            memory: 600Mi
            cpu: 1
          requests:
            memory: 300Mi
            cpu: 500m
      - name: busybox
        image: busybox:1.28
        resources:
          limits:
            memory: 200Mi
            cpu: 300m
          requests:
            memory: 100Mi
            cpu: 100m
  1. 如果Redis容器试图分配超过600MB的RAM,它将被OOM杀死,很可能使pod失败。
  2. 如果Redis试图在每1s内使用超过1的CPU,它将遭受CPU节流,导致性能下降。
  3. 如果Busybox容器试图分配超过200MB的RAM,它将被OOM杀死,导致一个失败的Pod。
  4. 如果Busybox试图每1s使用超过300m的CPU,它将遭受CPU节流,导致性能下降。

3.硬件特性

3.1 CPU特性

CPU是一种可压缩的资源,这意味着它可以被拉伸,以满足所有的需求。如果进程要求太多的CPU,其中一些将被节制。

CPU代表计算处理时间,以核为单位。

  • 你可以用毫微米(m)来表示比一个核心更小的数量(例如,500m是半个核心)
  • 最小的数量是1m
  • 一个节点可能有一个以上的核心可用

3.2 内存的特性

内存是一种不可压缩的资源,意味着它不能像CPU那样被拉伸。如果一个进程没有得到足够的内存来工作,这个进程就会被杀死。

在Kubernetes中,内存的单位是字节。

  • 你可以用,E,P,T,G,M,k来代表Exabyte,Petabyte,Terabyte,Gigabyte,Megabyte和kilobyte,尽管只有最后四个是常用的。(例如,500M, 4G)
  • 警告:不要用小写的m表示内存(这代表Millibytes,低得离谱)
  • 你可以用Mi来定义Mebibytes,其余的也可以用Ei、Pi、Ti来定义(例如,500Mi)

4.资源限制

4.1 Namespace ResourceQuata

通过ResourceQuota,你可以为整个命名空间设置一个内存或CPU限制,确保其中的实体不能消耗超过这个数量。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-mem-demo-1
  namespace: default
spec:
  hard:
    requests.cpu: 2
    requests.memory: 1Gi
    limits.cpu: 3
    limits.memory: 2Gi

列出一个命名空间的当前ResourceQuota:

kubectl get resourcequota -n <namespace>

4.2 Namespace LimitRange

LimitRanges是一种Kubernetes策略,它限制了命名空间中每个实体的资源设置。

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default:
      cpu: 500m
    defaultRequest:
      cpu: 500m
    min:
      cpu: 100m
    max:
      cpu: "1"
    type: Container
  • default。如果没有指定,创建的容器将有这个值。
  • min: 创建的容器不能有比这更小的限制或请求。
  • max: 创建的容器不能有大于此值的限制或请求。