作为 Kubernetes 的资源管理与调度部分的基础,需要从它的资源模型说起.

资源管理模型的设计

我们知道,在 Kubernetes 里面, Pod 是最小的原子调度单位,这就意味着,所有和调度和资源管理有关的属性,应该都是属于 Pod 对象的字段,而在这些字段中,最重要的部分就是 Pod 的 CPU 和内存配置.

在 Kubernetes 中,像 CPU 这样的资源被称作"可压缩资源"( compressible resources ).它典型特点是,当可压缩资源不足时, Pod 只会"饥饿",但是不会退出.

但是内存这样的资源,被称作"不可压缩资源"( incompressible resources ).当不可压缩资源不足时, Pod 就会因为 OOM( Out-Of-Memory )被内核杀掉.

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

来个例子:

apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

在上面,我们能够看到, cpu limits 的值是 500m ( 500m 指的就是 500 millicpu ,也就是 0.5 个 cpu 的意思),所以这个 Pod 会被分配到 1 个 CPU 一半的计算能力.

对于内存资源来说,它的单位是 bytes . Kubernetes 支持使用 Ei , Pi , Ti , Gi , Mi , Ki (或者 E , P , T , G , M , K )的方式来作为 bytes 的值.在上面的例子中,我们能够看到, Memory requests 的值就是 64MiB ( 2 的 26 次方 bytes ).所以, Kubernetes 中的 Pod 中 CPU 和内存资源,实际上还要分为 limits 和 requests 两种情况,如下所示:

spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory

limits 和 requests 的区别其实很简单:在调度的时候, kube-scheduler 只会按照 requests 的值进行计算,但在真正设置 Cgroups 限制的时候, kubelet 则会按照 limits 的值来进行设置.

说的再确切一点儿就是:当指定 requests.cpu=250m 之后,相当于将 Cgroups 的 cpu.shares 的值设置为 ( 250/1000)×1024 .如果没有设置 reques.cpu 的时候,默认是 1024 .如果指定了 limits.cpu=500m ,就相当于将 Cgroups 的 cpu.cfs_quota_us 的值设置为 (500/1000)×100ms , cpu.cfs_period_us 的值始终是 100ms .这个时候, Kubernetes 就设置了这个容器只能用到 CPU 的 50& .

对于内存来说,当指定了 limits.memory=128Mi 之后,相当于将 Cgroups 的 memory.limit_in_bytes 设置为 128×1024×1024 .但是在调度的时候,调度器只会使用 requests.memory=64Mi 来进行判断.

以上就是 Kubernetes 资源管理模型的设计.

QoS模型

在上面说到, Kubernetes 会有不同的 requests 和 limits 的设置方式, Kubernetes 接下来会将这个 Pod 划分到不同的 QoS 级别当中.所以,接下来咱们来说说, Kubernetes 中的 QoS 模型.

如果 Pod 中的每一个 Container 都同时设置了 requests 和 limits ,并且 requests 和 limits 值相等的时候,这个 Pod 就属于 Guaranteed 类别.如果 Pod 只是设置了 limits 的值,而没有设置 requests 的值, Kubernetes 会自动为它设置和 limits 相同的 requests 的值,此时这也属于 Guaranteed 情况.

如果 Pod 不满足以上的情况,但是至少有一个 Container 设置了 requests ,那么这个 Pod 就会被划分为 Burstable 类别.

如果一个 Pod 既没有设置 requests ,也没有设置 limits ,那么它的 QoS 类型就是 BestEffort .

为什么 Kubernetes 要为 Pod 设置这三种 QoS 类别呢?这样设置有什么作用呢?

那么我们就要知道, QoS 划分的主要应用场景:当宿主机资源紧张的时候, kubelet 对 Pod 进行 Eviction (即资源回收)时需要用到的.

也就是说,当 Kubernetes 所管理的宿主机上不可压缩资源短缺时,就有可能触发 Eviction .比如,可用内存,可用的宿主机磁盘空间等资源短缺时,就会触发 Eviction .

那么当 Eviction 发生的时候, kubelet 就会开始挑选 Pod 进行删除操作,来释放不可压缩资源,这个时候,就需要参考这些 Pod 的 QoS 类别了.

  • 要进行删除的时候
    • 首先考虑删掉的,肯定是 BestEffort 类别的 Pod
    • 如果不可压缩资源还是短缺,则会删除 Burstable 类别,而且发生"饥饿"的资源使用量已经超出 requests 的 Pod
    • 如果资源还是短缺,会考虑 Guaranteed 类别.并且, Kubernetes 会保证只有当 Guaranteed 类别的 Pod 的资源使用量超过了 limits 的限制,或者宿主机本身正处于 Memory Pressure 状态时, Guaranteed 的 Pod 才可能被选中进行 Eviction 操作.
  • 所以呢,在实际的使用过程中,建议将 DaemonSet 的 Pod 都设置为 Guaranteed 的 QoS 类型.否则,一旦 DaemonSet 的 Pod 被回收,它又会立即在原宿主机上被重建出来,这就使得资源回收变得没有意义了.

    要分享的内容,到这里就差不多了.

    以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.

    感谢您的阅读~

    [Kubernetes]资源模型与资源管理的更多相关文章

    1. Kubernetes资源与对象简述

      资料 k8s基本对象概念 背景 资源和对象   Kubernetes 中的所有内容都被抽象为"资源",如 Pod.Service.Node 等都是资源."对象" ...

    2. kubernetes系列06—kubernetes资源清单定义入门

      本文收录在容器技术学习系列文章总目录 1.认识kubernetes资源 1.1 常用资源/对象 workload工作负载型资源:pod,ReplicaSet,Deployment,StatefulSe ...

    3. 使用kubesql进行kubernetes资源查询

      kubesql kubesql(https://github.com/xuxinkun/kubesql)是我最近开发的一个使用sql查询kubernetes资源的工具.诸如node,pod等kuber ...

    4. 新手学习FFmpeg - 如何编写Kubernetes资源文件

      Kubernetes API的使用方式 Kubernetes API属于声明式API编程, 它和常用的命令式编程有一些区别. 通俗的说,命令式编程是第一人称,我要做什么,我要怎么做. 操作系统最喜欢这 ...

    5. 深入理解 Kubernetes 资源限制:CPU

      原文地址:https://www.yangcs.net/posts/understanding-resource-limits-in-kubernetes-cpu-time/ 在关于 Kubernet ...

    6. kubefuse 让Kubernetes 资源成为fuse 文件系统

      kubefuse 是基于fuse 开发的文件系统,我们可以像访问文件系统一样访问Kubernetes 资源,使用python开发 支持以下特性: 可以使用方便的linux tools: ls. vim ...

    7. 我非要捅穿这 Neutron(二)上层资源模型篇

      目录 文章目录 目录 Neutron 的资源模型 Network 运营商网络和租户网络 创建运营商网络 创建租户网络 创建外部网络 Network 小结 Subnet IP 核心网络服务 Subnet ...

    8. 深入理解Kubernetes资源限制:CPU

      写在前面 在上一篇关于Kubernetes资源限制的文章我们讨论了如何通过ResourceRequirements设置Pod中容器内存限制,以及容器运行时是如何利用Linux Cgroups实现这些限 ...

    9. Dubbo(五):Dubbo中的URL统一资源模型与Dubbo协议

      一.URL简介 URL也就是Uniform Resource Locator,中文叫统一资源定位符.Dubbo中无论是服务消费方,或者服务提供方,或者注册中心.都是通过URL进行定位资源的.所以今天来 ...

    随机推荐

    1. jeecg入门操作—表单界面

      一.搭建jeecg开发环境 参考环境搭建步骤 https://www.cnblogs.com/dyh004/p/10687633.html 二.创建用户数据库表: 登录上jeecg平台,点击在线开发- ...

    2. EasyUI的Datagrid鼠标悬停显示单元格内容

      功能描述:table鼠标悬停显示单元格内容 1.js函数 function hoveringShow(value) { return "<span title='" + va ...

    3. 通过java代码执行Linux命令查询声卡和显卡 型号

      package test; import java.io.BufferedReader; import java.io.InputStreamReader; public class ExcuteLi ...

    4. python定时执行任务的三种方式

      #!/user/bin/env python # @Time :2018/6/7 16:31 # @Author :PGIDYSQ #@File :PerformTaskTimer.py #定时执行任 ...

    5. Django Models 查询操作

      1.准备数据表: from django.db import models class City(models.Model): name=models.CharField(max_length=32) ...

    6. Java的properties文件读取和属性修改

      package Test; import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileO ...

    7. IIS7下设置https主机名灰色无法修改

      打开iis绑定域名时,点击绑定弹出绑定框,在选择类型为“https”的时候,主机名为灰色的无法填写 解决方法: 1. 选择https,在选择相应的SSL证书,点击确定 2. 打开C:\Windows\ ...

    8. sax

      <?xml version="1.0" encoding="UTF-8"?> <beauties> <beauty> < ...

    9. 原型设计的工具-----Axure RP

       原型设计的工具-----Axure RP 1.原型设计的工具 目前能用于原型设计的工具有很多,其中有七种比较好. (1)    Axure RP (2)    Mockplus (3)    Jus ...

    10. Codeforces 1092C Prefixes and Suffixes(思维)

      题目链接:Prefixes and Suffixes 题意:给定未知字符串长度n,给出2n-2个字符串,其中n-1个为未知字符串的前缀(n-1个字符串长度从1到n-1),另外n-1个为未知字符串的后缀 ...