k8s 资源管理
文章目录
- ResourceQuota
- 什么是资源配额
- 定义一个ResourceQuota
- ResourceQuota的使用
- LimitRange
- LimitRange的用途
- 示例1:配置默认的requests和limits
- 示例2:配置requests和limits的范围
- QoS
- 什么是服务质量保证
- 示例1:实现QoS为Guaranteed的Pod
- 示例2:实现QoS为Burstable的Pod
- 示例3:实现QoS为BestEffort的Pod
节点故障大部分都是由于资源分配不合理、超额分配引起的,因此需要用某个技术手段保证节点的资源不会过大地超额分配。Kubernetes为我们提供了开箱即用的资源管理,可以通过ResourceQuota和LimitRange的配合防止节点资源超额分配。
ResourceQuota
首先看一下ResourceQuota(资源配额)的使用,资源配额是限制某个命名空间对资源使用的一个总量限制,比如内存、CPU、Pod数量等。
什么是资源配额
在生产环境中,可能会有多个Kubernetes集群,面向开发环境、测试环境、预生产环境和生产环境等。身为Kubernetes管理员,必然知道每个环境的规模有多大、可调度资源有多少,并且知道如何合理地为容器分配内存和CPU,所以一个管理员去管理整个Kubernetes集群时,很少会有资源分配超出集群可调度范围的情况。
在生产环境中,可能会有多个Kubernetes集群,面向开发环境、测试环境、预生产环境和生产环境等。身为Kubernetes管理员,必然知道每个环境的规模有多大、可调度资源有多少,并且知道如何合理地为容器分配内存和CPU,所以一个管理员去管理整个Kubernetes集群时,很少会有资源分配超出集群可调度范围的情况。
为了解决上述问题,Kubernetes引入了ResourceQuota的概念,以方便Kubernetes管理员方便地进行资源分配,比如给A项目组分配16核64GB的资源,并且最多只能部署20个Pod、30个Service等,这样来对Kubernetes的各类资源进行限制。
定义一个ResourceQuota
和其他资源配置方法一样,资源配额也可以通过一个YAML文件进行创建,比如定义一个比较常用的ResourceQuota如下:
apiVersion: v1
kind: ResourceQuota
metadata:name: example-quotanamespace: default
spec:hard:pods: "10"requests.cpu: "4"requests.memory: "10Gi"limits.cpu: "8"limits.memory: "20Gi"
在此配置中:
pods: “10” 限制命名空间中的 Pod 数量最多为 10 个。
requests.cpu: “4” 限制命名空间中所有 Pod 合计的 CPU 请求最多为 4 个 CPU。
requests.memory: “10Gi” 限制命名空间中所有 Pod 合计的内存请求最多为 10 GiB。
limits.cpu: “8” 限制命名空间中所有 Pod 合计的 CPU 使用量上限为 8 个 CPU。
limits.memory: “20Gi” 限制命名空间中所有 Pod 合计的内存使用量上限为 20 GiB。
ResourceQuota的使用
接下来演示ResourceQuota的具体使用方法,首先创建一个用于测试的Namespace:
kubectl create ns quota-example
创建一个测试Demo,比如限制该Namespace的PVC不能超过1个:
apiVersion: v1
kind: ResourceQuota
metadata:name: pvc-quotanamespace: quota-example
spec:hard:persistentvolumeclaims: "1"
创建该ResourceQuota:
kubectl create -f quota-objects.yaml
查看创建的资源限制状态:
kubectl get quota pvc-quota -n quota-example -o yaml

可以从status字段的used看出当前资源限制的使用量,并且Namespace只有在创建了ResourceQuota才会启用资源使用的配额,没有创建ResourceQuota的Namespace不限制资源使用。
之后创建一个PVC:
**touch pvc.yaml **
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvcnamespace: quota-example
spec:accessModes:- ReadWriteOnceresources:requests:storage: 10GistorageClassName: standard
kubectl create -f pvc.yaml -n quota-example
查看当前资源的使用情况:
kubectl get quota pvc-quota -n quota-example -o yaml
再次尝试创建PVC:
touch pvc2.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvc2namespace: quota-example
spec:accessModes:- ReadWriteOnceresources:requests:storage: 10GistorageClassName: standard
kubectl create -f pvc2.yaml -n quota-example

可以看到此时无法创建PVC,其他资源的限制类似,在此不再演示。
环境清理:
LimitRange
和ResourceQuota不同的是,LimitRange用来配置默认值,也就是一个Pod如果没有配置要用多少内存、CPU,LimitRange会在创建Pod时添加一个默认值。
LimitRange的用途
每个命名空间的最大资源使用量,细心的读者可能会发现,如果创建了一个Pod或Deployment没有指定requests和limits字段,是不是就意味着资源配额对内存和CPU的限制变成了一个摆设?答案是可想而知的,CPU和内存永远不会被限制。还有另一种情况,假如一个Namespace分配了16核、64GB的空间,之后创建一个申请了requests.cpu为16、requests.memory为64GB的容器,那么单个Pod就能把整个Namespace的资源全部占用。
为了防止这类情况发生,Kubernetes又引出了另一个概念:LimitRanger,用于针对没有配置requests和limits的资源设置一个默认值,同时配置单个资源最大的requests和limits,这样就能解决上述问题(注意:LimitRanger不会影响已经创建的资源)。
示例1:配置默认的requests和limits
可以通过LimitRanger配置默认的requests和limits值,用来解决创建的资源没有配置或配置过小的requests和limits带来的问题,比如创建一个requests.cpu默认为0.5(0.5为半颗CPU,1个CPU等于1000m)、requests.memory为256MB、limits.cpu为1、limits.memory为512MB的LimitRanger(创建完成后可以通过kubectl get limitrange cpu-mem-limit-range -oyaml查看):
touch cpu-mem-limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:name: cpu-mem-limit-rangenamespace: default
spec:limits:- default:cpu: 1memory: 512MidefaultRequest:cpu: 0.5memory: 256Mitype: Container
default: 当 Pod 没有指定资源限制时,为容器设置默认的 CPU 和内存上限。
defaultRequest: 当 Pod 没有指定资源请求时,为容器设置默认的 CPU 和内存请求。
type: 规定该规则适用于容器级别。
应用 LimitRange:
使用 kubectl 命令将 LimitRange 对象应用到 Kubernetes 集群中。kubectl apply -f cpu-mem-limit-range.yaml
验证 LimitRange:
可以使用以下命令查看已经定义的 LimitRange:kubectl get limitrange -n default删除limit rangekubectl delete limitrange cpu-mem-limit-range -n default
定义pod,touch nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx-podlabels:app: nginx
spec:containers:- name: nginx-containerimage: nginx:latestports:- containerPort: 80
kubectl apply -f nginx-pod.yaml
kubectl get pod nginx-pod -o yaml

可以看到该Pod被设置为LimitRanger的默认配置。
在配置了
requests和limits参数时,会以自行配置的为准(如果没有超过LimitRanger的最大、最小限制的话)。如果配置了limits而没有配置requests,那么requests的默认值将被设置成limits配置的参数,由于该配置和ResourceQuota类似,此处不再演示,可以参考ResourceQuota的步骤进行验证。
示例2:配置requests和limits的范围
上述针对没有设置requests和limits字段的资源添加了默认值,但是并没有限制requests和limits的最大值和最小值,这样同样会给集群带来风险,所以在管理资源分配时,对requests和limits的最大值和最小值也需要进行管控。
touch cpu-min-max-demo-1r.yaml
apiVersion: v1
kind: LimitRange
metadata:name: cpu-min-max-demo-1r
spec:limits:- max:cpu: "800m"memory: "1Gi"min:cpu: "200m"memory: "500Mi"type: Container
kubectl apply -f cpu-mem-limit-range.yaml
验证 LimitRange:
可以使用以下命令查看已经定义的 LimitRange:kubectl get limitrange -n defaultkubectl get limitrange cpu-min-max-demo-1r -o yaml

假设创建一个内存最大值超过limits限制的Pod:
vim nginx-pod1.yaml
kubectl apply -f nginx-pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx-pod
spec:containers:- name: nginximage: nginx:latestresources:limits:memory: "1.5Gi"requests:memory: "800Mi"

假设创建一个内存最小值小于limits最小值的Pod:
vim nginx-pod2.yaml
kubectl apply -f nginx-pod2.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx-pod
spec:containers:- name: nginximage: nginx:latestresources:limits:memory: "1.5Gi"requests:memory: "100Mi"

QoS
虽然我们进行了资源限制,但是实际使用时依旧会造成节点资源不足,针对资源不足Kubernetes会通过重启或驱逐Pod释放资源,再重启时,难免会造成一些很重要的服务不可用。但实际情况可能是,如果重启或驱逐一些不重要的Pod可能会更好,而这种决策是通过QoS(Quality of Service,服务质量)决定的,所以在生产环境中,QoS是一个非常重要的环节。
什么是服务质量保证
Kubernetes为我们提供了3种级别的服务质量,分别是:
Guaranteed:最高服务质量,当宿主机内存不够时,会先杀死QoS为BestEffort和Burstable的Pod,如果内存还是不够,才会杀死QoS为Guaranteed的Pod,该级别Pod的资源占用量一般比较明确,即requests字段的cpu和memory与limits字段的cpu和memory配置的一致。
Burstable:服务质量低于Guaranteed,当宿主机内存不够时,会先杀死QoS为BestEffort的Pod,如果内存还是不够,就会杀死QoS级别为Burstable的Pod,用来保证QoS质量为Guaranteed的Pod,该级别的Pod一般知道最小资源使用量,但是当机器资源充足时,还是想尽可能使用更多的资源,即limits字段的cpu和memory大于requests字段的cpu和memory的配置。
BestEffort:尽力而为,当宿主机内存不够时,首先杀死的就是该QoS的Pod,用以保证Burstable和Guaranteed级别的Pod正常运行。
示例1:实现QoS为Guaranteed的Pod
创建一个QoS为Guaranteed的Pod需要满足以下条件:
-
Pod中的每个容器必须指定
limits.memory和requests.memory,并且两者需要相等。 -
Pod中的每个容器必须指定
limits.cpu和limits.memory,并且两者需要相等。
定义一个Guaranteed的Pod:
apiVersion: v1
kind: Pod
metadata:name: guaranteed-pod
spec:containers:- name: app-containerimage: nginxresources:requests:memory: "128Mi"cpu: "500m"limits:memory: "128Mi"cpu: "500m"

如果容器指定了limits的cpu和memory配置,但是没有指定requests的cpu和memory配置,Kubernetes会自动添加和limits配置相同的requests配置。
示例2:实现QoS为Burstable的Pod
创建一个QoS为Burstable的Pod需要满足以下条件:
1)Pod不符合Guaranteed的配置要求。
2)Pod中至少有一个容器配置了requests.cpu或者requests.memory。
定义一个Burstable的Pod:
apiVersion: v1
kind: Pod
metadata:name: burstable-pod
spec:containers:- name: nginx-container-1image: nginx:latestresources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80env:- name: NGINX_PORTvalue: "80"command: [ "sh", "-c", "nginx -g 'daemon off;' -c /etc/nginx/nginx.conf" ]- name: nginx-container-2image: nginx:latestresources:requests:memory: "32Mi"cpu: "100m"ports:- containerPort: 8080env:- name: NGINX_PORTvalue: "8080"command: [ "sh", "-c", "echo \"server { listen 8080; location / { root /usr/share/nginx/html; index index.html index.htm; } }\" > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" ]
kubectl describe pod burstable-pod

在这个示例中,Pod包含两个容器:
nginx-container-1
设置了资源请求和限制,但它们是不相等的。这个配置允许容器在需要的时候 “bust”,即可以临时使用超过请求的资源限制,但受限于定义的最大限制。
nginx-container-1
只设置了资源请求,没有设置资源限制。这意味着它默认没有硬性资源限制,可以利用集群中额外的可用资源。
这样配置也使得Pod属于Burstable类别。
示例3:实现QoS为BestEffort的Pod
创建一个QoS为Burstable的Pod更为简单,Pod中的所有容器都没有设置requests和limits字段即可,比如创建一个QoS为BestEffort的Pod:
apiVersion: v1
kind: Pod
metadata:name: besteffort-pod
spec:containers:- name: app-container-1image: nginx
kubectl describe pod besteffort-pod

相关文章:
k8s 资源管理
文章目录 ResourceQuota什么是资源配额定义一个ResourceQuotaResourceQuota的使用 LimitRangeLimitRange的用途示例1:配置默认的requests和limits示例2:配置requests和limits的范围 QoS什么是服务质量保证示例1:实现QoS为Guaranteed的Pod示例…...
演示:基于WPF的自绘的中国地铁轨道控件
一、目的:演示一个基于WPF的自绘的中国地铁轨道控件 二、效果演示 北京地铁 成都地铁 上海地铁 深圳地铁 南京地铁 长春地铁 哈尔滨地铁 武汉地铁 厦门地铁 香港地铁 三、功能 支持平移、缩放等操作 鼠标悬停显示线路信息和站点信息 按表格显示,按纸张…...
设计模式(Design Patterns)
设计模式(Design Patterns)是软件开发人员在软件设计过程中面临的一般性问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。设计模式的目的是为了提高代码的可重用性、可维护性、可读性、可靠性以及灵活性。设…...
C++:opencv生成结构元素用于膨胀腐蚀等cv::getStructuringElement
cv::getStructuringElement 是 OpenCV 库中用于生成结构元素的函数。结构元素在形态学操作中(如膨胀、腐蚀、开运算、闭运算等)扮演着关键角色。这个函数可以创建不同形状和尺寸的结构元素,以适应不同的图像处理需求。 函数原型 cv::Mat cv…...
最大余额法,解决百分比计算相加不等于100%(扇形/饼图百分比使用的此算法)
在开发项目的过程中有时候需要进行计算百分比,例如计算饼状图百分比。有时候在计算的过程中常规四舍五入计算会发生所有计算的值相加不等于100%的情况 这是 get_percent_value 函数的 JavaScript 版本: /*** 最大余额法,解决百分比计算相加不…...
哈希表简单介绍
概念 在顺序结构以及平衡树中,元素关键字与他们存储的位置并没有直接的映射关系,从而会影响查找关键字的效率,顺序结构中查找关键字的时间复杂度为O(N),平衡树查找关键字的时间复杂度为O(log2^…...
kafka 之 本地部署单机版
安装JDK 查看你选择的版本需要安装哪一个版本的jdk 网址 下载 JDK下载 注:如果网页不允许下载,使用wget命令下载即可,下载之后安装。 建议使用rpm安装,之后使用 update-alternatives --config java 控制当前环境使用Java的版…...
开发一款通过蓝牙连接控制水电表的微信小程序
增强软硬件交互 为了更好的解决师生生活中的实际问题,开发蓝牙小程序加强了和校区硬件的交互。 比如通过蓝牙连接控制水电表,减少实体卡片的使用。添加人脸活体检测功能,提高本人认证效率,减少师生等待时间。 蓝牙水电控展示 蓝…...
力扣14.最长公共前缀
思路:将字符串数组中第一个字符串用作参考; 8.将他的长度作为范围,因为超范围了之后就不会再有公共前缀了 9.将字符串数组的长度也作为范围,意思是便利字符串数组中的字符串 11.开始第一层循环,依次遍历第一个字符串的…...
你也喜欢“钓鱼“吗?
免责声明:本文仅做分享! 目录 什么是网络钓鱼 流程 攻击手法 0-隐藏自己 1-office宏 创建xxx.dotm 创建xxx.docx 2-RLO 自解压 3-快捷方式lnk 4-邮件伪造 Swaks Gophish 5-网站克隆 setoolkit nginx反向代理 前端页面克隆 6-wifi钓鱼 7-其他 防御 溯源 反…...
druid jdbc 执行 sql 输出 开销耗时
druid 执行sql输出 参考链接配置_LogFilter alibaba/druid Wiki GitHub 看不太懂的往这里瞅瞅。 1. 别名映射 这个地方 给我们提供了 5 种 logfilter : log4j、log4j2、slf4j、commonlogging和commonLogging 每一种实际上都代表一个日志框架 或 日志门面。 -Ddruid.fil…...
C++如何处理内存碎片问题
目录 一.前言二.什么是内存碎片三.如何处理内存碎片 一.前言 这篇文章简单讨论一下C如何处理内存碎片问题。 二.什么是内存碎片 所谓内存碎片就是系统中存在的不能供进程使用的小块内存,主要包括外部碎片以及内部碎片。 外部碎片:内存分配和回收的过…...
FreeRTOS常用API接口函数
提示:FreeRTOS常用API接口函数:并对部分参数附上自己的解释,后面继续补充 FreeRTOS常用API接口函数 1.任务相关的API1.1 创建任务:xTaskCreate1.2 开启任务调度器函数:vTaskStartScheduler1.3 任务的删除:vTaskDelete1…...
DesignPattern设计模式
1 前言 1.1 内容概要 理解使用设计模式的目的掌握软件设计的SOLID原则理解单例的思想,并且能够设计一个单例理解工厂设计模式的思想,能够设计简单工厂,理解工厂方法了解建造者模式的思想,掌握其代码风格理解代理设计模式的思想&a…...
3.ChatGPT在教育领域的应用:教学辅助与案例分享(3/10)
ChatGPT在教育领域的应用:教学辅助与案例分享 引言 在21世纪的教育领域,技术革新正以前所未有的速度改变着传统的教学和学习方式。随着人工智能(AI)的快速发展,教育技术(EdTech)领域迎来了新的…...
Kafka+PostgreSql,构建一个总线服务
之前开发的系统,用到了RabbitMQ和SQL Server作为总线服务的传输层和存储层,最近一直在看Kafka和PostgreSql相关的知识,想着是不是可以把服务总线的技术栈切换到这个上面。今天花了点时间试了试,过程还是比较顺利的,后续…...
电脑怎么录屏?四款录屏工具分享
作为一个刚刚踏入视频创作领域的新手,我一直在寻找一款适合自己的录屏软件。最近,我尝试了四款市面上比较热门的录屏工具。今天,就让我来分享一下我的使用体验,希望能给同样在寻找录屏软件的朋友们一些参考。 一、福昕录屏大师 …...
Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计
文章目录 Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计0. 前言1. XXE代码审计【有1处】1.1. 搜索JRXmlLoader1.1.1. JRAntApiWriteTask1.1.2. JRAntUpdateTask1.1.3. TableReportContextXmlRule1.1.4. JasperCompileManager【存在漏洞】 1.2. 搜索XMLReader1.2…...
Leetcode 每日一题:Word Ladder
写在前面: 今天我们来看一道图论的题,这道题目是我做过目前最难与图论联想到的一道题目之一。如果没有提示的话,我们很容易往 dp 等解决 array 问题的方向去解决它,经过我超过 2个小时的思考我觉得这种方向是没前途的~…...
c++ 编辑器 和 编译器 的详细解释
在 C 开发中,编辑器 和 编译器 是两个不同的工具,分别在编写代码和生成可执行文件的过程中起着不同的作用。下面是它们的详细介绍: 1. 编辑器(Editor) 编辑器 是用来编写和编辑代码的工具。C 代码就是通过编辑器编写…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
