十四. k8s资源需求和限制, 以及pod驱逐策略

目录

  • 容器的资源需求和资源限制
  • QoS Classes分类
    • Guaranteed
    • Burstable
    • Best-Effort
  • kubernetes之node资源紧缺时pod驱逐机制
    • Qos Class优先级排名
    • 可压缩资源与不可压缩资源
    • 存储资源不足
      • 举例
    • 内存资源不足
      • 举例
    • Node OOM (Out Of Memory)
    • 总结
  • 参考链接

容器的资源需求和资源限制

  • requests:需求,最低保障, 保证被调度的节点上至少有的资源配额
  • limits:限制,硬限制, 容器可以分配到的最大资源配额

apiVersion: v1
kind: Pod
metadata:
    name: pod-demo
    labels:
        app: myapp
        tier: fronted
spec:
    containers:
    - name: myapp
      image: ikubernetes/stress-ng
      command: ["/usr/bin/stress-ng", "-m 1", "-c 1", "--metrics-brief"]
      resources:
        requests:
          cpu: "200m"
          memory: "128Mi"
        limits:
          cpu: "500m"
          memory: "200Mi"
kubectl exec pod-demo -- top

这是一个CPU为2核的节点, 分配给容器500m的CPU, 也就是0.5个CPU, 所以看到的进程CPU占用率约为26%

QoS Classes分类

Guaranteed

如果Pod中所有Container的所有Resource的limitrequest都相等且不为0,则这个Pod的QoS Class就是Guaranteed。

注意,如果一个容器只指明了limit,而未指明request,则表明request的值等于limit的值。

containers:
    name: foo
        resources:
            limits:
                cpu: 10m
                memory: 1Gi
    name: bar
        resources:
            limits:
                cpu: 100m
                memory: 100Mi
            requests:
                cpu: 100m
                memory: 100Mi

Burstable

至少有一个容器设置CPU或内存资源的requests属性

Best-Effort

如果Pod中所有容器的所有Resource的request和limit都没有赋值,则这个Pod的QoS Class就是Best-Effort.

containers:
    name: foo
        resources:
    name: bar
        resources:

kubernetes之node资源紧缺时pod驱逐机制

Qos Class优先级排名

Guaranteed > Burstable > Best-Effort

可压缩资源与不可压缩资源

Pod 使用的资源最重要的是 CPU、内存和磁盘 IO,这些资源可以被分为可压缩资源(CPU)不可压缩资源(内存,磁盘 IO)

  • 可压缩资源(CPU)不会导致pod被驱逐

    因为当 Pod 的 CPU 使用量很多时,系统可以通过重新分配权重来限制 Pod 的 CPU 使用

  • 不可压缩资源(内存)则会导致pod被驱逐

    于不可压缩资源来说,如果资源不足,也就无法继续申请资源(内存用完就是用完了),此时 Kubernetes 会从该节点上驱逐一定数量的 Pod,以保证该节点上有充足的资源。

存储资源不足

下面是 kubelet 默认的关于节点存储的驱逐触发条件:

  • nodefs.available<10%(容器 volume 使用的文件系统的可用空间,包括文件系统剩余大小和 inode 数量)
  • imagefs.available<15%(容器镜像使用的文件系统的可用空间,包括文件系统剩余大小和 inode 数量)

imagefs 使用量达到阈值时,kubelet 会尝试删除不使用的镜像来清理磁盘空间。

nodefs 使用量达到阈值时,kubelet 就会拒绝在该节点上运行新 Pod,并向 API Server 注册一个 DiskPressure condition。然后 kubelet 会尝试删除死亡的 Pod 和容器来回收磁盘空间,如果此时 nodefs 使用量仍然没有低于阈值,kubelet 就会开始驱逐 Pod。kubelet 驱逐 Pod 的过程中不会参考 Pod 的 QoS,只是根据 Pod 的 nodefs 使用量来进行排名,并选取使用量最多的 Pod 进行驱逐。所以即使 QoS 等级为 Guaranteed 的 Pod 在这个阶段也有可能被驱逐(例如 nodefs 使用量最大)。如果驱逐的是 Daemonset,kubelet 会阻止该 Pod 重启,直到 nodefs 可用量超过阈值。

如果一个 Pod 中有多个容器,kubelet 会根据 Pod 中所有容器的 nodefs 使用量之和来进行排名。即所有容器的 container_fs_usage_bytes 指标值之和。

举例

Pod Name Pod QoS nodefs usage
A Best Effort 800M
B Guaranteed 1.3G
C Burstable 1.2G
D Burstable 700M
E Best Effort 500M
F Guaranteed 1G

当 nodefs 的使用量超过阈值时,kubelet 会根据 Pod 的 nodefs 使用量来对 Pod 进行排名,首先驱逐使用量最多的 Pod。排名如下图所示:

Pod Name Pod QoS nodefs usage
B Guaranteed 1.3G
C Burstable 1.2G
F Guaranteed 1G
A Best Effort 800M
D Burstable 700M
E Best Effort 500M

内存资源不足

下面是 kubelet 默认的关于节点内存资源的驱逐触发条件:

  • memory.available<100Mi

当内存使用量超过阈值时,kubelet 就会向 API Server 注册一个 MemoryPressure condition,此时 kubelet 不会接受新的 QoS 等级为 Best Effort 的 Pod 在该节点上运行,并按照以下顺序来驱逐 Pod:

  • Pod 的内存使用量是否超过了 request 指定的值
  • 根据 priority 排序,优先级低的 Pod 最先被驱逐
  • 比较它们的内存使用量与 request 指定的值之差。

按照这个顺序,可以确保 QoS 等级为 Guaranteed 的 Pod 不会在 QoS 等级为 Best Effort 的 Pod 之前被驱逐,但不能保证它不会在 QoS 等级为 Burstable 的 Pod 之前被驱逐。

如果一个 Pod 中有多个容器,kubelet 会根据 Pod 中所有容器相对于 request 的内存使用量与之和来进行排名。即所有容器的 (container_memory_usage_bytes 指标值与 container_resource_requests_memory_bytes 指标值的差)之和。

举例

Pod Name Pod QoS Memory requested Memory limits Memory usage
A Best Effort 0 0 700M
B Guaranteed 2Gi 2Gi 1.9G
C Burstable 1Gi 2Gi 1.8G
D Burstable 1Gi 2Gi 800M
E Best Effort 0 0 300M
F Guaranteed 2Gi 2Gi 1G

当节点的内存使用量超过阈值时,kubelet 会根据 Pod 相对于 request 的内存使用量来对 Pod 进行排名。排名如下所示:

Pod Name Pod QoS Memory requested Memory limits Memory usage 内存相对使用量
C Burstable 1Gi 2Gi 1.8G 800M
A Best Effort 0 0 700M 700M
E Best Effort 0 0 300M 300M
B Guaranteed 2Gi 2Gi 1.9G -100M
D Burstable 1Gi 2Gi 800M -200M
F Guaranteed 2Gi 2Gi 1G -1G

当内存资源不足时,kubelet 在驱逐 Pod 时只会考虑 requests 和 Pod 的内存使用量,不会考虑 limits。

Node OOM (Out Of Memory)

因为 kubelet 默认每 10 秒抓取一次 cAdvisor 的监控数据,所以有可能在 kubelet 驱逐 Pod 回收内存之前发生内存使用量激增的情况,这时就有可能触发内核 OOM killer。这时删除容器的权利就由kubelet 转交到内核 OOM killer 手里,但 kubelet 仍然会起到一定的决定作用,它会根据 Pod 的 QoS 来设置其 oom_score_adj 值:

QoS oom_score_adj
Guaranteed -998
Burstable min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
pod-infra-container -998
kubelet, docker daemon, systemd service -999

如果该节点在 kubelet 通过驱逐 Pod 回收内存之前触发了 OOM 事件,OOM killer 就会采取行动来降低系统的压力,它会根据下面的公式来计算 oom_score 的值:

容器使用的内存占系统内存的百分比 + oom_score_adj = oom_score>

OOM killer 会杀掉 oom_score_adj 值最高的容器,如果有多个容器的 oom_score_adj 值相同,就会杀掉内存使用量最多的容器(其实是因为内存使用量最多的容器的 oom_score 值最高)。关于 OOM 的更多内容请参考:Kubernetes 内存资源限制实战

假设某节点运行着 4 个 Pod,且每个 Pod 中只有一个容器。每个 QoS 类型为 Burstable 的 Pod 配置的内存 requests 是 4Gi,节点的内存大小为 30Gi。每个 Pod 的 oom_score_adj 值如下所示:

Pod Name Pod QoS oom_score_adj
A Best Effort 1000
B Guaranteed -998
C Burstable 867(根据上面的公式计算)
D Best Effort 1000

当调用 OOM killer 时,它首先选择 oom_score_adj 值最高的容器(1000),这里有两个容器的 oom_score_adj 值都是 1000,OOM killer 最终会选择内存使用量最多的容器。

总结

  • 因为 kubelet 默认每 10 秒抓取一次 cAdvisor 的监控数据,所以可能在资源使用量低于阈值时,kubelet 仍然在驱逐 Pod。
  • kubelet 将 Pod 从节点上驱逐之后,Kubernetes 会将该 Pod 重新调度到另一个资源充足的节点上。但有时候 Scheduler 会将该 Pod 重新调度到与之前相同的节点上,比如设置了节点亲和性,或者该 Pod 以 Daemonset 的形式运行。

参考链接

https://www.yangcs.net/posts/kubernetes-eviction/

https://cloud.tencent.com/developer/article/1097431

原文地址:https://www.cnblogs.com/peitianwang/p/11588003.html

时间: 2024-08-29 00:52:39

十四. k8s资源需求和限制, 以及pod驱逐策略的相关文章

k8s之dashboard认证、资源需求、资源限制及HeapSter

1.部署dashboard kubernetes-dashboard运行时需要有sa账号提供权限 Dashboard官方地址:https://github.com/kubernetes/dashboard # 在node1上下载镜像 docker pull googlecontainer/kubernetes-dashboard-amd64:v1.10.1 docker tag googlecontainer/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.

容器资源需求、资源限制(二十二)

官网:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ 容器的资源需求,资源限制 Request:需求,最低保障: Limits:限制,硬限制 CPU: 1颗逻辑CPU 1=1000,millcores 500m=0.5CPU 内存: E.P.T.G.M.K.Ei.Pi Request保障容器CPU资源可用,limits限制资源 编写Demo测试, 查看CPU压缩使用情况 [

淘宝从几百到千万级并发的十四次架构演进之路!

1.概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. 2.基本概念 在介绍架构之前,为了避免部分读者对架构设计中的一些概念不了解,下面对几个最基础的概念进行介绍: 分布式系统中的多个模块在不同服务器上部署,即可称为分布式系统,如Tomcat和数据库分别部署在不同的服务器上,或两个相同功能的Tomcat分别部署在不同服务器上 高可用系统中部分节点失效时,

javaSE第十四天

第十四天????92 1. 正则表达式(理解)????92 (1)定义:????92 (2)常见规则????92 A:字符????92 B:字符类????93 C:预定义字符类????93 D:边界匹配器????93 E:Greedy 数量词????93 (3)常见功能:(分别用的是谁呢?)????93 (4)案例????94 A:判断电话号码和邮箱????94 B:按照不同的规则分割数据????95 C:把论坛中的数字替换为*????96 D:获取字符串中由3个字符组成的单词????96 2.

javaSE第二十四天

第二十四天????363 1:多线程(理解)????363 (1)JDK5以后的Lock锁????363 A:定义????363 B:方法:????364 C:具体应用(以售票程序为例)????364 1,. SellTicket类????364 2,. SellTicketDemo测试类????365 (2)死锁问题的描述和代码体现????365 1. DieLockDemo测试类????365 2. DieLock类(该类继承自Thread)????366 3. MyLock(锁对象类)??

Android基础之十四数据存储 之 SQLite数据库详解

Android基础之十四数据存储 之 SQLite数据库详解 SQLite 是一款 轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 K 的内存就足够了,因而特别适合在移动设备上使用. SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID( 原子性(Atomicity) .一致性(Consistency) . 隔离性(Isolation) . 持久性(Durability))事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手 SQLite.而

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十四:储存模块

实验十四比起动手笔者更加注重原理,因为实验十四要讨论的东西,不是其它而是低级建模II之一的模块类,即储存模块.接触顺序语言之际,“储存”不禁让人联想到变量或者数组,结果它们好比数据的暂存空间. 1. int main() 2. { 3. int VarA; 4. char VarB; 5. VarA = 20; 6. VarB = 5; 7. } 代码14.1 如代码14.1所示,主函数内一共声明两个变量VarA与VarB(第3~4行).VarA是两个字节的整型变量,VarB是一个字节的字符变量

2.k8s资源清单

一.常见资源对象 常见的资源对象:(包括但不仅限于) l  Workload: Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob l  服务发现及均衡:Service,Ingress…… l  配置与存储:Volume,CSI(扩展第三方存储的接口) ConfigMap,Secret DownwardAPI l  集群级资源:Namespace,Node,Role,ClusterRole,RoleBinding,Cluster