做为 Kubernetes 的资源管理与调度部分的基础,须要从它的资源模型提及.mysql
资源管理模型的设计 |
咱们知道,在 Kubernetes 里面, Pod 是最小的原子调度单位,这就意味着,全部和调度和资源管理有关的属性,应该都是属于 Pod 对象的字段,而在这些字段中,最重要的部分就是 Pod 的 CPU 和内存配置.
在 Kubernetes 中,像 CPU 这样的资源被称做"可压缩资源"( compressible resources ).它典型特色是,当可压缩资源不足时, Pod 只会"饥饿",可是不会退出.
可是内存这样的资源,被称做"不可压缩资源"( incompressible resources ).当不可压缩资源不足时, Pod 就会由于 OOM( Out-Of-Memory )被内核杀掉.
还记得吗, Pod 能够由多个 Container 组成,因此 CPU 和内存资源的限额,是要配置在每一个 Container 的定义上的.这样, Pod 总体的资源配置,就由这些 Container 的配置值累加获得.web
来个例子:sql
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 两种状况,以下所示:api
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 资源管理模型的设计.frontend
QoS模型 |
在上面说到, Kubernetes 会有不一样的 requests 和 limits 的设置方式, Kubernetes 接下来会将这个 Pod 划分到不一样的 QoS 级别当中.因此,接下来我们来讲说, Kubernetes 中的 QoS 模型.svg
若是 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 .wordpress
为何 Kubernetes 要为 Pod 设置这三种 QoS 类别呢?这样设置有什么做用呢?
那么咱们就要知道, QoS 划分的主要应用场景:当宿主机资源紧张的时候, kubelet 对 Pod 进行 Eviction (即资源回收)时须要用到的.
也就是说,当 Kubernetes 所管理的宿主机上不可压缩资源短缺时,就有可能触发 Eviction .好比,可用内存,可用的宿主机磁盘空间等资源短缺时,就会触发 Eviction .
那么当 Eviction 发生的时候, kubelet 就会开始挑选 Pod 进行删除操做,来释放不可压缩资源,这个时候,就须要参考这些 Pod 的 QoS 类别了.学习
因此呢,在实际的使用过程当中,建议将 DaemonSet 的 Pod 都设置为 Guaranteed 的 QoS 类型.不然,一旦 DaemonSet 的 Pod 被回收,它又会当即在原宿主机上被重建出来,这就使得资源回收变得没有意义了.设计
要分享的内容,到这里就差很少了.
以上内容来自我学习<深刻剖析Kubernetes>专栏文章以后的一些看法,有偏颇之处,还望指出.
感谢您的阅读~code