Kubernetes节点资源驱逐、调度策略与资源管控

Kubernetes节点资源驱逐、调度策略与资源管控

_

一、Kubernetes资源管理

1. 节点总硬件资源

capacity表示节点整机物理硬件的原始资源上限,是机器自身具备的全部硬件规格,没有做任何资源预留扣除。包含CPU、内存、临时存储、大页内存、最多Pod数量等硬件指标,反映服务器硬件出厂配置。

kubelet、操作系统、容器运行时等底层组件本身也要占用这部分硬件,Pod不能直接使用全部capacity资源。

capacity数据由节点上的kubelet组件负责采集并上报,kubelet启动时会同步内置cadvisor子模块。由其采集本机CPU、内存等硬件资源信息,kubelet再将采集到的整机硬件容量数据同步上报至apiserver。

[Step1] 执行命令查看指定节点完整资源描述信息,重点查看“capacity”部分。

root@k8s-master:~# kubectl get nodes k8s-worker1 -o yaml

2. 节点可调度资源

Kubernetes集群内各计算节点均具备CPU、内存等硬件资源,可通过清单文件查看节点资源的详情。

allocatable是从capacity总硬件中,扣除系统预留资源后,真正能够分配给业务Pod使用的资源额度。kubelet会预先预留一部分CPU、内存、临时存储供给节点系统组件,防止业务Pod抢占资源导致节点宕机。Kubernetes调度器调度Pod、计算资源配额时,全部以allocatable数值作为判断依据,而非capacity资源。

capacity表示机器硬件原始总资源,allocatable表示扣除kubelet、系统组件预留资源后,能够分配给业务Pod的资源。调度器调度Pod时以allocatable数值为准。

[Step1] 执行命令查看指定节点完整资源描述信息,重点查看“allocatable”部分。

root@k8s-master:~# kubectl get nodes k8s-worker1 -o yaml

3. 组件类型

Kubernetes集群各节点除业务容器外,还运行大量关键后台程序,这类程序并非容器化部署,主要分为两类:

  1. kubernetes daemon:Kubernetes守护进程,集群相关的后台服务,如kubelet、dockerd等。

  2. system daemon:系统守护进程,独立于k8s的系统服务,如sshd等。

为保障两类程序稳定运行,避免业务容器抢占资源造成节点故障,Kubernetes提供驱逐策略(eviction policy)机制。

4. 资源回收

节点资源不足时,kubelet会依据驱逐策略执行Pod回收操作。当集群不可压缩资源达到短缺阈值,便会触发驱逐行为,常见不可压缩资源包含:可用内存(memory.available)、可用宿主机磁盘(nodefs.available)、容器运行镜像存储空间(imagefs.available)等。

[Step1] 在Kubernetes中,设置的eviction默认阈值如下。

memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%
imagefs.available<15%

5. 资源驱逐机制

Kubernetes的节点资源驱逐Eviction包含Soft软驱逐和Hard硬驱逐两类机制:

  • 软驱逐(Soft Eviction):支持为资源阈值设置宽期限,用于规避瞬时资源峰值造成的误驱逐。当资源占用达到阈值后,kubelet会持续观测资源状态。若宽限期结束后资源压力仍未缓解,则启动Pod驱逐,同时允许Pod执行优雅退出逻辑。

  • 硬驱逐(Hard Eviction):不存在宽限期,属于兜底保护机制。资源指标一旦达到阈值,kubelet会马上强制销毁Pod,快速释放紧缺资源,避免节点因资源耗尽宕机。

当宿主机资源占用达到驱逐阈值时,节点会标记为“MemoryPressure”(内存压力)或“DiskPressure”(磁盘压力)状态。同时自动加上对应动态污点,阻止新Pod调度至该节点。触发驱逐时,kubelet会依据Pod的QoS服务质量等级确定删除顺序:

  1. 优先驱逐BestEffort Pod(尽力服务级);

  2. 其次驱逐Burstable(弹性服务级)中紧缺资源实际使用量超出requests申请额度的Pod;

  3. 最后才会驱逐Guaranteed Pod(保障服务级),该类Pod仅在资源使用超出limits限制时,才会被纳入驱逐候选。

同一QoS等级下,集群会按照Pod优先级判定驱逐先后,低优先级的Pod优先被回收。

二、Kubernetes调度

1. Kubernetes调度器

客户端提交Pod创建请求至API Server后,请求会交由调度组件kube-scheduler处理,由其筛选出集群内最优可用节点用于部署运行Pod。整个Pod调度流程分为3个核心阶段:

  • 节点预选(Predicates):依据预设筛选规则逐一校验集群所有节点,剔除资源、标签、亲和性等条件不匹配的节点,完成候选节点过滤。在具体的调度流程中,默认调度器首先会调用一组“Predicate”的算法,来检查各个Node。

  • 节点优选(Priorities):对预选后留存的合格节点进行综合优先级打分排序,量化判定各节点运行当前 Pod 的适配程度。调用一组“Priority”的调度算法,来给节点预选中的每个Node打分,最终得分最高的Node就是调度结果。当调度器对一个Pod调度成功,会在它的“spec.nodeName”字段填上调度结果的名字。

  • 节点选定(Select):选取优先级得分最高的节点作为Pod部署目标,若存在多个相同优先级最优节点,系统将随机从中on选定一个节点承载Pod。

2. Predicates常用策略

预选策略(Predicates)本质是节点过滤器。典型规则包含:节点标签需要与Pod的节点选择器匹配(由PodMatchNodeSelector规则实现)。Pod容器声明的资源请求量不得超过节点剩余可分配资源(PodFitsResources规则)。调度器将依次执行所有预选规则筛选节点,若预选后无符合条件的节点,Pod将持续处于Pending状态,直至出现满足条件的节点完成调度。

常用策略

说明

CheckNodeCondition

校验节点运行状态,如果节点磁盘异常、网络故障或节点未就绪,就不允许把Pod调度到该节点。

CheckNodeLabelPresence

校验节点标签,判断节点上是否存在用户指定的标签,需要校验哪些标签、标签是否允许存在,均由用户自行配置。

PodToleratesNodeTaints

污点容忍校验,如果Pod配置了容忍度“tolerations”,则判断该容忍度是否匹配并接纳节点设置的污点。

CheckServiceAffinity

Service亲和度调度,参考当前Service下已有Pod所在的节点,优先将相同Service的新Pod调度到相同或同类节点。

CheckServiceAffinity

Service亲和调度,参考同一服务下现有Pod运行的节点,优先把该服务新创建的Pod调度至相同或同类节点。

CheckVolumeBinding

检查节点上已绑定、待绑定的PVC资源,判断能否满足Pod的存储卷使用需求。

PodFitsResources

校验节点剩余CPU、内存资源,是否能够满足Pod配置的资源需求(requests)。

CheckNodeMemoryPressure

如果节点上报内存压力过高,判断是否允许将Pod调度到此节点。

CheckNodeDiskPressure

如果节点存在磁盘资源压力过高的情况,判断是否允许将将Pod调度到此节点。

MatchInterPodAffinity

校验节点是否满足Pod亲和性与反亲和性规则,以此实现Pod间亲和调度、隔离调度。

3. 打分阶段

调度器通过预选策略筛选出合格节点列表后,进入优选阶段(Priorities)。调度器会调用一系列优选函数,对每一个通过预选的节点进行评估,计算对应的优先级分数,分值区间为0~10。分数为0代表不适宜运行该Pod,分数为10代表该节点最适合承载当前Pod。

调度器支持为每一个优选函数配置权重,在计算节点最终优先级分值时,先将单个优选函数得出的分数乘以对应权重,再把所有优选函数的加权结果求和,得到节点综合得分。借助权重配置,管理员能够自主调整各类优选规则的影响程度,改变调度器的偏向性。

优选函数

中文译名

说明

LeastRequested

资源最少请求策略

计算结果数值越高,节点得分越高,该策略倾向于将Pod调度到资源剩余更多的节点。 计算公式:(CPU((capacity-sum(requested))10/capacity)+memory((capacity-sum(requested))10/capacity))

BalancedResourceAllocation

资源均衡分配策略

优先选择CPU、内存资源占用比例接近的节点,资源使用率越均衡,节点得分越高,避免出现某一项资源耗尽而另一项资源大量闲置的情况。

NodePreferAvoidPods

节点规避Pod策略

优先级极高,默认权重10000,满足10。根据节点注解信息(annotations)是否包含“scheduler.alpha.kubernetes.io/preferAvoidPods”,如果存在该注解,则尽量不在此节点调度Pod。

TaintToleration

污点容忍度策略

对比Pod的“tolerations”配置与节点污点“taints”,Pod容忍的污点越多、匹配程度越高,节点得分越低,调度器会尽量避开这类节点。

SelectorSpreading

标签选择器分散策略

统计运行着相同标签选择器Pod的节点,目标节点上同类Pod数据量越小,得分越高,实现同类Pod的分散部署。

InterPodAffinity

Pod亲和性优选策略

校验节点是否满足当前Pod的Pod亲和规则,满足条件越多,节点得分越高。

NodeAffinity

节点亲和优选策略

根据Pod内节点亲和配置匹配节点,匹配条件越多,节点得分越高。

MostRequested

最大资源占用策略

作为LeastRequestedPriority的替代策略,优先将Pod调度到资源利用率较高的节点,充分利用节点资源。 计算公式:(CPU((capacity-sum(requested))10/capacity)+memory((capacity-sum(requested))10/capacity))

NodeLabel

节点标签优选策略

检查节点是否存在指定标签,不校验标签具体取值。拥有的目标标签数量越多,得分越高。

ImageLocality

本地镜像优选策略

统计节点上已存在当前Pod所需镜像的总大小,已有镜像体积越大得分越高,减少镜像拉取开销。

三、资源配额

1. 单个Pod限额

Pod支持设置CPU、Memory两种资源限额。

1.1 CPU资源计量规则

  • 单位m代表毫核,1颗逻辑CPU核心等价于1000m。

  • 数值无单位时直接表示CPU核心数

  • 支持小数写法,如0.1代表0.1核

1.2 内存资源计量规则

  • 十进制标识M:换算基数为1000,例如100M=100x1000KB

  • 二进制标识Mi:换算基数为1024,例如100Mi=100x1024Ki

  • 数值无单位时,默认表示为字节

1.3 Kubernetes常见资源配额字段

资源名称

说明

limits.cpu

所有非终止状态的Pod,其CPU限额总量不能超过该值。

limits.memory

所有非终止状态的Pod,其内存限额总量不能超过该值。

requests.cpu

所有非终止状态的Pod,其CPU需求总量不能超过该值。

requests.memory

所有非终止状态的Pod,其内存需求量不能超过该值。

hugepages-<size>

所有非终止状态的Pod,针对指定尺寸的巨页请求总数不能超过此值。

cpu

与requests.cpu相同

memory

与requests.memory相同

2. 命名空间资源总量配额

通过为单个Pod配置“requests”和“limits”资源限制,能够有效规避因单容器程序逻辑Bug或瞬时流量峰值引发的资源激增问题,避免单个Pod耗尽节点硬件资源。但是单个Pod资源限制存在明显短板,该管控手段仅约束单个容器实例,若通过Deployment控制器调整副本数,批量创建大量Pod,多个Pod叠加占用的CPU与内存总和仍会耗尽整个节点乃至集群资源,无法实现全局资源管控。

为了解决多个Pod批量抢占资源的管控盲区,Kubernetes提供了“ResourceQuota”命名空间资源总量配额机制。该资源对象作用于独立命名空间,可统一统计并限制当前命名空间内所有非终止状态Pod的总资源使用量,从命名空间维度约束CPU、内存、巨页、Pod总数等各类资源的整体上限,实现租户/业务维度的资源隔离与总量管控。

ResourceQuota spec.hard常用可选字段如下表所示:

字段

说明

requests.cpu

命名空间所有Pod的CPU申请容量上限

requests.memory

命名空间所有Pod的内存申请容量上限

requests.storage

PVC总申请存储容量上限

limits.cpu

命名空间所有Pod的CPU限制容量上限

limits.memory

命名空间所有Pod的内存限制容量上限

pods

命名空间内允许的非终止Pod最大数量

persistentvolumeclaims

命名空间内PVC的最大创建个数

configmaps

ConfigMap最大数量

secrets

Secret最大数量

services

Service总数量上限

services.loadbalancers

LoadBalancer类型Service最大数量

services.nodeports

NodePort类型Service最大数量

replicationcontrollers

RC控制器最大数量

3. 资源限制区间

3.1 LimitRange核心定义

LimitRange作用于单个命名空间的资源管控对象,面向单个容器与Pod做粒度管控,能够统一约束命名空间内容器CPU、内存等资源的最小申请值、最大使用上限。同时限制资源上限与资源申请的比值,规范单个Pod资源的配置标准。弥补ResourceQuota仅能管控命名空间资源总用量,无法约束单实例资源大小的短板。从单容器维度避免出现资源配置过大过小甚至缺失资源配额的问题。

当同一命名空间下存在多条LimitRange规则且均匹配待创建Pod时,Kubernetes会按照管控类型(Container、Pod、PersistentVolumeClaim)分类校验,依次核对对应类型的资源约束条件,全部校验通过后Pod才可以正常创建。

3.2 LimitRange解决痛点

  • ResourceQuota仅限制命名空间资源总容量,无法约束单个容器资源大小;

  • 开发人员创建Pod时可能不写requests/limits,或是内存、CPU配置过大/过小,引发节点资源失衡;

  • LimitRange可强制规范单容器资源区间,缺失配置时自动填充默认值。

3.3 LimitRange核心能力

限制资源最小/最大值,规定单个容器CPU、内存的requests、limits取值范围:

  • min:容器资源申请不能低于该值

  • max:容器资源上限不能高于该值,如果Pod配置超出区间,创建直接报错拒绝。

设置默认资源配置,若创建Pod时间未填写requests/limits,LimitRange会自动给容器注入默认的requests、limits,确保所有Pod都具备资源配额,避免无限制抢占资源。

约束requests与limits比例,配置“maxLimitRequestRatio”限制requests和limits的比值,防止内存/CPU弹性区间过大。例如:内存比例为3,代表limits.memory÷requests.memory≤3。

3.4 管控资源对象类型

limits.type是LimitRange中用于指定当前资源限制规则要管控的资源对象类型,用于区分规则是约束容器、Pod整体还是PVC。

管控资源对象类型

说明

Container

规则作用于单个容器,只校验容器的CPU、内存 requests/limits

Pod

规则作用于整个Pod,统计Pod内所有容器资源总和做上下限校验

PersistentVolumeClaim

规则作用于存储PVC,仅限制单个PVC申请的存储容量大小

3.5 LimitRange与ResourceQuota核心区别

对象

管控维度

管控目标

作用场景

LimitRange

单容器 / 单 Pod

单个容器资源大小、默认值、比例

规范每个 Pod 的资源配置标准

ResourceQuota

整个命名空间

命名空间所有资源总用量

控制业务整体资源开销上限

四、资源配额案例配置

1. 单个Pod限额案例

[Step1] 本地新建YAML清单,定义Pod资源描述模板。

root@k8s-master:~# vim busybox-resources.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: busybox-resources
spec:
  containers:
    - name: busybox-resources
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","10000"]
      # 配置容器资源限额,包含requests和limits两类子项
      resources:
        requests:   # 资源申请配额,集群调度器分配节点资源的判断依据
          memory: "64Mi"    # 申请内存64Mi,调度器会预留64Mi内存供容器使用
          cpu: "100m"       # 申请CPU 100毫核(0.1核),调度时预留0.1核CPU资源
        limits:     # 资源使用硬上限,限制容器最大可用硬件资源,防止容器耗尽节点资源
          memory: "128Mi"   # 内存最大使用上限128Mi,容器内存占用超过该值会触发OOM被直接终止
          cpu: "100m"       # CPU最大使用上限100毫核,容器CPU占用超出上限会被系统节流降频,不会杀死容器

[Step2] 根据YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f busybox-resources.yml

[Step3] 验证:基于文件内定义的资源清单,查询集群中该资源的运行状态与基础信息。

root@k8s-master:~# kubectl get -f busybox-resources.yml

[Step4] 验证:查看busybox-resources的详细信息,可以看到Limits和Requests字段。

root@k8s-master:~# kubectl describe pod busybox-resources

2. 命名空间资源总量配置

[Step1] 创建一个namespace,名称为quota。

root@k8s-master:~# kubectl create namespace quota

[Step2] 本地新建YAML清单,定义ResourceQuota资源描述模板。

root@k8s-master:~# vim resource-quota.yml

# 写入下列内容
apiVersion: v1			# 固定配置
kind: ResourceQuota		# 资源类型
metadata:
  name: resource-quota
  namespace: quota
spec:
  hard:		# 硬件总量上限,达到该数值后,拒绝创建新资源
    pods: "1"			# 命名空间下最多允许1个非终止状态Pod运行
    requests.cpu: "1"	# 命名空间内所有Pod的CPU总申请上限为1核
    limits.cpu: "2"		# 命名空间内所有Pod的CPU总限额上限为2核
    limits.memory: "2Gi"	# 命名空间所有Pod的内存总限额上限为2Gi

[Step3] 根据YAML清单向Kubernetes集群声明式地创建ResourceQuota资源。

root@k8s-master:~# kubectl create -f resource-quota.yml

[Step4] 验证:查看quota命名空间下所有ResourceQuota资源配额使用情况。

root@k8s-master:~# kubectl get resourcequotas -n quota

[Step5] 本地新建YAML清单,定义Pod资源描述模板。

root@k8s-master:~# vim quota-pod.yml

# 写入下列内容
apiVersion: v1	# 固定配置
kind: Pod		# 资源类型
metadata:
  name: quota-pod
  namespace: quota
spec:
  containers:
    - name: quota-busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","10000"]
      # 配置容器资源限额,包含requests和limits两类子项
      resources:
        requests:	# 资源申请配额,集群调度器分配节点资源的判断依据
          memory: "64Mi"	# 申请内存64Mi,调度器会预留64Mi内存供容器使用
          cpu: "10"			# 申请CPU 10核
        limits:		# 资源使用硬上限,限制容器最大可用硬件资源,防止容器耗尽节点资源
          memory: "128Mi"	# 内存最大使用上限128Mi,容器内存占用超过该值会触发OOM被直接终止
          cpu: "10"			# CPU最大使用上限10核,容器CPU占用超出上限会被系统节流降频,不会杀死容器

[Step6] 根据YAML清单向Kubernetes集群声明式地创建Pod资源,此时可以看到报错信息,原因是超出命名空间ResourceQuota配额限制。

root@k8s-master:~# kubectl create -f quota-pod.yml

[Step7] 修改YAML文件,将“requests.cpu”和“limits.cpu”核心数调整为1。

root@k8s-master:~# vim quota-pod.yml

# 修改后文件内容如下
apiVersion: v1
kind: Pod
metadata:
  name: quota-pod
  namespace: quota
spec:
  containers:
    - name: quota-busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","10000"]
      resources:
        requests:
          memory: "64Mi"
          cpu: "1"
        limits:
          memory: "128Mi"
          cpu: "1"

[Step8] 根据YAML清单向Kubernetes集群声明式地创建Pod资源,此时能够正常创建。

root@k8s-master:~# kubectl create -f quota-pod.yml

[Step9] 验证:基于文件内定义的资源清单,查询集群中该资源的运行状态与基础信息。

root@k8s-master:~# kubectl get -f quota-pod.yml

[Step10] 验证:查看quota命名空间下所有ResourceQuota资源配额使用情况,可以看到上述创建Pod所占用的资源。

root@k8s-master:~# kubectl get resourcequotas -n quota

3. 资源限制区间配置

[Step1] 创建一个namespace,名称为limit。

root@k8s-master:~# kubectl create namespace limit

[Step2] 本地新建YAML清单,定义LimitRange资源描述模板。

root@k8s-master:~# vim limit-range.yml

# 写入下列内容
apiVersion: v1		# 固定配置
kind: LimitRange	# 资源类型
metadata:
  name: limit-range	
  namespace: limit
spec:
  limits:	# 定义资源范围约束规则列表
    - type: Container	# 约束对象类型:Container容器级约束
      max:	# 单个容器允许设置的资源上限最大值
        cpu: "2"		# 单个容器CPU最高只能设置2核
        memory: "1Gi"	# 单个容器内存最高只能设置1Gi
      min:	# 单个容器允许设置的资源上限最小值
        cpu: "200m"		# 单个容器CPU最低必须200毫核
        memory: "6Mi"	# 单个容器内存最低必须6Mi
      default:	# 容器未手动定义limits时,自动填充的资源上限默认值
        cpu: "500m"	
        memory: "128Mi"
      defaultRequest:	# 容器未手动定义requests时,自动填充的资源申请默认值
        cpu: "200m"
        memory: "64Mi"

[Step3] 根据YAML清单向Kubernetes集群声明式地创建LimitRange资源。

root@k8s-master:~# kubectl create -f limit-range.yml

[Step4] 验证:查看命名空间limit下的名为limit-range的LimitRange资源详细配置,可以看到资源上下限以及默认资源规则。

root@k8s-master:~# kubectl describe limitranges -n limit limit-range

[Step5] 本地新建YAML清单,定义Pod资源描述模板。

root@k8s-master:~# vim limit-range-pod.yml

# 写入下列内容
apiVerions: v1		# 固定配置
kind: Pod			# 资源类型
metadata:
  name: limit-range-pod
  namespace: limit
spec:
  - name: limit-range-pod
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["sleep","1000"]

[Step6] 根据YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f limit-range-pod.yml

[Step7] 验证:查看YAML文件中Pod资源的详细信息,筛选出包含Limit的行及其后续5行内容。因为在创建Pod时未手动定义request和limits,命名空间内的LimitRange规则会自动为容器填充预设的默认资源参数。

root@k8s-master:~# kubectl describe -f limit-range-pod.yml | grep Limits -A 5

Kubernetes ConfigMap与Secret配置管理 2026-10-27
Kubernetes Dashboard可视化管理面板 2026-10-29

评论区