【kubernetes系列】kubernetes之计算资源管理

news2025/1/23 13:07:02

资源类型

在 Kubernetes 中,Node 提供资源,而 Pod 使用资源。其中资源分为计算(CPU、Memory、GPU)、存储(Disk、SSD)、网络(Network Bandwidth、IP、Ports)。这些资源提供了应用运行的基础,正确理解这些资源以及集群调度如何使用这些资源,对于大规模的 Kubernetes 集群来说至关重要,不仅能保证应用的稳定性,还可以提高资源的利用率。在日常工作中,我们一般比较关心其中的计算资源,包括CPU和内存。CPU 的单位是 core,memory 的单位是 byte。

可压缩资源

目前kubernetes支持的可压缩资源是CPU。它的特点是,当可压缩资源不足时,Pod 只会饥饿少用,但不会退出。CPU 资源的限制和请求以cpu为单位。Kubernetes 中的一个 cpu 就是一个核,就是一个逻辑CPU。一个核相当于1000个微核,即1=1000m,0.5=500m。

不可压缩资源

目前kubernetes支持的不可压缩资源是内存。它的特点是,当不可压缩资源不足时,Pod 就会因为 OOM被内核杀掉。内存的限制和请求以字节为单位。可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。

POD中的资源请求和资源限制

requests 资源请求 pod最低需求(表示Pod对资源的最小需求,因此在调度的时候会如果Node剩余的资源不能满足Pod的需求,则不会调度到对应的Node上。Scheduler调度的时候并不关注在调度时具体的资源使用情况,而是根据现存Pod的资源请求情况来进行调度。调度器首先将不符合请求的Node排除在外,然后在执行优选策略最后在选定pod)

由于 Pod 可以由多个 Container 组成,所以 CPU 和内存资源的限额,是要配置在每个Container的定义上的。这样,Pod 整体的资源配置,就由这些 Container的配置值累加得到。

示例

执行下面yaml的内容:

[root@k8s-m1 k8s-resource]# cat resource-limit-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: resource-limit-pod
  namespace: default
  labels:
    name: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/stress-ng
    command: ["/usr/bin/stress-ng","-c 1","--metrics-brief"]
    ports:
    - name: http
      containerPort: 80
    resources:
      requests:
        memory: "128Mi"
        cpu: "200m"
      limits:
        memory: "512Mi"
        cpu: "500m"
[root@k8s-m1 k8s-resource]# kubectl apply  -f resource-limit-pod.yaml 
pod/resource-limit-pod created

查看结果:

[root@k8s-m1 k8s-resource]# kubectl exec -it resource-limit-pod -- top
Mem: 7805096K used, 202092K free, 6444K shrd, 2104K buff, 4575292K cached
CPU:   3% usr   1% sys   0% nic  88% idle   6% io   0% irq   0% sirq
Load average: 0.14 0.55 0.71 3/1509 33
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    6     1 root     R     6892   0%  15   2% {stress-ng-cpu} /usr/bin/stress-ng -c 1 --metrics-brief
    1     0 root     S     6244   0%   9   0% /usr/bin/stress-ng -c 1 --metrics-brief
   29     0 root     R     1500   0%   9   0% top

我们看到CPU占用是3%,为什么呢?因为我的集群node都是是16个core。我们最大限制是0.5核。所以应该是0.5/16≈3.1%。

Request和Limits

基于Requests和Limits的Pod调度机制

  • 调度器在调度时,首先要确保调度后该节点上所有Pod的CPU和内存的Requests总和,不超过该节点能提供给Pod使用的CPU和Memory的最大容量值;
  • 即使某节点上的实际资源使用量非常低,但是已运行Pod配置的Requests值的总和非常高,再加上需要调度的Pod的Requests值,会超过该节点提供给Pod的资源容量上限,这时Kubernetes仍然不会将Pod调度到该节点上。如果Kubernetes将Pod调度到该节点上,之后该节点上运行的Pod又面临服务峰值等情况,就可能导致Pod资源短缺;

Requests和Limits的背后机制

kubelet在启动Pod的某个容器时,会将容器的Requests和Limits值转化为相应的容器启动参数传递给容器执行器。如果是docker 容器:

  • spec.container[].resources.requests.cpu: 转化为docker 的–cpu-share;
  • spec.container[].resources.limits.cpu: 转为docker的–cpu-quota;
  • spec.container[].resources.requests.memory: 提供给Kubernetes调度器作为调度和管理的依据,不会作为任何参数传递给Docker;
  • spec.container[].resources.limits.memory: 会转为–memory;
    在这里插入图片描述

QoS(服务质量等级)

Kubernetes是根据Pod的Requests和Limits配置来实现针对Pod的不同级别的资源服务质量控制。当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS 等级。

QoS分类

  • Guaranteed:pod里的每一个container都同时设置了CPU和内存的requests和limits 而且值必须相等。(这类的pod是最高优先级)
  • Burstable:pod至少有一个container设置了cpu或内存的requests和limits,且不满足 Guarantee 等级的要求。即内存或CPU的值设置的不同。(中等优先级)
  • BestEffort:没有任何一个容器设置了requests或limits的属性。(最低优先级)

应用场景:当宿主机资源紧张的时候,kubelet会根据服务质量等级对pod进行eviction,即驱逐pod进行资源回收。

Requests和Limits资源配置特点

  • 如果Pod配置的Requests值等于Limits值,那么该Pod可以获得的资源是完全可靠的;
  • 如果Pod的Requests值小于Limits值,那么该Pod获得的资源可分成两部分;

完全可靠的资源,资源量的大小等于Requests值;
不可靠的资源,资源量最大等于Limits与 Requests的差额,这份不可靠的资源能够申请到多少,取决于当时主机上容器可用资源的余量;通过这种机制,Kubernetes可以实现节点资源的超售(Over Subscription),超售机制能有效提高资源的利用率,同时不会影响容器申请的完全可靠资源的可靠性。

调度策略的影响

  • Kubernetes的kubelet通过计算Pod中所有容器的Requests的总和来决定对Pod的调度;
  • 不管是CPU还是内存,Kubernetes调度器和kubelet都会确保节点上所有Pod的Requests的总和不会超过在该节点上可分配给容器使用的资源容量上限;

示例

https://www.cnblogs.com/wtzbk/p/15816291.html

Guaranteed样例

[root@k8s-m1 k8s-resource]# cat   guaranteed-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: guaranteed-pod
  labels:
    name: nginx
spec:
  containers:
  - name: myapp
    image: nginx
    ports:
    - name: http
      containerPort: 80
    resources:
      requests:
        memory: "512Mi"
        cpu: "500m"
      limits:
        memory: "512Mi"
        cpu: "500m"
[root@k8s-m1 k8s-resource]# kubectl apply -f guaranteed-pod.yaml 
pod/guaranteed-pod created

结果:

[root@k8s-m1 k8s-resource]# kubectl describe po guaranteed-pod 
......
Volumes:
  default-token-glxls:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-glxls
    Optional:    false
QoS Class:       Guaranteed
Node-Selectors:  <none>
.....

更详细检查
1)查看该pod被分配到的节点

[root@k8s-m1 k8s-resource]# kubectl get pod -o wide
NAME                 READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
guaranteed-pod       1/1     Running   0          8s      10.244.11.39    k8s-m3   <none>           <none>

2)然后到k8s-m3上去查看这个pod里面启动的容器的资源限制是否生效

[root@k8s-m3 ~]# docker ps |grep guaranteed
434a95e67849   nginx                                               "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes             k8s_myapp_guaranteed-pod_default_7095c77a-7c31-4a0a-ba1c-c347c690cfe8_0
32a0053da67b   registry.aliyuncs.com/google_containers/pause:3.2   "/pause"                 6 minutes ago   Up 6 minutes             k8s_POD_guaranteed-pod_default_7095c77a-7c31-4a0a-ba1c-c347c690cfe8_0

#查看主容器的信息
[root@k8s-m3 ~]# docker inspect  434|egrep -i 'cpu|mem'
            "CpuShares": 512,
            "Memory": 536870912,
            "NanoCpus": 0,
            "CpuPeriod": 100000,
            "CpuQuota": 50000,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 536870912,
            "MemorySwappiness": null,
            "CpuCount": 0,
            "CpuPercent": 0,
关注Memory、CpuPeriod、CpuQuota这三个值

3)通过cgroup的相关信息查看
从上面的结果实际上我们就可以看到这个容器的一些资源情况,Pod 上的资源配置最终也还是通过底层的容器运行时去控制 CGroup 来实现的,我们可以进入如下目录查看 CGroup 的配置,该目录就是 CGroup 父级目录,而 CGroup 是通过文件系统来进行资源限制的,所以我们上面限制容器的资源就可以在该目录下面反映出来:
##查看CPU的限制##

[root@k8s-m3 ~]# docker exec -it 434 /bin/bash
root@guaranteed-pod:/# cd /sys/fs/cgroup/cpu/
root@guaranteed-pod:/sys/fs/cgroup/cpu# cat cpu.cfs_period_us 
100000
root@guaranteed-pod:/sys/fs/cgroup/cpu# cat cpu.cfs_quota_us  
50000
root@guaranteed-pod:/sys/fs/cgroup/cpu# 
#反向计算出--cpus参数
#cpu.cfs_quota_us / cpu.cfs_period_us = cpu的限制
50000/100000=0.5核(也就是500m)

##查看内存的限制##
root@guaranteed-pod:/sys/fs/cgroup/cpu# cd /sys/fs/cgroup/memory/
root@guaranteed-pod:/sys/fs/cgroup/memory# cat memory.limit_in_bytes 
536870912
root@guaranteed-pod:/sys/fs/cgroup/memory# 

内存的计算方法为:536870912÷1024÷1024÷1024 = 0.5(G)

Burstable样例

[root@k8s-m1 k8s-resource]# cat  burstable-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: burstable-pod
  labels:
    name: nginx
spec:
  containers:
  - name: myapp
    image: nginx
    ports:
    - name: http
      containerPort: 80
    resources:
      requests:
        memory: "256Mi"
        cpu: "200m"
      limits:
        memory: "512Mi"
        cpu: "500m"

[root@k8s-m1 k8s-resource]# kubectl apply  -f burstable-pod.yaml 
pod/burstable-pod created

结果:

[root@k8s-m1 k8s-resource]# kubectl describe po burstable-pod 
......
Volumes:
  default-token-glxls:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-glxls
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
......

上面Burstable的示例中,可以看到limit和Request都设置了的,且limit大于Request。大家可以自行测试只设置其中一个的Qos等级。当只设置Request时,系统是不会补全limit的相关配置,也是Burstable。而当只设置limit时,系统会自动补全Request的相关配置和limit一样,Qos是Guaranteed类型。

BestEffort样例

[root@k8s-m1 k8s-resource]# cat  besteffort-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: besteffort-pod
  labels:
    name: myapp
    tier: appfront
spec:
  containers:
  - name: http
    image: nginx
    ports:
    - name: http
      containerPort: 80

[root@k8s-m1 k8s-resource]# kubectl apply -f besteffort-pod.yaml 
kupod/besteffort-pod created

结果:

[root@k8s-m1 k8s-resource]# kubectl describe po besteffort-pod 
......
Volumes:
  default-token-glxls:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-glxls
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
.....

总结:
CPU是可以压缩资源,所以在CPU不够的时候会压缩限流。而内存是不可压缩资源,所以QoS主要用于内存限制。

  • BestEffort Pod的优先级最低,在这类Pod中运行的进程会在系统内存紧缺时被第一优先杀掉。当然,从另外一个角度来看,BestEffort Pod由于没有设置资源Limits,所以在资源充足时,它们可以充分使用所有的闲置资源;
  • Burstable Pod的优先级居中,这类Pod初始时会分配较少的可靠资源,但可以按需申请更多的资源。当然,如果整个系统内存紧缺,又没有BestEffort容器可以被杀掉以释放资源,那么这类Pod中的进程可能会被杀掉;
  • Guaranteed Pod的优先级最高,而且一般情况下这类Pod只要不超过其资源Limits的限制就不会被杀掉。当然,如果整个系统内存紧缺,又没有其他更低优先级的容器可以被杀掉以释放资源,那么这类Pod中的进程也可能会被杀掉;

OOM计分系统

在这里插入图片描述
如果kubelet无法在系统OOM之前回收足够的内存,则oom_killer 会根据内存使用比率来计算oom._score, 将得出的结果和oom_score_adj相加,最后得分最高的Pod会被首先驱逐。这个策略的思路是,QoS最低且相对于调度的Request来说消耗最多内存的Pod会被首先清除,来保障内存的回收。这意味着与Burstable或Guaranteed QoS类别的容器相比,BestEffort这种类别的容器被杀死的可能性更高。
与Pod驱逐不同,如果一个Pod的容器被oom杀掉,是可能被 kubelet根据restartpolicy重启的。

容器中的JVM资源限制

在Kubernetes环境中部署Java程序不一会就重启了,这意味着你的pod是不健康的。然后我们可以通过describe去查看一下重启的原因。发现是因为Pod超出了资源限制被kill掉,在日志最后一行会出现一个kill的字段。为什么Kubernetes会kill掉,因为它超出了Kubernetes对Pod的资源限制。默认情况下Docker容器会使用宿主机所有的资源,但如果不做资源限制,会影响整个宿主机。然后整个宿主机资源不够会实现飘移,会转移到其他主机上,然后再异常,可能会起到一种雪崩的效应,所以一般我们都是要做Pod资源限制。如果Java容器中未设置JVM的-Xmx(最大的堆内存使用)参数,一旦这个Pod的使用内存超出Kubernetes的limits限制,Kubernetes就会把它杀掉并重启一个新的Pod。所以在实际使用中,JVM中的这个值建议要比limits要小一点,小个10%左右,因为超过这个limits限制就可能会被杀死掉再重新起一个Pod。

更多关于kubernetes的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767690.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DIN - 序列模型之深度兴趣网络(阿里)

&#x1f525; DIN来自于 阿里 盖坤团队 在 KDD-2018 发的论文《Deep Interest Network for Click-Through Rate Prediction》。该模型在当时已经应用于阿里的电商广告推荐业务&#xff0c;效果不错。 文章目录 1、介绍&#xff1a;2、单值特征 & 多值特征&#xff1a;3、动…

共筑信创生态!亚信科技AntDB数据库与用友、东方通、星辰天合达成兼容互认

近日&#xff0c;亚信科技AntDB数据库与用友U8 cloud、东方通应用服务器TongWeb V7.0、星辰天合全产品体系完成兼容适配。经测试&#xff0c;AntDB数据库与U8 cloud产品&#xff0c;TongWeb V7.0服务器&#xff0c;星辰天合天合翔宇分布式存储系统、统一数据平台XEDP、超融合平…

分析分布式架构-技术

分布式系统的主要目的 提高系统的性能 提高吞吐量&#xff0c;服务更多的客户。提高并发和流量。 通过以下的技术提高处理高并发场景的能力 缓存系统&#xff0c;更快的响应客户端的请求。降低对数据库的压力(提高响应速度) 前端浏览器&#xff0c;网络&#xff0c;后端服务&a…

深入理解Linux网络——TCP连接的开销

文章目录 一、相关实际问题二、Linux内核如何管理内存1&#xff09;node划分2&#xff09;zone划分3&#xff09;基于伙伴系统管理空闲页面4、slab分配器5&#xff09;小结 三、TCP连接相关内核对象1&#xff09;socket函数直接创建1. sock_inode_cache对象申请2. tcp对象申请3…

自建sqlserver迁移到aliyun的rds for sqlserver实战

大家好&#xff0c;在实际中有些客户有上云的需求&#xff0c;需要把线下自建的sqlserver迁移至aliyun的rds for sqlserver。大家第一时间想到的是用dts工具&#xff0c;根据工作经验&#xff0c;DTS迁移mysql类的数据库比较成熟&#xff0c;但是迁移sqlserver之类会有问题。首…

二本逆互联网大厂! 高薪就业

【二本屌丝也能逆袭&#xff01;毕业四年从小公司到大厂之路&#xff0c;这就是我的逆袭&#x1f680;✨】 大家对如何逆袭互联网大厂而感到惊讶&#xff1f;作为计算机专业的大学生&#xff0c;想必你对于进入互联网行业有很多的期望和追求。但是面对激烈的竞争和复杂的招聘要…

wasserstein distance简单记录

W a s s e r s t e i n Wasserstein Wasserstein d i s t a n c e distance distance一般被称为推土距离&#xff0c;假设有两个分布 P ( x ) P(x) P(x)和 Q ( y ) Q(y) Q(y) &#xff0c;两个分布间的推土距离为&#xff1a; W ( P , Q ) inf ⁡ γ ∈ Π ( P , Q ) E ( x ,…

深度学习trick

本次Tricks主要面向于深度学习中计算机视觉方向的研究&#xff0c;分为数据增广方法、训练技巧&#xff0c;参数调节这三个方面进行深入的分析。内容有一部分是基于openmmlab的mmdet和mmseg两个框架上的成熟应用案例进行详细阐述。 首先是数据增广的tricks&#xff1a; 0、Fli…

【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~

Java基础教程之包及访问权限 下 本节学习目标1️⃣ 访问控制权限2️⃣ 命名规范3️⃣ 单例设计模式 (Singleton)4️⃣ 多例设计模式 本节学习目标 掌握Java 中的4种访问权限&#xff1b;掌握Java 语言的命名规范&#xff1b;掌握单例设计模式与多例设计模式的定义结构&#x…

【HISI IC萌新虚拟项目】cpu_if的接口cpu_agent utils搭建

关于整个虚拟项目,请参考: 【HISI IC萌新虚拟项目】Package Process Unit项目全流程目录_尼德兰的喵的博客-CSDN博客 前言 spt_agent utils已经完成了(虽然之后可能还会有微调),接下来完成配置通路cpu interface对应的utils。这个通路比较特殊,一是带反馈的接口,二是时…

Android 通过插桩来代理线程池

前言 在日常开发App的过程中&#xff0c;难免需要依赖第三方Sdk&#xff0c;这样就无形中增加了我们自己App的线程数&#xff0c;从而会导致App出现内存溢出、Cpu消耗增加等等负面影响。如果依赖的Sdk提供了线程池代理的接口还好&#xff0c;那样直接设置我们自定义的线程池。但…

密码学学习笔记(十五):ECDSA - 椭圆曲线数字签名算法

椭圆曲线数字签名算法是DSA的一种椭圆曲线变体&#xff0c;它发明的初衷只是避免使用Schnorr签名的专利。椭圆曲线数字签名算法依赖于验证器中的私钥和主机用于验证验证器的公钥。它的缺点和DSA一样&#xff0c;它也没有提供安全性证明。 椭圆曲线算法 DSS&#xff08;数字签…

工作空间内各文件夹解析

src文件夹用来存放源代码 launch文件夹用来存放一个或多个ros节点启动文件 msg文件夹包含用户定制化消息的定义 srv文件夹包含各种服务的定义 action文件夹包含动作文件 package.xml是软件包清单文件 Cmakelists.txt文件包含编译软件包的各类指令

面试官: 说一下你做过哪些性能优化?

前言 如果你已经有 2 - 3 年以上开发经验还不懂的怎么去优化自己的项目&#xff0c;那就有点说不过去了&#xff0c;下面是我自己总结的一套通用级别的 Android 性能优化。 如果你正在找工作, 那么你需要一份 Android 高级开发面试宝典 1、 你对 APP 的启动有过研究吗? 有做过…

Spring解决数据乱码问题-spring21

乱码数据实际情况&#xff1a; 都出现了&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 怎么解决&#xff1a; 第一步&#xff0c;找到web.xml配置文件。 改成name控制台就不出来了 如何解决地址方法与Controller业务参数名称不一致的情况&#xf…

Linux 之 基本工具(一)

一、粘滞位 1.背景 在现实生活中&#xff0c;有很多人会在同一台云服务器上共同工作&#xff0c;会出现这些人的某些文件需要保存但又不想保存在各自的家目录下且这些文件需要共给其他一同工作的同事共享&#xff08;可查阅&#xff09;的情况&#xff0c;则需要将这些文件保…

Mysql表锁与行锁

Mysql锁实战 前言&#xff1a;什么是锁一&#xff1a;全局锁1.1 概念1.2 作用1.3 使用1.4 特点 二&#xff1a;表级锁2.1 概念2.2 分类2.2.1 表锁2.2.2 元数据锁 MDL2.2.3 意向锁 三&#xff1a;行级锁3.1 行锁(Record Lock)3.2 间隙锁(Gap Lock)3.3 临键锁(Next-Key Lock): 四…

redis乐观锁概念

乐观锁&#xff08;又名乐观并发控制&#xff0c;Optimistic Concurrency Control&#xff0c;缩写“OCC”&#xff09;&#xff0c;是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响&#xff0c;各事务能够在不产生锁的情况下处理各自影响的那部分数据。…

Ubuntu下安装、配置及重装CUDA教程

安装CUDA 前往Nvidia CUDA Tools官网选择对应的架构和版本下载CUDA 以如下架构和版本为例&#xff1a; 查看显卡驱动 nvidia-smi如果显卡驱动已经装了&#xff0c;那么在CUDA安装过程中不用再勾选安装driver 下载并安装CUDA wget https://developer.download.nvidia.co…

如何设计一个完美的复杂业务系统架构?

1 什么是复杂系统 我们经常提到复杂系统&#xff0c;那么到底什么是复杂系统。我们看下维基的定义&#xff1a;复杂系统&#xff08;英语&#xff1a;complex system&#xff09;&#xff0c;又称复合系统&#xff0c;是指由许多可能相互作用的组成成分所组成的系统。强调了两…