Kubernetes——资源需求及资源限制
资源需求及资源限制
一、资源需求
目前来说,资源隔离尚且属于容器级别,CPU 和 内存 资源的配置需要在 Pod 中的容器上进行,每种资源均可由 "requests" 属性定义其请求的确保可用值,即容器运行可能用不到这些额度的资源,但用到时必须要确保有如此多的资源可用,而 "limits" 属性则用于限制资源可用的最大值,即硬限制。
一个简单的资源需求示例:
- name: JAVA_OPTS
value: >-
-Xms1536M -Xmx1536M -Xmn512M -Xss300K -XX:MaxMetaspaceSize=256M
-XX:MetaspaceSize=256M -XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70 -XX:+UseFastAccessorMethods
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
-Duser.timezone=GMT+08
- name: OTHER_OPTS
value: >-
-javaagent:/sidecar/jmx_exporter/jmx_prometheus_javaagent.jar=6060:/sidecar/jmx_exporter_config/sample-config.yml
resources:
limits:
cpu: '2'
memory: 2Gi
requests:
cpu: '0'
memory: 2Gi
二、资源限制
容器资源需求仅能达到为其保证可用的最少资源量的目的,它并不会限制容器的可用资源上限,因此对因应用程序自身存在 Bug 等多种原因而导致的系统资源被长时间占用的情况则无计可施,这就需要通过 limits 属性为容器定义资源的最大可用量。申请分配超过 limits 属性定义的硬限制的内存资源时,它将会被 OOM killer 杀死,不过,随后可能会被其控制器进程所重启,例如,容器进程的 Pod 对象会被杀死并重启(重启策略为 Always 或 OnFailure 时),或者是容器进程的子进程被其父进程所重启。
Kubernetes 系统上运行的关键型业务相关的 Pod 时必须使用 requests 属性为容器定义资源的确保可用量。Kubernetes 的调度器会根据容器的 requests 属性中定义的资源需求量来判定仅哪些节点可接收运行相关的 Pod 资源,而对一个节点的资源来说,每运行一个 Pod 对象,其 request 中定义的请求量都要被预留,直到被所有 Pod 对象瓜分完毕为止。与 requests 不同的是,limits 并不会影响 Pod 的调度结果,也就是说,一个节点上的所有 Pod 对象的 limits 数量之和可以大于节点所拥有的资源量,即支持资源过载使用(overcommitted)。
另外需要说明的是,Kubernetes 仅会确保 Pod 能够获得它们请求(requests)的 CPU 时间额度,它们能否获得额外(throttled)的 CPU 时间,则取决于其他正在使用的作业对 CPU 资源的占用情况。例如:对于总数为 1000m 的 CPU 资源来说,容器A 请求使用 200m,容器B 请求使用 500m,在不超过它们各自的最大限额的前提下,余下的 300m 在双方都需要时会以 2:5(200m:500m)的方式进行配置。
三、Pod 的服务质量类别
前面曾提到过,Kubernetes 允许节点资源对 limits 的过载使用,这意味着节点无法同时满足其上的所有 Pod 对象以资源满载的方式运行。于是,在内存资源紧缺时,应该以何种次序先后终止哪些 Pod 对象? Kubernetes 无法自行对此作出决策,它需要借助于 Pod 对象的优先级完成判定。根据 Pod 对象的 requests 和 limits 属性,Kubernetes 将 Pod 对象归类到 BestEffort、Burstable 和 Guaranteed 三个服务质量(Quality of Service,QoS)类别下,具体说明如下:
- Guaranteed:每个容器都为 CPU 资源设置了具有相同值的 requests 和 limits 属性,以及每个容器都为内存资源设置了具有相同值的 requests 和 limits 属性的 Pod 资源会自动归属于此类别,这类 Pod 资源具有最高优先级。
- Burstable:至少有一个容器设置了 CPU 或 内存 资源的 requests 属性,但不满足 Guaranteed 类别要求的 Pod 资源将自动归属于此类别,它们具有中等优先级。
- BestEffort:未为任何一个容器设置 requests 或 limits 属性的 Pod 资源将自动归属于此类别,它们的优先级最最低级别。
内存资源紧缺时,BestEffort 类别的容器将首当其冲地被终止,因为系统不为其提供任何级别的资源保证,但换来的好处是,它们能够在可用时做到尽可能多地占用资源。如果不存在 BestEffort 类别的容器,则接下来是有着中等优先级的 Burstable 类别的 Pod 被终止。Guaranteed 类别的容器拥有最高优先级,它们不会被杀死,除非其内存资源需求超限,或者 OOM 时没有其他更低优先级的 Pod 资源存在。