kubernetes之资源限制及QOS服务质量
1.什么是资源限制?
1.1在kubernetes集群中,为了使得系统能够稳定的运行,通常会对Pod的资源使用量进行限制。在kubernetes集群中,如果有一个程序出现异常,并且占用大量的系统资源,如果没有对该Pod进行资源限制的话,可能会影响其他的Pod正常运行,从而造成业务的不稳定性。
1.2正常情况下我们在一个宿主机的内核之上,这个宿主机可能管理了一组硬件包括CPU、内存。而后在这个宿主机的内核之上,我们可以运行多个容器,这些容器将共享底层的同一个内核,很显然,硬件是属于内核的,因此任何容器中的每一个进程默认可以请求占有这个内核管理的所有的可用硬件资源。
1.3尤其是多租户的环境当中,有人恶意的运行了一个容器,这个容器可能会大量的占用CPU和内存,进而会导致其他容器无法运行,Docker容器启动的时候默认是在内核的名称空间级别进行了隔离,在进程所运行的资源范围上并没有做太多的隔离操作。我们应该为每个应用设定内部进程运行最为合理的资源的最小保证量和最大保证量。
2.如何实现资源限制?
- kubernetes通过Requests和Limits字段来实现对Pod的资源限制;
- Requests: 启动Pod时申请分配的资源大小,即容器运行可能用不到这些额度的资源,但用到时必须确保有这么多的资源使用;(Pod在调度的时候requests比较重要)
- Limits: 限制Pod运行最大的可用的资源大小,即硬限制;(Pod在运行时limits比较重要)
- 相比较来说,CPU属于可压缩(compressible)资源,即资源额度可按需收缩,而内存则是不可压缩型资源,对其执行收缩操作可能会导致某种程度上的问题,如果超载,所有Pod内存加起来超过节点就会触发OOM机制,杀死Pod,具体杀死哪个Pod,就要看QOS服务质量。优先把评分低的杀掉;
- 正常情况下,Resources可以定义在Pod上也可以定义在Containers上。定义在Pod上是对Pod上所有容器都生效。一般而言我们定义资源是明确定义在每个容器上的,因为不同容器之间可能需求是不一样的。
spec.containers[].resources.request.cpu # Pod申请时的CPU,如果节点没有足够大,则Pod调度失败
spec.containers[].resources.request.memory # Pod申请时的内存
spec.containers[].resource.limits.cpu # Pod最大可使用的CPU
spec.containers[].resource.limits.memory # Pod最大可使用的内存
3.资源限制的目的
3.1我们为什么要进行资源限制?
- CPU: 为集群中运行的容器配置CPU请求和限制,可以有效的利用集群上可用的CPU资源;
设置Pod CPU请求,设置在较低的数值,可以使得Pod更有机会被调度节点;
通过设置CPU限制大于CPU请求,可以完成两件事:
1.当Pod碰到一些突发负载时,它可以合理利用可用的CPU资源。
2.当Pod在突发流量期间,可使用的CPU被限制为合理的值,从而可用避免影响其他Pod的正常运行; - memory: 为集群中运行的容器配置内存请求和限制,可以有效利用集群节点上的可以的内存资源;
通过将Pod的内存请求设定在较低的数值,可以有效的利用节点上可用的内存资源。通过让内存限制大于内存请求,可以完成如下:
1.当Pod碰到突发请求,可以更好的利用其主机上的可用内存;
2.当Pod在突发负载期间可使用的内存被限制为合理的数值,从而可用避免影响其他Pod的运行;
4.资源限制单位
4.1CPU限制单位
1核CPU=1000毫核,当定义容器为0.5时,所需要的CPU资源是1核心CPU的一般,对于CPU单位,表达式0.1等价于表达式100m,可以看作是100millicpu;
1核=1000millicpu (1 Core=1000m)
0.5核=500millicpu (0.5 Core=500m)
4.2内存限制单位
内存的基本单位是字节数(Bytes),也可以使用E、P、T、G、M、K作为单位后缀,或Ei、Pi、Ti、Gi、Mi和Ki形式单位后缀;
1MB=1000KB=1000000Bytes
1Mi=1024KB=1048576Bytes
5.资源限制配置案例
5.1CPU配置;
5.1.1设置容器的CPU请求与限制;
需安装Metrics-Server才能用top命令否则无法使用;
# 创建一个具有一个容器的Pod,容器将请求0.5个CPU,最多限制1个CPU;
root@kubernetes-master01:~# cat cpu-requests-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: cpu-test-cpu-limits
spec:
containers:
- name: cpu-test-stress
image: registry.cn-hangzhou.aliyuncs.com/lengyuye/stress:latest
args:
- -cpus # 容器尝试使用2核CPU
- "2"
resources:
requests: # 限制Pod最多可申请0.5核CPU
cpu: "500m"
limits: # 限制Pod最大可使用1核CPU
cpu: "1000m"
root@kubernetes-master01:~# kubectl apply -f cpu-requests-limits.yaml
pod/cpu-test-cpu-limits created
# 查看资源限制情况,容器配置去尝试使用2个CPU,但是容器只能被允许使用1个CPU;
root@kubernetes-master01:~# kubectl top pods cpu-test-cpu-limits
NAME CPU(cores) MEMORY(bytes)
cpu-test-cpu-limits 999m 1Mi
5.1.2创建一个Pod,设置该Pod中容器请求为100核,这个值会大于集群中所有内存的总和;
root@kubernetes-master01:~# cat cpu-requests-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: cpu-test-cpu-limits
spec:
containers:
- name: cpu-demo-ctr
image: registry.cn-hangzhou.aliyuncs.com/lengyuye/stress:latest
args:
- -cpus
- "2"
resources:
requests:
cpu: "100" # 设置Pod申请100GB,我们集群上没有100GB的资源
limits:
cpu: "100" # 最大使用100GB,集群资源不足,无法创建;
root@kubernetes-master01:~# kubectl apply -f cpu-requests-limits.yaml
pod/cpu-test-cpu-limits created
# 查看Pod的状态,为Pending,Pod未被调度到任何节点上;
root@kubernetes-master01:~# kubectl get pods
cpu-test-cpu-limits 0/1 Pending 0 4s
# 查看Events,输出显示由于3节点的CPU资源不足,无法进行调度;
root@kubernetes-master01:~# kubectl describe pods cpu-test-cpu-limits
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 113s default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
Warning FailedScheduling 113s default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
5.1.3如果不指定CPU的Limits?
如果没有为容器配置CPU限制,那么容器在可以使用的CPU资源是没有上限的,因而可以使用所在节点上的所有可用CPU资源,这样会造成某一个Pod占用了大量的CPU,可能会影响其他Pod的正常允许,从而造成业务的不稳定性。
5.2内存配置;
5.2.1设置容器的内存请求与限制;
创建一个1个容器Pod,容器会将请求100MB内存,并且最大可用内存为200MB以内;
root@kubernetes-master01:~# cat memory-requests-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-memory-resource
spec:
containers:
- name: momory-demo-stress
image: registry.cn-hangzhou.aliyuncs.com/lengyuye/stress:latest
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1" ]
resources:
requests:
memory: "100Mi" # 设置最小请求为100Mi
limits:
memory: "200Mi" # 最大可使用200Mi
root@kubernetes-master01:~# kubectl apply -f memory-requests-limits.yaml
pod/pod-memory-resource created
# 获取Pod的内存使用信息,输出结果显示Pod正在使用的内存约为150Mi,大于Pod请求的100Mi,但是在Pod限制的200Mi之内。
root@kubernetes-master01:~# kubectl top po pod-memory-resource
NAME CPU(cores) MEMORY(bytes)
pod-memory-resource 43m 151Mi
# 也可用通过Yaml文件的方式来看limits最大可使用为200Mi
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
5.2.2运行超过容器内存限制的应用
当节点拥有足够的可用内存时,容器可用使用其请求的内存,但是,容器不允许使用超过其限制的内存。如果容器分配的内存超过其限制,该容器会成为被终止的候选容器。如果容器继续消耗超过其限制的内存,则终止容器。如果终止的容器可以被重启,则kubelet会重新启动它。
5.2.2.1创建一个Pod,拥有一个Containers,该容器的内存请求为100Mi,内存限制为200Mi,尝试分配超出其限制的内存;
root@kubernetes-master01:~# cat memory-requests-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-memory-resource
spec:
containers:
- name: momory-demo-ctr
image: registry.cn-hangzhou.aliyuncs.com/lengyuye/stress:latest
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1" ] # 强行分配250M
resources:
requests:
memory: "100Mi"
limits:
memory: "200Mi" # 我们上限不能超过200,超过200Mi会发生OOM Kill
root@kubernetes-master01:~# kubectl apply -f memory-requests-limits.yaml
# 查看Pod,此时容器被杀死;
root@kubernetes-master01:~# kubectl get pods -w
pod-memory-resource 0/1 OOMKilled 0 9s
pod-memory-resource 0/1 OOMKilled 1 11s
pod-memory-resource 0/1 CrashLoopBackOff 1 12s
# 查看更详细的信息,显示为OOMKilled;
root@kubernetes-master01:~#kubectl get pod pod-memory-resource -o yaml
lastState:
terminated:
containerID: docker://3d6e53a12a101f474d24c00b8e9c5b1e6da2ef26735b6e2cb6790184c6d69cfa
exitCode: 1
finishedAt: "2022-07-27T06:40:07Z"
reason: OOMKilled
5.2.3超过节点的内存分配
Pod的调度基于请求,只有当前节点拥有足够满足Pod内存请求的内存时,才会将Pod调度至该节点运行;
5.2.3.1创建一个Pod,其拥有一个请求1000GB内存的容器,超出了集群任何一个节点所拥有的内存;
root@kubernetes-master01:~/cloud-Native/resource# cat memory-requests-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-memory-resource
spec:
containers:
- name: momory-demo-ctr
image: registry.cn-hangzhou.aliyuncs.com/lengyuye/stress:latest
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1" ]
resources:
requests:
memory: "100Gi"
limits:
memory: "200Gi"
root@kubernetes-master01:~# kubectl apply -f memory-requests-limits.yaml
# 查看Pod状态,发现处于pending,这意味着该Pod未被调度至任何节点;
root@kubernetes-master01:~# kubectl get pods -w
pod-memory-resource 0/1 Pending 0 6s
# 通过describe查看更详细信息;显示为由于节点内存不足,该容器无法被调度;
root@kubernetes-master01:~# kubectl describe pods pod-memory-resource
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 2m21s default-scheduler 0/3 nodes are available: 3 Insufficient memory.
Warning FailedScheduling 2m20s default-scheduler 0/3 nodes are available: 3 Insufficient memory.
5.2.4如果没有指定内存限制;
如果为容器指定内存限制,容器可以无限的使用其所在节点的所有可用内存,进而可能导致该节点调用OOM Killer。此外如果发生OOM Kill,没有配置资源限制的容器将被杀死的可能性会更大。
6.QOS服务质量
6.1什么是QOS?
kubernetes允许节点资源对limits的过载使用,这意味着节点无法同时满足其上的所有Pod对象以资源满载的方式运行,于是在内存资源紧缺时,应该以何种次序先后终止哪些Pod对象?
kubernetes无法自行对此做出决策,它需要借助于Pod对象的优先级判定,根据Pod对象的Requests和Limits属性,kubernetes将Pod对象归类到BestEffort、Burstable和Guaranteed三个服务质量(Quality of Service,QOS);
6.1.1Guaranteed: Pod对象为每个容器都设置了CPU资源需求和资源限制,且两者的值相同,还同时为每个容器设置了内存需求与内存限制,并且两者的值相同,这类Pod对象具有最高级别服务质量。
6.1.2Burstable: 至少有一个容器设置了CPU或内存资源Requests属性,但不满足Guaranteed,这类Pod具有中级服务质量;
6.1.3BestEffort: 没有为任何容器设置Requests和Limits属性,这类Pod对象服务质量是最低级别。
1.当kubernetes集群内存资源紧缺,优先杀死BestEffort类别的容器,因为系统不为该类资源提供任何服务保证,但是此类资源最大的好处就是能够尽可能的使用资源。
2.如果系统中没有BestEffort类别的容器,接下来就轮到Burstable类别的容器,如果有多个Burstable类别的容器,就看谁的资源占用多就优先杀死谁。对于Guaranteed类别的容器拥有最高优先级,他们不会被杀死,除非其内存需求超限,或OMM时没有其他更低优先级的Pod对象存在,才干掉Guaranteed类容器;
kubernetes之资源限制及QOS服务质量的更多相关文章
- kubernetes学习资源
参考文章: 1.kubernetes学习资源 1. <Kubernetes与云原生应用>系列之Kubernetes的系统架构与设计理念 2.[docker专业介绍的网站dockerinfo ...
- Kubernetes Pod 资源限制
Kubernetes Pod 资源限制 官方文档:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources- ...
- Kubernetes 针对资源紧缺处理方式的配置
如何在资源紧缺的情况下,保证 Node 的稳定性,是 Kubelet 需要面对的一个重要的问题.尤其对于内存和磁盘这种不可压缩的资源,紧缺就相当于不稳定. 在kubelet启动作为参数或者在配置文件中 ...
- Kubernetes 学习22 kubernetes容器资源需求资源限制及HeapSter(翻车章节)
一.概述 1.接下来介绍在k8s上运行pod对象时我们如何去监控我们系统级的资源指标以及业务级别的资源指标.数据如何获取和监控.在此之前先介绍一下Pod对象的资源请求和资源限制.即容器的资源需求和资源 ...
- Kubernetes中资源配额管理
设置资源请求数量 创建Pod的时候,可以为每个容器指定资源消耗的限制.Pod的资源请求限制则是Pod中所有容器请求资源的总和. apiVersion: v1 kind: Pod metadata: n ...
- QoS 服务质量
一.QoS QoS: Quality of Service(服务质量) 是指网络通信过程中,允许用户业务在丢包率.延迟.抖动和带宽等方面获得可预期的服务水平.更简单地说:QoS就是针对各种不同需求,提 ...
- kubernetes创建资源对象yaml文件例子--pod详解
apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: ...
- [置顶]
kubernetes创建资源yaml文件例子--pod
kubernetes创建pod的yaml文件,参数说明 apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 ...
- 【Kubernetes】资源列表
1.Kubernetes资源列表 https://www.cnblogs.com/linuxk/p/10436260.html
随机推荐
- Redis进阶知识一览
Redis的持久化机制 RDB: Redis DataBase 什么是RDB RDB∶每隔一段时间,把内存中的数据写入磁盘的临时文件,作为快照,恢复的时候把快照文件读进内存.如果宕机重启,那么内存里的 ...
- 【Java8新特性】Stream(分类+案例)
一.Stream概述 什么是Stream? Stream是Java8引入的全新概念,它用来处理集合中的数据,可以让你以一种声明的方式处理数据. Stream 使用一种类似用 SQL 语句从数据库查询数 ...
- Git技法:.gitignore、移除暂存与撤销修改
1. .gitignore常见项目添加 1.1 .gitignore模板 .gitignore针对每个语言都有对应的模板,在GitHub创建项目时就可以选择(你可以在GitHub提供的.gitigno ...
- 专家PID控制仿真学习
目录 专家控制 专家系统 专家控制 学习笔记,用于记录学习 资料:<智能控制>(第四版)--刘金琨 专家系统 一.专家系统的定义 专家系统是一类包含知识和推理的智能计算机程序,其内部包含某 ...
- mybatis-plus分页插件
package com.tanhua.server.config; import com.baomidou.mybatisplus.extension.plugins.PaginationInterc ...
- ThreadLocal模板
public class UserIdThreadLocal { private static final ThreadLocal<Long>LOCAL=new ThreadLocal&l ...
- USB机械键盘改蓝牙键盘
手里有两把机械键盘,一个是IKBC 87键,一个是IKBC POKER II 60键,由于买的比较早,两把键盘均为USB的,使用起来桌面线比较多,碍事,于是开始研究如何改成蓝牙键盘. 首先说一下USB ...
- SSMS设置为深色模式
更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2022年2月8日. 2022年4月16日:SSMS很好用,但现在我更多使用DataGrip了. 2022年6月11日:S ...
- Ubuntu 配置 .NET 使用环境
本文迁移自Panda666原博客,原发布时间:2021年3月29日. 说明 测试使用的环境 Linux版本:Ubuntu Server 20.04 LTS x64 .NET SDK版本:5.0 其他版 ...
- RPA应用场景-报税机器人
场景概述 报税机器人 所涉系统名称 税务网站 人工操作(时间/次) 53分钟 所涉人工数量 60 操作频率 每月 场景流程 1.通过RPA自动将财税信息从对应系统中导出 2.RPA根据不同的税务报表规 ...