ResourceQuota 限制可用资源总量

ResourceQuota 资源可以用来限制命名空间中各类资源的可用总量。

ResourceQuota 也是由 API 服务器中的一个准入插件实现的,该插件默认开启,在收到创建 Pod 的请求时,会检查总资源量是否超过 ResourceQuota 资源定义的量。

🦁 ResourceQuota 目前可以在下面在下面三种场景中进行限制:

  • 限制一个命名空间中 Pod 和 PVC 最多可以使用的 资源总量

  • 限制用户允许在一个命名空间中创建的 Pod、PVC、ReplicationController、Secret、ConfigMap、Service、ResourceQuota 等资源对象的 个数

限制资源总量

ResourceQuota 必须与 LimitRange 共存

⚠️ 需要注意的是,在创建 ResourceQuota 时,必须同时创建一个 LimitRange,否则在创建未明确指定 requestslimits 的 Pod 时会提示错误,因为 Kubernetes 会认为这类容器想要无限的资源,而这与 ResourceQuota 的定义是相悖的,因此会被 ResourceQuota 拒绝。所以最好同时创建一个 LimitRange 对单个 Pod 的资源申请及限制量进行校验,做一个保险。

Pod 的 CPU 和内存资源总量限制

下面展示一个限制 Pod 的 CPU 和内存资源总量限制的 YAML 描述文件,在该文件中,它限制 default 命名空间中的所有的 CPU 和 内存 资源的申请总量分别为 400m200MB,而限制总量则分别为 600m500MB

apiVersion: v1
kind: ResourceQuota    # 资源类型为 ResourceQuota
metadata:
  namespace: default    # 在 default 命名空间中起效
  name: cpu-and-mem
spec:
  hard:
    requests.cpu: 400m    # 所有 Pod 可以申请的 CPU 总量
    requests.memory: 200Mi    # 所有 Pod 可以申请的内存总量
    limits.cpu: 600m    # 所有 Pod 可以限制的 CPU 总量
    limits.memory: 500Mi    # 所有 Pod 可以限制的内存总量

PVC 可申请的存储总量限制

Pod 可以通过请求挂载 PVC 的方式实现动态存储分配,PVC 会通过 StorageClass 获取底层存储,StorageClass 会与底层的存储驱动挂钩,分配相应的存储空间。

因此 Kubernetes 在提供限制 Pod 可申请的存储总量的基础上,还实现了对 StorageClass 能够从底层存储驱动中申请的存储量的限制,便于更细粒度的进行限制。

下面展示一个限制 Pod 可申请的存储总量以及 StorageClass 可申请的存储量的限制 YAML 描述文件,限制了 Pod 能够申请的存储总量为 500GB,名为 ssd 的 StorageClass 总共可以从底层申请最多 300GB,名为 standard 的 StorageClass 总共可以从底层申请最多 1TB

apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: default    # 在 default 命名空间中起效
  name: storage
spec:
  hard:
    requests.storage: 500Gi    # 可申请的存储总量
    ssd.storageclass.storage.k8s.io/requests.storage: 300Gi    # 名为 ssd 的 StorageClass 可以从底层申请的存储总量
    standard.storageclass.storage.k8s.io/requests.storage: 1Ti    # 名为 standard 的 StorageClass 可以从底层申请的存储总量

限制可创建对象数量

目前 ResourceQuota 支持限制命名空间下 Pod、ReplicationController、Secret、ConfigMap、PVC、Service (通用类型、LoadBalancer 类型以及 NodePorts 类型) 以及 ResourceQuota 这些资源对象的数量。未来应该还会添加更多支持的对象。

下面展示一个限制创建对象数量的例子:

apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: default    # 作用于 default 命名空间中
  name: objects
spec:
  hard:
    pods: 10    # 该命名空间中最多可创建10个Pod
    replicationcontrollers: 5    # 该命名空间中最多可创建5个RC
    secrets: 10    # 该命名空间中最多可创建10个Secret
    configmaps: 10    # 该命名空间中最多可创建10个ConfigMap
    persistentvolumeclaims: 5    # 该命名空间中最多可创建5个PVC
    services: 5    # 该命名空间中最多可创建5个通用Sevice
    services.loadbalancers: 1    # 该命名空间中最多可创建1个LoadBalancer类型的Service
    services.nodeports: 2    # 该命名空间中最多可创建2个NodePort类型的Service
    ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2    # 该命名空间中最多声明2个StorageClass为ssd的PVC

根据 Pod 状态或 QoS 等级指定配额

上述都是针对命名空间下所有 Pod 进行限制的,ResourceQuota 还支持根据 Pod 的状态和 QoS 等级进行配额指定,在 ResourceQuota 中称之为作用范围,通过 spec.scopes 进行指定。

💊 目前支持的作用范围共有四种,前面两种与 QoS 等级有关,后面两种与 Pod 的状态有关:

  • BestEffort:命名空间中 Pod 中所有容器的 requestslimits 都没有指定的所有 Pod(即 QoS 优先级为 BestEffort 的 Pod);

  • NotBestEffort:命名空间中 QoS 优先级为 Burstable 或 Guarranteed 的所有 Pod;

  • Termination:命名空间中 Pod 的描述文件中指定了 spec.activeDeadlineSeconds 字段的所有 Pod;

  • NotTermination:命名空间中 Pod 的描述文件 spec.activeDeadlineSeconds 字段为空的所有 Pod;

下面展示一个具有指定作用范围的 ResourceQuota 案例。在名为 default 的命名空间中,所有 QoS 优先级为 BestEffort 并且描述文件中没有指定 spec.activeDeadlineSeconds 字段的这种 Pod 最多只能创建 4 个:

apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: default
  name: besteffort-notterminating-pods
spec:
  scopes:    # 有多个作用范围时,必须全部满足。属于 BestEffort 以及 NotTerminating 的所有 Pod
  - BestEffort
  - NotTerminating
  hard:
    pods: 4    # 最多创建4个这样的Pod

🏖 像上述案例中存在多个作用范围的情况,取交集,即必须同时属于这两个作用范围的 Pod 才能被限制住

Last updated

Was this helpful?