简介

在k8s集群中为了能够使系统正常稳定运行,通常会限制Pod的资源使用情况,在k8s集群中如果有一个程序出现异常,并占用大量的系统资源。如果未对该Pod进行资源限制的话,可能会影响其他的Pod。

k8s常见的资源管理方式:计算资源管理(Compute Resources)、资源的配置范围管理(LimitRange)和资源的配额管理(Resource Quotas)

计算资源管理(Compute Resources): 为Pod中的容器指定使用的计算资源(CPU和内存)。

资源的配置范围管理(LimitRange):可以对集群内Request和Limits的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的Pod的资源使用限制。

资源的配额管理(Resource Quotas):可以为每一个命名空间(namespace)提供一个总体的资源使用限制,通过它可以限制命名空间中某个类型的对象的总数目上限,也可以设置命名空间中Pod可以使用到的计算资源的总上限。资源的配额管理有效解决了多用户或多个团队公用一个k8s集群时资源有效分配的问题。

本篇主要总结 资源的配额管理(Resource Quotas)的使用

资源配额,通过 ResourceQuota 对象来定义,对每个命名空间的资源消耗总量提供限制。 它可以限制命名空间中某种类型的对象的总数目上限,也可以限制命令空间中的 Pod 可以使用的计算资源的总上限。

资源配额的工作方式如下:

  • 不同的团队可以在不同的命名空间下工作,目前这是非约束性的,在未来的版本中可能会通过 ACL (Access Control List 访问控制列表) 来实现强制性约束。

  • 集群管理员可以为每个命名空间创建一个或多个资源配额对象。

  • 当用户在命名空间下创建资源(如 Pod、Service 等)时,Kubernetes 的配额系统会 跟踪集群的资源使用情况,以确保使用的资源用量不超过资源配额中定义的硬性资源限额。

  • 如果资源创建或者更新请求违反了配额约束,那么该请求会报错(HTTP 403 FORBIDDEN), 并在消息中给出有可能违反的约束。

  • 如果命名空间下的计算资源 (如 cpumemory)的配额被启用,则用户必须为 这些资源设定请求值(request)和约束值(limit),否则配额系统将拒绝 Pod 的创建。 提示: 可使用 LimitRanger 准入控制器来为没有设置计算资源需求的 Pod 设置默认值。

ResourceQuota 对象的名称必须时合法的 DNS 子域名。

下面是使用命名空间和配额构建策略的示例:

  • 在具有 32 GiB 内存和 16 核 CPU 资源的集群中,允许 A 团队使用 20 GiB 内存 和 10 核的 CPU 资源, 允许 B 团队使用 10 GiB 内存和 4 核的 CPU 资源,并且预留 2 GiB 内存和 2 核的 CPU 资源供将来分配。

  • 限制 "testing" 命名空间使用 1 核 CPU 资源和 1GiB 内存。允许 "production" 命名空间使用任意数量。

在集群容量小于各命名空间配额总和的情况下,可能存在资源竞争。资源竞争时,Kubernetes 系统会遵循先到先得的原则。

不管是资源竞争还是配额的修改,都不会影响已经创建的资源使用对象。

启用资源配额

资源配额的支持在很多 Kubernetes 版本中是默认开启的。当 apiserver --enable-admission-plugins= 参数中包含 ResourceQuota 时,资源配额会被启用。

当命名空间中存在一个 ResourceQuota 对象时,对于该命名空间而言,资源配额就是开启的。

计算资源配额

用户可以对给定命名空间下的可被请求的 计算资源 总量进行限制。

配额机制所支持的资源类型:

资源名称 描述
limits.cpu 所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。
limits.memory 所有非终止状态的 Pod,其内存限额总量不能超过该值。
requests.cpu 所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。
requests.memory 所有非终止状态的 Pod,其内存需求总量不能超过该值。

扩展资源的资源配额

除上述资源外,在 Kubernetes 1.10 版本中,还添加了对 扩展资源 的支持。

由于扩展资源不可超量分配,因此没有必要在配额中为同一扩展资源同时指定 requestslimits。 对于扩展资源而言,目前仅允许使用前缀为 requests. 的配额项。

以 GPU 拓展资源为例,如果资源名称为 nvidia.com/gpu,并且要将命名空间中请求的 GPU 资源总数限制为 4,则可以如下定义配额:

  • requests.nvidia.com/gpu: 4

有关更多详细信息,请参阅查看和设置配额。

存储资源配额

用户可以对给定命名空间下的存储资源总量进行限制。

此外,还可以根据相关的存储类(Storage Class)来限制存储资源的消耗。

资源名称 描述
requests.storage 所有 PVC,存储资源的需求总量不能超过该值。
persistentvolumeclaims 在该命名空间中所允许的 PVC 总量。
<storage-class-name>.storageclass.storage.k8s.io/requests.storage 在所有与 storage-class-name 相关的持久卷声明中,存储请求的总和不能超过该值。
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims 在与 storage-class-name 相关的所有持久卷声明中,命名空间中可以存在的持久卷申领总数。

例如,如果一个操作人员针对 gold 存储类型与 bronze 存储类型设置配额,操作人员可以定义如下配额:

  • gold.storageclass.storage.k8s.io/requests.storage: 500Gi

  • bronze.storageclass.storage.k8s.io/requests.storage: 100Gi

在 Kubernetes 1.8 版本中,本地临时存储的配额支持已经是 Alpha 功能:

资源名称 描述
requests.ephemeral-storage 在命名空间的所有 Pod 中,本地临时存储请求的总和不能超过此值。
limits.ephemeral-storage 在命名空间的所有 Pod 中,本地临时存储限制值的总和不能超过此值。

对象数量配额

Kubernetes 1.9 版本增加了使用以下语法对所有标准的、命名空间域的资源类型进行配额设置的支持。

  • count/<resource>.<group>

这是用户可能希望利用对象计数配额来管理的一组资源示例。

  • count/persistentvolumeclaims

  • count/services

  • count/secrets

  • count/configmaps

  • count/replicationcontrollers

  • count/deployments.apps

  • count/replicasets.apps

  • count/statefulsets.apps

  • count/jobs.batch

  • count/cronjobs.batch

  • count/deployments.extensions

Kubernetes 1.15 版本增加了对使用相同语法来约束自定义资源的支持。 例如,要对 example.com API 组中的自定义资源 widgets 设置配额,请使用 count/widgets.example.com

当使用 count/* 资源配额时,如果对象存在于服务器存储中,则会根据配额管理资源。 这些类型的配额有助于防止存储资源耗尽。例如,用户可能想根据服务器的存储能力来对服务器中 Secret 的数量进行配额限制。集群中存在过多的 Secret 实际上会导致服务器和控制器无法启动!用户可以选择对 Job 进行配额管理,以防止配置不当的 CronJob 在某命名空间中创建太多作业而导致集群拒绝服务。

在 Kubernetes 1.9 版本之前,可以在有限的一组资源上实施一般性的对象数量配额。 此外,还可以进一步按资源的类型设置其配额。

支持以下类型:

资源名称 描述
configmaps 在该命名空间中允许存在的 ConfigMap 总数上限。
persistentvolumeclaims 在该命名空间中允许存在的 PVC 的总数上限。
pods 在该命名空间中允许存在的非终止状态的 pod 总数上限。Pod 终止状态等价于 Pod 的 .status.phase in (Failed, Succeeded) = true
replicationcontrollers 在该命名空间中允许存在的 RC 总数上限。
resourcequotas 在该命名空间中允许存在的资源配额总数上限。
services 在该命名空间中允许存在的 Service 总数上限。
services.loadbalancers 在该命名空间中允许存在的 LoadBalancer 类型的服务总数上限。
services.nodeports 在该命名空间中允许存在的 NodePort 类型的服务总数上限。
secrets 在该命名空间中允许存在的 Secret 总数上限。

例如,pods 配额统计某个命名空间中所创建的、非终止状态的 Pod 个数并确保其不超过某上限值。 用户可能希望在某命名空间中设置 pods 配额,以避免有用户创建很多小的 Pod,从而耗尽集群所能提供的 Pod IP 地址。

配额作用域

每个配额都有一组相关的作用域(scope),配额只会对作用域内的资源生效。 配额机制仅统计所列举的作用域的交集中的资源用量。

当一个作用域被添加到配额中后,它会对作用域相关的资源数量作限制。 如配额中指定了允许(作用域)集合之外的资源,会导致验证错误。

作用域 描述
Terminating 匹配所有 spec.activeDeadlineSeconds 不小于 0 的 Pod。
NotTerminating 匹配所有 spec.activeDeadlineSeconds 是 nil 的 Pod。
BestEffort 匹配所有 Qos 是 BestEffort 的 Pod。
NotBestEffort 匹配所有 Qos 不是 BestEffort 的 Pod。
BestEffort` 作用域限制配额跟踪以下资源:`pods

TerminatingNotTerminatingNotBestEffort 这三种作用域限制配额跟踪以下资源:

  • cpu

  • limits.cpu

  • limits.memory

  • memory

  • pods

  • requests.cpu

  • requests.memory

基于优先级类(PriorityClass)来设置资源配额

FEATURE STATE: Kubernetes 1.12 [beta]

Pod 可以创建为特定的优先级。 通过使用配额规约中的 scopeSelector 字段,用户可以根据 Pod 的优先级控制其系统资源消耗。

仅当配额规范中的 scopeSelector 字段选择到某 Pod 时,配额机制才会匹配和计量 Pod 的资源消耗。

本示例创建一个配额对象,并将其与具有特定优先级的 Pod 进行匹配。 该示例的工作方式如下:

  • 集群中的 Pod 可取三个优先级类之一,即 "low"、"medium"、"high"。

  • 为每个优先级创建一个配额对象。

将以下 YAML 保存到文件 quota.yml 中。

apiVersion: v1
kind: List
items:
- apiVersion: v1kind: ResourceQuotametadata:name: pods-highspec:hard:cpu: "1000"memory: 200Gipods: "10"scopeSelector:matchExpressions:- operator : InscopeName: PriorityClassvalues: ["high"]
- apiVersion: v1kind: ResourceQuotametadata:name: pods-mediumspec:hard:cpu: "10"memory: 20Gipods: "10"scopeSelector:matchExpressions:- operator : InscopeName: PriorityClassvalues: ["medium"]
- apiVersion: v1kind: ResourceQuotametadata:name: pods-lowspec:hard:cpu: "5"memory: 10Gipods: "10"scopeSelector:matchExpressions:- operator : InscopeName: PriorityClassvalues: ["low"]

使用 kubectl create 命令运行以下操作。

kubectl create -f ./quota.yml
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created

使用 kubectl describe quota 操作验证配额的 Used 值为 0

kubectl describe quota
Name:       pods-high
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     1k
memory      0     200Gi
pods        0     10
​
​
Name:       pods-low
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     5
memory      0     10Gi
pods        0     10
​
​
Name:       pods-medium
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     10
memory      0     20Gi
pods        0     10

创建优先级为 "high" 的 Pod。 将以下 YAML 保存到文件 high-priority-pod.yml 中。

apiVersion: v1
kind: Pod
metadata:name: high-priority
spec:containers:- name: high-priorityimage: ubuntucommand: ["/bin/sh"]args: ["-c", "while true; do echo hello; sleep 10;done"]resources:requests:memory: "10Gi"cpu: "500m"limits:memory: "10Gi"cpu: "500m"priorityClassName: high

使用 kubectl create 运行以下操作。

kubectl create -f ./high-priority-pod.yml

确认 "high" 优先级配额 pods-high 的 "Used" 统计信息已更改,并且其他两个配额未更改。

kubectl describe quota
Name:       pods-high
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         500m  1k
memory      10Gi  200Gi
pods        1     10
​
​
Name:       pods-low
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     5
memory      0     10Gi
pods        0     10
​
​
Name:       pods-medium
Namespace:  default
Resource    Used  Hard
--------    ----  ----
cpu         0     10
memory      0     20Gi
pods        0     10

scopeSelectoroperator 字段中支持以下值:

  • In

  • NotIn

  • Exist

  • DoesNotExist

请求与限制

分配计算资源时,每个容器可以为 CPU 或内存指定请求和约束。 配额可以针对二者之一进行设置。

如果配额中指定了 requests.cpurequests.memory 的值,则它要求每个容器都显式给出对这些资源的请求。 同理,如果配额中指定了 limits.cpulimits.memory 的值,那么它要求每个容器都显式设定对应资源的限制。

查看和设置配额

Kubectl 支持创建、更新和查看配额:

kubectl create namespace myspace
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: compute-resources
spec:hard:requests.cpu: "1"requests.memory: 1Gilimits.cpu: "2"limits.memory: 2Girequests.nvidia.com/gpu: 4
EOF
kubectl create -f ./compute-resources.yaml --namespace=myspace
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: object-counts
spec:hard:configmaps: "10"persistentvolumeclaims: "4"pods: "4"replicationcontrollers: "20"secrets: "10"services: "10"services.loadbalancers: "2"
EOF
kubectl create -f ./object-counts.yaml --namespace=myspace
kubectl get quota --namespace=myspace
NAME                    AGE
compute-resources       30s
object-counts           32s
kubectl describe quota compute-resources --namespace=myspace
Name:                    compute-resources
Namespace:               myspace
Resource                 Used  Hard
--------                 ----  ----
limits.cpu               0     2
limits.memory            0     2Gi
requests.cpu             0     1
requests.memory          0     1Gi
requests.nvidia.com/gpu  0     4
kubectl describe quota object-counts --namespace=myspace
Name:                   object-counts
Namespace:              myspace
Resource                Used    Hard
--------                ----    ----
configmaps              0       10
persistentvolumeclaims  0       4
pods                    0       4
replicationcontrollers  0       20
secrets                 1       10
services                0       10
services.loadbalancers  0       2

kubectl 还使用语法 count/<resource>.<group> 支持所有标准的、命名空间域的资源的对象计数配额:

kubectl create namespace myspace
kubectl create quota test --hard=count/deployments.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=myspace
kubectl create deployment nginx --image=nginx --namespace=myspace
kubectl describe quota --namespace=myspace
Name:                         test
Namespace:                    myspace
Resource                      Used  Hard
--------                      ----  ----
count/deployments.extensions  1     2
count/pods                    2     3
count/replicasets.extensions  1     4
count/secrets                 1     4

配额和集群容量

资源配额与集群资源总量是完全独立的。它们通过绝对的单位来配置。 所以,为集群添加节点时,资源配额不会自动赋予每个命名空间消耗更多资源的能力。

有时可能需要资源配额支持更复杂的策略,比如:

  • 在几个团队中按比例划分总的集群资源。

  • 允许每个租户根据需要增加资源使用量,但要有足够的限制以防止资源意外耗尽。

  • 探测某个命名空间的需求,添加物理节点并扩大资源配额值。

这些策略可以通过将资源配额作为一个组成模块、手动编写一个控制器来监控资源使用情况, 并结合其他信号调整命名空间上的硬性资源配额来实现。

注意:资源配额对集群资源总体进行划分,但它对节点没有限制:来自不同命名空间的 Pod 可能在同一节点上运行。

默认情况下限制特定优先级的资源消耗

有时候可能希望当且仅当某名字空间中存在匹配的配额对象时,才可以创建特定优先级 (例如 "cluster-services")的 Pod。

通过这种机制,操作人员能够将限制某些高优先级类仅出现在有限数量的命名空间中, 而并非每个命名空间默认情况下都能够使用这些优先级类。

要实现此目的,应使用 kube-apiserver 标志 --admission-control-config-file 传递如下配置文件的路径:

  • apiserver.config.k8s.io/v1

  • apiserver.k8s.io/v1alpha1

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"configuration:apiVersion: apiserver.config.k8s.io/v1kind: ResourceQuotaConfigurationlimitedResources:- resource: podsmatchScopes:- scopeName: PriorityClassoperator: Invalues: ["cluster-services"]

现在,仅当命名空间中存在匹配的 scopeSelector 的配额对象时,才允许使用 "cluster-services" Pod。

示例:

    scopeSelector:matchExpressions:- scopeName: PriorityClassoperator: Invalues: ["cluster-services"]

以上内容主要摘自k8s官方文档:https://kubernetes.io/zh/docs/concepts/policy/resource-quotas/

k8s资源限制——资源的配额管理(Resource Quotas)相关推荐

  1. pod的requests、limits解读、LimitRange资源配额、Qos服务质量等级、资源配额管理 Resource Quotas

    前言 环境:k8s-v1.22.17 docker-20.10.9 centos-7.9 目录 前言 什么是可计算资源 CPU.Memory计量单位 pod资源请求.限额方式 pod定义request ...

  2. 磁盘配额管理disk quotas

    条件: a.确保系统内核支持,Linux一般都支持 b.确保分区格式支持,ext2都只持! c.安装有quota软件,centos默认都有! (1)检查内核是否打开磁盘配额支持 [root@cento ...

  3. openstack nova 基础知识——Quota(配额管理)

    很久没有写博客了,之前在学校的一段时间比较堕落,坐着火车从南到北,穿越长江黄河,来到了一片新的天地.在这里,不管男的女的,老的少的,在吃饭,在路上,我听到的不再是"游戏"这个永久不 ...

  4. 《Kubernetes知识篇:基于Namespace(多租户)进行资源配额管理》

    文章目录 一.资源配额管理对象 二.基于Namespace资源配额概述 三.资源配额所能管理的资源类型 3.1.计算资源配额 3.2.存储资源配额 3.3.对象数量配额 四.设置和查看资源配额 4.1 ...

  5. k8s中namespace资源讲解

    前言 环境:centos7.9 docker-ce-20.10.9 kubernetes-version v1.22.6 什么是namespace namespace是kubernetes系统中的一种 ...

  6. Kubernetes(k8s)常用资源的使用、Pod的常用操作

    1.K8s是如何运行容器的. 答:k8s是通过定义一个Pod的资源,然后在Pod里面运行容器的.K8s最小的资源单位Pod. 2.如何创建一个Pod资源呢? 答:在K8s中,所有的资源单位都可以使用一 ...

  7. 【Azure】微软 Azure 基础解析(五)核心体系结构之管理组、订阅、资源和资源组以及层次关系

    本系列博文还在更新中,收录在专栏:「Azure探秘:构建云计算世界」 专栏中. 本系列文章列表如下: [Azure]微软 Azure 基础解析(三)描述云计算运营中的 CapEx 与 OpEx,如何区 ...

  8. k8s操作自定义资源

    如何操作自定义资源? client-go为每种K8S内置资源提供对应的clientset和informer.那如果我们要监听和操作⾃定义资源对象,应该如何做呢?这⾥我们有两种⽅式: ⽅式⼀: 使⽤cl ...

  9. Unity3D资源加载与内存管理

    Unity3D资源加载与内存管理 Unity 3D中的资源加载 AssetBundle运行时加载: Unity3D占用内存太大怎么解决呢? 关于内存管理 举两个例子帮助理解 额外问题 Hog的评论引用 ...

最新文章

  1. 图灵九月书讯 ——金秋时节推荐给程序员们的书
  2. php form提交跳转,form表单页面跳转方式提交练习
  3. linux部署项目路径如下
  4. oracle插入数据语句实例,oracle Insert 用法总结
  5. webstorm 设置tslint_webstorm(2019)配置eslint规范
  6. 块裁剪后的矩形边界如何去掉_手持拍摄画面太抖?这节课教你如何快速稳定抖动的画面...
  7. linux 内存规划,生产场景怎么对linux系统进行合理规划分区?
  8. 蓝桥杯第八届省赛JAVA真题----承压计算
  9. 中国移动停售华为5G手机?双方回应...
  10. 论文翻译:Real-Time High-Resolution Background Matting
  11. java服务端验证框架_SpringBoot服务端数据校验过程详解
  12. Python基础 -- 注释、变量以及数据类型、标识符和关键字、类型转、运算符
  13. 三个数比较大小函数调用c语言,C语言程序系列第四弹–max函数判断三个数的大小...
  14. IPv6 内网穿透(一)
  15. python寻峰算法_python/scipy的寻峰算法
  16. (12)树莓派B+ GPIO控制四驱车
  17. 小结Win7下开启硬盘NCQ功能
  18. 计算机右键管理无法访问指定设备,简单几步解决win10打开任务管理器显示无法访问指定设备方法...
  19. 车道线检测-从单车道到多车道的车道线检测(一)
  20. 你想了解的所有树结构,都收集在这篇文章里了

热门文章

  1. EIGRP原理及配置
  2. 为什么样本方差是总体方差的无偏估计?
  3. 关于fastapi框架的异步
  4. 什么内网穿透?如何使用内网穿透?
  5. JavaScript:将输入的一串数字转换成中文大写,最高可写12位(千亿)
  6. @Scheduled使用及讲解
  7. 接口 和 http协议
  8. Linux 修改系统时间的两种方式
  9. LabVIEW2018中文版资源分享及安装指导
  10. nginx_tcp转发