K8s进阶之多租户场景下的资源配额(ResourceQuota)
概述
ResourceQuota官方文档:https://kubernetes.io/zh-cn/docs/concepts/policy/resource-quotas/
在 Kubernetes(K8s)中,ResourceQuota(资源配额)是一种用于管理命名空间(Namespace)资源使用的核心机制。它通过限制命名空间内可消耗的资源总量,实现资源的精细化分配和隔离,避免单个命名空间过度占用集群资源,保障集群稳定性和多租户环境的公平性。
ResourceQuota 通常与 LimitRange 的配合使用:
- ResourceQuota:限制命名空间级别的资源总量(如整个命名空间最多使用 2 核 CPU)。
- LimitRange:限制单个 Pod / 容器的资源请求 / 限制范围(如单个 Pod 的 CPU 请求必须≥100m 且≤500m)。
关于LimitRange可以查看这篇文章:K8s进阶之LimitRange
应用场景
多租户资源隔离
场景:
在多租户集群中(如开发、测试、生产环境共用一个集群),不同租户或团队使用独立的命名空间。
作用:
为每个命名空间设置 CPU、内存、存储等资源的硬限制,防止某个租户滥用资源影响其他租户。
开发 / 测试环境资源管控
场景:
开发和测试环境通常需要快速迭代,但资源使用可能缺乏约束(如临时创建大量 Pod)。
作用:
限制命名空间内可创建的 Pod、服务、PersistentVolumeClaim(PVC)等对象的数量,避免资源浪费。
生产环境资源预留与保障
场景:
生产环境需要为关键应用预留资源,避免被非关键业务抢占。
作用:
为生产环境的命名空间设置较高的资源配额,同时限制非生产环境的资源上限。
结合LimitRange(资源限制范围),确保 Pod 的资源请求 / 限制符合配额要求。
防止集群资源耗尽
场景:
当集群资源有限时(如 CPU、内存总量固定),未限制的命名空间可能导致集群整体资源不足,影响所有业务。
作用:
通过全局配额(在default命名空间或所有命名空间启用),限制整个集群的资源使用上限,保障系统组件(如 kube-proxy、CoreDNS)和高优先级应用的资源可用性。
ResourceQuota支持的资源类型
计算资源
- requests.cpu:所有 Pod 的 CPU 请求总量(以核心数为单位,如1表示 1 核,0.5或500m表示 0.5 核)
- requests.memory:内存请求总量(如1Gi、512Mi)
- limits.cpu:CPU 限制总量(Pod 可突发使用的最大 CPU)
- limits.memory:内存限制总量(Pod 的 OOM 阈值)
存储资源
- persistentvolumeclaims:PVC 数量上限
- storageclass.storage:特定存储类的存储总量(如storageclass.storage.k8s.io/ssd=100Gi)
对象数量
- pods:Pod 数量上限(包括运行中、已终止的 Pod)
- services:服务数量上限
- replicationcontrollers:复制控制器数量上限
- secrets:Secret 数量上限
- configmaps:ConfigMap 数量上限
- deployments.apps:Deployment 数量上限(需启用apps API 组)
- statefulsets.apps:StatefulSet 数量上限
ResourceQuota资源文件解析
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-quota
namespace: my-namespace # 指定要应用配额的命名空间
spec:
hard:
# 计算资源配额
requests.cpu: "2" # CPU 总请求量上限
requests.memory: 4Gi # 内存总请求量上限
limits.cpu: "4" # CPU 总限制量上限
limits.memory: 8Gi # 内存总限制量上限
# 存储资源配额
requests.storage: 10Gi # 存储总请求量上限
persistentvolumeclaims: "2" # PVC 数量上限
# 对象数量配额
pods: "10" # Pod 数量上限
services: "5" # Service 数量上限
configmaps: "10" # ConfigMap 数量上限
secrets: "10" # Secret 数量上限
replicationcontrollers: "5" # ReplicationController 数量上限
services.loadbalancers: "2" # LoadBalancer 类型 Service 数量上限
services.nodeports: "2" # NodePort 类型 Service 数量上限
实战案例
创建命名空间并配置资源配额
# 创建命名空间
[root@master01 ~]# kubectl create namespace dev
namespace/dev created
# 查看命名空间是否创建成功
[root@master01 ~]# kubectl get ns dev
NAME STATUS AGE
dev Active 5s
配置资源配额
# 定义资源配额
[root@master01 ~/quota]# cat dev-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
# 指定要应用配额的命名空间
namespace: dev
spec:
hard:
# 计算资源配额
# CPU 总请求量上限,1核心
requests.cpu: "1"
# 内存总请求量上限,1G
requests.memory: 1Gi
# CPU 总限制量上限,1核心
limits.cpu: "1"
# 内存总限制量上限,1G
limits.memory: 1Gi
# 存储资源配额
# 存储总请求量上限
requests.storage: 5Gi
# PVC 数量上限
persistentvolumeclaims: "2"
# 对象数量配额
# Pod 数量上限
pods: "10"
# Service 数量上限
services: "2"
# ConfigMap 数量上限
configmaps: "3"
# Secret 数量上限
secrets: "10"
# ReplicationController 数量上限
replicationcontrollers: "5"
# LoadBalancer 类型 Service 数量上限
services.loadbalancers: "2"
# NodePort 类型 Service 数量上限
services.nodeports: "2"
# Deployment 数量上限
apps/deployments: "3"
# replicasets 数量上限
apps/replicasets: "3"
# job的数量上限
batch/jobs: "2"
# cronjobs的数量上限
batch/cronjobs: "2"
# 创建资源配额
[root@master01 ~/quota]# kubectl apply -f dev-quota.yaml
resourcequota/dev-quota created
查看一下详细信息
# 查看quota
[root@master01 ~/quota]# kubectl get quota -n dev
NAME AGE REQUEST LIMIT
dev-quota 59s apps/deployments: 0/3, apps/replicasets: 0/3, batch/cronjobs: 0/2, batch/jobs: 0/2, configmaps: 1/3, persistentvolumeclaims: 0/2, pods: 0/10, replicationcontrollers: 0/5, requests.cpu: 0/1, requests.memory: 0/1Gi, requests.storage: 0/5Gi, secrets: 0/10, services: 0/2, services.loadbalancers: 0/2, services.nodeports: 0/2 limits.cpu: 0/1, limits.memory: 0/1Gi
# 查看详细信息
[root@master01 ~/quota]# kubectl describe quota dev-quota -n dev
Name: dev-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
apps/deployments 0 3
apps/replicasets 0 3
batch/cronjobs 0 2
batch/jobs 0 2
configmaps 1 3
limits.cpu 0 1
limits.memory 0 1Gi
persistentvolumeclaims 0 2
pods 0 10
replicationcontrollers 0 5
requests.cpu 0 1
requests.memory 0 1Gi
requests.storage 0 5Gi
secrets 0 10
services 0 2
services.loadbalancers 0 2
services.nodeports 0 2
验证ResourceQuota
验证计算资源
当我们创建Pod时不指定CPU和memory的资源会发生什么呢?
创建Pod时会报错,错误信息提示我们需要指定request和limit,当在ResourceQuota限制的命名空间内,创建Pod时,需要配置对应的资源限额,这是一个强制性的诉求
[root@master01 ~/quota]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: dev
spec:
containers:
- name: nginx-container-1
image: nginx:latest
[root@master01 ~/quota]# kubectl apply -f pod.yaml
Error from server (Forbidden): error when creating "pod.yaml": pods "nginx-pod" is forbidden: failed quota: dev-quota: must specify limits.cpu for: nginx-container-1; limits.memory for: nginx-container-1; requests.cpu for: nginx-container-1; requests.memory for: nginx-container-1
创建出一个符合规则约束的Pod,看看会发生什么
[root@master01 ~/quota]# cat pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-1
namespace: dev
spec:
containers:
- name: nginx-container-1
image: nginx:latest
# 定义资源限制
resources:
requests:
cpu: "0.5"
memory: "500Mi"
limits:
cpu: "0.5"
memory: "500Mi"
[root@master01 ~/quota]# kubectl apply -f pod-1.yaml
pod/nginx-pod-1 created
# 查看quota,发现Used列产生了数据
[root@master01 ~/quota]# kubectl describe quota -n dev
Name: dev-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
apps/deployments 0 3
apps/replicasets 0 3
batch/cronjobs 0 2
batch/jobs 0 2
configmaps 1 3
limits.cpu 500m 1
limits.memory 500Mi 1Gi
persistentvolumeclaims 0 2
pods 1 10
replicationcontrollers 0 5
requests.cpu 500m 1
requests.memory 500Mi 1Gi
requests.storage 0 5Gi
secrets 0 10
services 0 2
services.loadbalancers 0 2
services.nodeports 0 2
在创建一个Pod,将CPU和memory分别设置为0.8和800Mi
发现在我们创建时,提示报错了,为什么呢?因为我们创建的Pod资源请求超出了规定的配额
[root@master01 ~/quota]# cat pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-2
namespace: dev
spec:
containers:
- name: nginx-container-2
image: nginx:latest
resources:
requests:
cpu: "0.8"
memory: "800Mi"
limits:
cpu: "0.8"
memory: "800Mi"
[root@master01 ~/quota]# kubectl apply -f pod-2.yaml
Error from server (Forbidden): error when creating "pod-2.yaml": pods "nginx-pod-2" is forbidden: exceeded quota: dev-quota, requested: limits.cpu=800m,limits.memory=800Mi,requests.cpu=800m,requests.memory=800Mi, used: limits.cpu=500m,limits.memory=500Mi,requests.cpu=500m,requests.memory=500Mi, limited: limits.cpu=1,limits.memory=1Gi,requests.cpu=1,requests.memory=1Gi
验证service资源
我们先创建两个service,类型分别是nodePort和loadBalancer
[root@master01 ~/quota]# cat service-1.yaml
# NodePort类型的service
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
namespace: dev
spec:
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
---
# LoadBalancer类型service
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
namespace: dev
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 80
# 创建
[root@master01 ~/quota]# kubectl apply -f service-1.yaml
service/nginx-nodeport created
service/nginx-loadbalancer created
# 查看
[root@master01 ~/quota]# kubectl get service -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-loadbalancer LoadBalancer 10.96.1.23 <pending> 80:30531/TCP 5s
nginx-nodeport NodePort 10.96.1.11 <none> 80:30080/TCP 5s
查看一下quota详细信息
[root@master01 ~/quota]# kubectl describe quota dev-quota -n dev
Name: dev-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
apps/deployments 0 3
apps/replicasets 0 3
batch/cronjobs 0 2
batch/jobs 0 2
configmaps 1 3
limits.cpu 500m 1
limits.memory 500Mi 1Gi
persistentvolumeclaims 0 2
pods 1 10
replicationcontrollers 0 5
requests.cpu 500m 1
requests.memory 500Mi 1Gi
requests.storage 0 5Gi
secrets 0 10
services 2 2
services.loadbalancers 1 2
services.nodeports 2 2
这里nodeports的数量为2,为什么呢?因为loadbalancer类型的service底层使用的就是nodeport。所以创建loadbalancer类型的service时会自动创建一个nodeport。
关于service可以学习这篇文章:K8s新手系列之Service资源
这个时候我们在创建一个clusterip类型的service,看看会发生什么?
再继续创建的话,会报错,提示我们service的数量已经不够了
[root@master01 ~/quota]# cat service-3.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
namespace: dev
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@master01 ~/quota]# kubectl apply -f service-3.yaml
Error from server (Forbidden): error when creating "service-3.yaml": services "nginx-clusterip" is forbidden: exceeded quota: dev-quota, requested: services=1, used: services=2, limited: services=2
验证其它资源
这里大家可以根据上面的案例自行测试,
ResourceQuota管理
查看ResourceQuota
kubectl get quota <quota-name> -n <namespace>
# 查看详细信息
kubectl describe quota <quota-name> -n <namespace>
删除ResourceQuota
kubectl delete quota <quota-name> -n <namespace>
修改已经定义好的ResourceQuota
方式一,直接修改资源清单文件,重新应用即可
示例:
[root@master01 ~/quota]# cat dev-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
# 指定要应用配额的命名空间
namespace: dev
spec:
hard:
# 修改为10
requests.cpu: "10"
# 修改为10G
requests.memory: 10Gi
limits.cpu: "1"
limits.memory: 10Gi
# 修改为50G
requests.storage: 50Gi
persistentvolumeclaims: "2"
pods: "10"
services: "2"
configmaps: "3"
secrets: "10"
replicationcontrollers: "5"
services.loadbalancers: "2"
services.nodeports: "2"
apps/deployments: "3"
apps/replicasets: "3"
batch/jobs: "2"
batch/cronjobs: "2"
# 重新应用
[root@master01 ~/quota]# kubectl apply -f dev-quota.yaml
resourcequota/dev-quota configured
# 查看更新后的资源
[root@master01 ~/quota]# kubectl describe quota dev-quota -n dev
Name: dev-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
apps/deployments 0 3
apps/replicasets 0 3
batch/cronjobs 0 2
batch/jobs 0 2
configmaps 1 3
limits.cpu 500m 1
limits.memory 500Mi 10Gi # 已更新
persistentvolumeclaims 0 2
pods 1 10
replicationcontrollers 0 5
requests.cpu 500m 10
requests.memory 500Mi 10Gi # 已更新
requests.storage 0 50Gi # 已更新
secrets 0 10
services 2 2
services.loadbalancers 1 2
services.nodeports 2 2
方式二:使用kubectl edit
命令直接编辑保存即可
K8s进阶之多租户场景下的资源配额(ResourceQuota)的更多相关文章
- Serverless 如何应对 K8s 在离线场景下的资源供给诉求
本文整理自腾讯云云原生产品团队的专家产品经理韩沛在 Techo 开发者大会云原生专题的分享内容--Kubernetes 混部与弹性容器.本次分享主要分为三部分:基于 K8s 的应用混部.提升应用混部效 ...
- k8s中 资源配额 ResourceQuota
文章转载自:https://www.kuboard.cn/learning/k8s-advanced/policy/lr.html 当多个用户(团队)共享一个节点数量有限的集群时,如何在多个用户(团队 ...
- 超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?
作者 | 张晓宇(衷源) 阿里云容器平台技术专家 关注『阿里巴巴云原生』公众号,回复关键词"1010",可获取本文 PPT. 导读:资源利用率一直是很多平台管理和研发人员关心的话 ...
- 难道主键除了自增就是GUID?支持k8s等分布式场景下的id生成器了解下
背景 主键(Primary Key),用于唯一标识表中的每一条数据.所以,一个合格的主键的最基本要求应该是唯一性. 那怎么保证唯一呢?相信绝大部分开发者在刚入行的时候选择的都是数据库的自增id,因为这 ...
- Ironic几种不同的场景下的网络拓扑
最近帮领导做了几页ppt,总结几种场景下ironic管理物理机网络的网络拓扑,简单做成一份文章记录下.只是方便自己记忆,没有认真修改.如果对ironic有一定了解,可以看下,加深理解. 1. vlan ...
- 硬核测试:Pulsar 与 Kafka 在金融场景下的性能分析
背景 Apache Pulsar 是下一代分布式消息流平台,采用计算存储分层架构,具备多租户.高一致.高性能.百万 topic.数据平滑迁移等诸多优势.越来越多的企业正在使用 Pulsar 或者尝试将 ...
- API 管理在云原生场景下的机遇与挑战
作者 | 张添翼 来源 | 尔达Erda公众号 云原生下的机遇和挑战 标准和生态的意义 自从 Kubernetes v1.0 于 2015 年 7 月 21 日发布,CNCF 组织随后建立以来,其 ...
- ADO.NET Entity Framework 在哪些场景下使用?
在知乎回答了下,顺手转回来. Enity Framework已经是.NET下最主要的ORM了.而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的 ...
- CephRGW 在多个RGW负载均衡场景下,RGW 大文件并发分片上传功能验证
http://docs.ceph.com/docs/master/radosgw/s3/objectops/#initiate-multi-part-upload 根据分片上传的API描述,因为对同一 ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
随机推荐
- Avalanche公链深度解析:创新共识、亚秒级最终性与生态竞争力
摘要:Avalanche定位为一个高性能.可扩展的Layer 1区块链平台,但它并不是一个新公链,其主网于2020年9月21日正式上线,有Ava Labs开发.Ava Labs成立于2018年,总部位 ...
- javascript 陀螺仪加摄像头可以玩出AR效果
原文链接:https://blog.jijian.link/2020-09-08/js-ar/ 重要事情说三遍 此文章中的API接口,必须放在 https 协议下测试!浏览器APP必须开启摄像头权限! ...
- css 技巧:利用 after 伪对象和 background 属性实现 img 图片标签占位图
同步发布:https://blog.jijian.link/2020-04-15/css-img-after-placeholder/ 如图: 图片加载失败了,在浏览器会默认显示一张破图.受各种网速. ...
- Windows核心编程 进程与线程
进程 Windows作为多任务操作系统,允许多个程序同时在系统中运行.这些程序被称为进程,进程运行在一片独立的空间中,受到操作系统保护,操作系统的很多资源都是围绕着进程来进行分配,可以理解为操作系统维 ...
- Linux+Typora+Picgo图床配置
Linux+Typora+Picgo图床配置 首先不建议安装在UbuntuStore里的版本,会有一些限制. 首先安装node.js 去官网下载编译好的源码,配置软连接,使全局都可以使用node命令. ...
- 寻找可靠的长久的存储介质之旅,以及背后制作的三个网页“图片粘贴转base64”、“生成L纠错级别的QR码”、“上传文件转 base64以及粘贴 base64 转可下载文件”
其实对于目前的形式来说,虽然像 U 盘.固态硬盘.甚至光盘这些信息储存介质(设备)的容量越来越高,但是不得不说这些设备的可靠性依然像悬着的一块石头,虽然这块石头确实牢牢的粘在天花板上,但是毕竟是粘上去 ...
- Vite CVE-2025-30208 安全漏洞
Vite CVE-2025-30208 安全漏洞 一.漏洞概述 CVE-2025-30208 是 Vite(一个前端开发工具提供商)在特定版本中存在的安全漏洞.此漏洞允许攻击者通过特殊的 URL 参数 ...
- 异常的两种处理方式--java进阶day08
1.异常的默认处理流程 java中,对于异常的默认处理方式是--向上抛出 之前我们说过,异常都是类,当某个程序出错后,就会自动生成该异常对象,而这个异常对象就如同一颗雷 . java的异常默认处理方式 ...
- Java24发布,精心总结
Java 24作为2025年3月发布的最新版本,延续了Java平台每半年发布一次的节奏,带来了24项重要改进.本文将按照核心改进领域分类,详细解析每个特性的技术原理和实际价值,帮助开发者全面了解这一版 ...
- EntityFramework GroupJoin
总而言之, GroupJoin 是先 Join 后 Group, 对应的 SQL 也是先 Join, 然后通过内置 LINQ 操作分组. 参考文档 GroupJoin 方法 Reimplementin ...