当前位置: 首页 > news >正文

K8S(八)—— Kubernetes 集群调度全面解析:从组件协作到实战(含亲和性、污点容忍与故障排查)

文章目录

  • 前言
  • 一、Kubernetes集群调度基础
    • 1.1 Kubernetes组件协作机制
      • 1.1.1 关键组件及职责
      • 1.1.2 组件协作流程简述
    • 1.2 Pod创建与工作机制流程
      • 1.2.1 初始化监听(List-Watch启动)
      • 1.2.2 用户发起创建Pod对象请求
      • 1.2.3 etcd数据存储与事件触发
      • 1.2.4 副本控制与调度
      • 1.2.5 容器运行与状态维护
  • 二、Scheduler工作原理
    • 2.1 调度器核心任务与目标
      • 2.1.1 核心任务
      • 2.1.2 调度目标
    • 2.2 调度流程详解
      • 2.2.1 过滤阶段(Predicate)
      • 2.2.2 优选阶段(Priorities)
  • 三、指定调度节点的常用方式
    • 3.1 nodeName:强制绑定节点
      • 3.1.1 配置示例
      • 3.1.2 特点
    • 3.2 nodeSelector:基于标签匹配
      • 3.2.1 操作流程
      • 3.2.2 标签管理命令
  • 四、亲和性与反亲和性调度
    • 4.1 节点亲和性(NodeAffinity)
      • 4.1.1 配置结构
      • 4.1.2 支持的操作符
      • 4.1.3 实践案例
        • 案例1:硬策略(必须排除node02)
        • 案例2:软策略
        • 案例3:软硬策略
    • 4.2 Pod亲和性与反亲和性
      • 4.2.1 核心区别
      • 4.2.2 实践案例
        • 案例1:Pod亲和性(与myapp01同拓扑域)
        • 案例2:Pod反亲和性(与myapp01不同节点)
  • 五、污点(Taint)与容忍(Toleration)
    • 5.1 污点(Taint)
      • 5.1.1 污点格式与作用
      • 5.1.2 污点管理命令
    • 5.2 容忍(Toleration)
      • 5.2.1 配置示例
      • 5.2.2 特殊配置
      • 5.2.3 污点在Node节点更新组件时的作用
  • 六、节点维护与Pod生命周期
    • 6.1 节点维护操作
    • 6.2 Pod生命周期阶段(Phase)
  • 七、故障排查常用命令
  • 总结

前言

在Kubernetes(简称K8s)集群中,调度是实现资源高效利用与业务稳定运行的核心环节。它负责将Pod合理分配到集群节点上,既要满足业务的资源需求,又要保证集群整体的负载均衡。

本文将从K8s组件协作机制出发,详细解析Pod的创建流程、调度器的工作原理,以及节点选择、亲和性调度、污点与容忍等关键技术,并结合实践案例说明节点维护与故障排查方法,帮助读者全面掌握K8s集群调度的核心知识。

一、Kubernetes集群调度基础

1.1 Kubernetes组件协作机制

Kubernetes各组件通过List-Watch机制实现协同工作与数据同步,这种机制确保了组件间的解耦与集群状态的实时一致性。

1.1.1 关键组件及职责

组件职责描述
kubectl / API客户端向APIServer发起资源创建、查询、更新等管理请求
APIServer集群控制的核心入口,负责API调用处理、权限校验、与etcd交互
etcd分布式键值存储,保存集群所有状态信息(如Pod、Node、配置等)
Controller Manager运行各类控制器(如ReplicaSet、Deployment),维持资源期望状态(如副本数、自愈逻辑)
Scheduler调度器,为未分配节点的Pod选择最合适的Node节点
kubelet节点代理程序,负责本节点上Pod的生命周期管理(创建、启停、状态上报)

1.1.2 组件协作流程简述

  • 用户通过kubectl或其他客户端向APIServer发送请求(如创建Pod)后,APIServer会完成权限校验并将数据存入etcd。
  • etcd存储数据时会触发事件(如Create事件),并同步给APIServer;
  • 其他组件(Controller Manager、Scheduler、kubelet)通过监听APIServer的事件变化,触发各自的业务逻辑(如Controller Manager维持副本数、Scheduler调度Pod、kubelet运行容器),最终完成整个资源的部署与管理。

1.2 Pod创建与工作机制流程

Pod的完整生命周期需多个组件协同完成,其核心依托于List-Watch模型实现动态响应。以下是Pod创建的典型流程:

1.2.1 初始化监听(List-Watch启动)

Controller Manager、Scheduler、kubelet 启动后会分别通过 Watch API Server(HTTPS 6443 端口)监听集群资源事件变化。

  • Controller Manager:监听副本控制类对象(如ReplicaSet、Deployment),确保资源符合期望状态;
  • Scheduler:监听未被调度的Pod(spec.nodeName为空),准备为其分配节点;
  • kubelet:监听分配到本节点的Pod,负责后续容器的创建与管理。

1.2.2 用户发起创建Pod对象请求

用户通过kubectl apply -f pod.yaml等命令,向APIServer发送创建Pod的请求。配置文件pod.yaml可能包含Pod的元数据、容器镜像、资源需求等信息。

1.2.3 etcd数据存储与事件触发

  1. APIServer校验请求合法性后,将Pod元数据写入etcd;
  2. etcd写入成功后,向APIServer返回确认,并触发Create事件
  3. APIServer将事件广播给所有监听的组件。

1.2.4 副本控制与调度

  1. Controller Manager响应:若Pod关联ReplicaSet/Deployment,Controller Manager会检查当前副本数是否符合期望,不足则创建新副本;
  2. APIServer更新数据:Controller Manager 创建完 Pod 副本后,API Server 会将 Pod 的详细信息更新写入 etcd,触发更新事件
  3. Scheduler调度:监听至未调度的Pod(Pending状态),通过调度算法选择合适节点,并将节点信息写入APIServer;
  4. 数据同步:APIServer更新etcd中Pod的节点绑定信息,完成调度确认。

1.2.5 容器运行与状态维护

  1. 目标节点的kubelet监听到新分配的Pod,调用容器运行时(如Docker、containerd)拉取镜像、创建并启动容器;
  2. kubelet将Pod状态(如Running、Failed)上报给APIServer;
  3. APIServer更新etcd中Pod的状态信息,etcd 确认写入成功后,集群状态同步完成,Pod进入稳定运行(running)阶段。

说明:kubelet会持续监听Pod事件,以应对副本数调整、镜像更新等动态变化,确保容器状态与期望一致。

二、Scheduler工作原理

2.1 调度器核心任务与目标

2.1.1 核心任务

Scheduler的核心职责是为未绑定节点的Podspec.nodeName == "")分配合适的Node节点,通过创建binding对象记录调度结果。

2.1.2 调度目标

  • 公平性:确保节点间资源分配均衡,避免个别节点负载过高;
  • 高效性:最大化集群资源利用率,减少资源浪费;
  • 效率:快速完成大批量Pod的调度,降低调度延迟;
  • 灵活性:支持自定义调度策略与插件,适配复杂业务场景。

2.2 调度流程详解

调度过程分为过滤(Predicate)优选(Priorities) 两个阶段,最终选择最优节点绑定Pod。

2.2.1 过滤阶段(Predicate)

过滤阶段通过一系列算法排除不满足Pod需求的节点,确保剩余节点均为“可行节点”。常见过滤算法如下:

算法名功能描述
PodFitsResources检查节点剩余CPU、内存等资源是否满足Pod需求
PodFitsHost检查Pod指定的nodeName是否匹配当前节点
PodFitsHostPorts检查Pod所需端口是否与节点已使用端口冲突
PodSelectorMatches检查节点标签是否匹配Pod的标签选择器
NoDiskConflict检查Pod挂载的Volume是否与节点已有挂载冲突

注意

  • 若过滤后无可行节点,Pod将保持Pending状态,调度器会不断重试直至有节点满足条件。
  • 如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。

2.2.2 优选阶段(Priorities)

优选阶段对过滤后的可行节点进行打分排序,选择得分最高的节点作为目标。常见优选算法如下:

优先级项描述
LeastRequestedPriority节点资源使用率越低,得分越高(优先分配资源充足的节点)
BalancedResourceAllocation优先选择CPU与内存使用率更均衡的节点(如20%CPU+30%内存优于10%CPU+50%内存)
ImageLocalityPriority优先选择已缓存Pod所需镜像的节点(减少镜像拉取时间)

最终,调度器将得分最高的节点作为Pod的绑定目标,并更新APIServer中的Pod信息。

三、指定调度节点的常用方式

3.1 nodeName:强制绑定节点

pod.spec.nodeName直接将Pod调度到指定节点,跳过Scheduler的调度逻辑,属于强制绑定。

3.1.1 配置示例

vim myapp.yamlapiVersion: apps/v1
kind: Deployment
metadata:name: myapp
spec:replicas: 3selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:nodeName: node01  # 强制调度到node01containers:- name: myappimage: soscscs/myapp:v1ports:- containerPort: 80
# 执行YAML文件创建Deployment
kubectl apply -f myapp.yaml# 查看pod详细信息,全部调度到了node01
kubectl get pods -o wide

在这里插入图片描述

# 查看详细事件(发现未经过 scheduler 调度分配)
kubectl describe po myapp-699655c7fd-c7shz

在这里插入图片描述

3.1.2 特点

  • 直接由kubelet负责创建容器,无需Scheduler参与;
  • 若指定节点不存在或不可用,Pod会一直处于Pending状态。

3.2 nodeSelector:基于标签匹配

pod.spec.nodeSelector通过标签选择器 label-selector 匹配节点,由Scheduler根据标签策略调度匹配 label,然后调度 Pod 到目标节点,属于强制约束。

3.2.1 操作流程

1、需要获取 node 上的 NAME 名称

kubectl get node

在这里插入图片描述

2、 为节点添加标签:

# 给对应的 node 设置标签分别为 yjs=a 和 yjs=b
kubectl label nodes node01 yjs=a
kubectl label nodes node02 yjs=b
# 查看标签
kubectl get nodes --show-labels

在这里插入图片描述

3、 配置Pod的nodeSelector:

vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp1
spec:replicas: 3selector:matchLabels:app: myapp1template:metadata:labels:app: myapp1spec:nodeSelector:yjs: acontainers:- name: myapp1image: soscscs/myapp:v1ports:- containerPort: 80kubectl apply -f myapp1.yaml 

4、验证结果:

kubectl get pods -o wide  # 所有Pod均运行在node01# 查看详细事件(通过事件可以发现要先经过 scheduler 调度分配)
kubectl describe po myapp1-64c58784f9-4mgc6

在这里插入图片描述

在这里插入图片描述

3.2.2 标签管理命令

  • 查看节点标签:kubectl get nodes --show-labels
  • 筛选指定标签的节点:kubectl get nodes -l yjs=a
  • 修改标签(需加--overwrite):kubectl label nodes node01 yjs=b --overwrite
  • 删除标签:kubectl label nodes node01 yjs-
kubectl label nodes node01 yjs=a
kubectl get nodes --show-labels#指定标签查询 node 节点
kubectl get node -l yjs=a  ##修改一个 label 的值,需要加上 --overwrite 参数
kubectl label nodes node02 yjs=b --overwrite###删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可:
kubectl label nodes node01 yjs-

在这里插入图片描述

四、亲和性与反亲和性调度

亲和性调度用于更灵活地控制Pod与节点、Pod与Pod之间的调度关系,分为节点亲和性Pod亲和性Pod反亲和性

4.1 节点亲和性(NodeAffinity)

节点亲和性定义Pod对节点的“偏好”或“硬性要求”,类似“想去哪个班”(软策略)或“必须去哪个班”(硬策略)。

4.1.1 配置结构

affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略(必须满足)nodeSelectorTerms:- matchExpressions:  # 匹配规则- key: <节点标签键>operator: <操作符>values: [<值列表>]preferredDuringSchedulingIgnoredDuringExecution: # 软策略(优先满足)- weight: <权重,0-100>  # 多个软策略时,权重越高优先级越高preference:matchExpressions:- key: <节点标签键>operator: <操作符>values: [<值列表>]

4.1.2 支持的操作符

操作符含义示例
In标签值在列表中env In (dev, test)
NotIn标签值不在列表中env NotIn (prod)
Gt标签值大于指定数值version Gt 3
Lt标签值小于指定数值version Lt 3
Exists标签存在(忽略值)Exists zone
DoesNotExist标签不存在DoesNotExist debug

4.1.3 实践案例

案例1:硬策略(必须排除node02)
# requiredDuringSchedulingIgnoredDuringExecution:硬策略
mkdir /opt/affinity
cd /opt/affinity
vim pod1.yamlapiVersion: v1
kind: Pod
metadata:name: affinitylabels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostname    #指定node的标签operator: NotIn #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上values:- node02
# 创建 Pod
kubectl apply -f pod1.yaml# 查看 Pod 调度节点(确认不在 node02 上)
kubectl get pods -o wide

在这里插入图片描述

# 重新部署并验证(可选
kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide

在这里插入图片描述

如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态。

案例2:软策略
# preferredDuringSchedulingIgnoredDuringExecution:软策略
vim pod2.yamlapiVersion: v1
kind: Pod
metadata:name: affinity01labels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 5   #如果有多个软策略选项的话,权重越大,优先级越高preference:matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node01- weight: 10   #如果有多个软策略选项的话,权重越大,优先级越高preference:matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node02
kubectl apply -f pod2.yaml
# 查看Pod状态及调度节点(-o wide显示详细信息,包括运行节点)
# 若node02优先级高,Pod会优先调度到node02
kubectl get pods -o wide

在这里插入图片描述

案例3:软硬策略

如果把硬策略和软策略合在一起使用,则要先满足硬策略之后才会满足软策略。

vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: affinity03labels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:   #先满足硬策略,排除有kubernetes.io/hostname=node02标签的节点nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: NotInvalues:- node02preferredDuringSchedulingIgnoredDuringExecution:  #再满足软策略,优先选择有yjsc=a标签的节点- weight: 1preference:matchExpressions:- key: yjsoperator: Invalues:- a
kubectl apply -f pod3.yaml
# 先满足硬策略不在Node02上,在满足软策略yjs=a的节点上
kubectl get po -owide

在这里插入图片描述

4.2 Pod亲和性与反亲和性

Pod亲和性/反亲和性基于已有Pod的标签控制调度,用于实现“Pod与目标Pod同节点/同拓扑域”或“Pod与目标Pod分离”的需求。

4.2.1 核心区别

调度策略匹配对象核心作用拓扑域支持
nodeAffinity主机根据节点标签(如主机名、硬件配置、环境标识),控制 Pod 调度到指定节点(硬 / 软策略)不支持
podAffinity其他Pod使当前Pod与目标Pod在同一拓扑域支持
podAntiAffinity其他Pod使当前Pod与目标Pod在不同拓扑域支持

拓扑域:通过topologyKey指定节点标签,标签值相同的节点属于同一拓扑域(如同一机房、同一机架)。

4.2.2 实践案例

案例1:Pod亲和性(与myapp01同拓扑域)
kubectl label nodes node01 yjs=a      
kubectl label nodes node02 yjs=b    
# 先创建一个带标签app=myapp01的Pod(例如它运行在node02,node02标签yjs=b)
vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1kubectl apply -f pod4.yamlkubectl get pods --show-labels -o wide

在这里插入图片描述

# 新Pod通过亲和性调度到与myapp01同拓扑域的节点(yjs=a)
vim pod5.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp02labels:app: myapp02
spec:containers:- name: myapp02image: soscscs/myapp:v1affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01    # 匹配标签app=myapp01的PodtopologyKey: yjs # 拓扑域为标签yjs,值相同的节点为同一域
#仅当节点和至少一个已运行且有键为“app”且值为“myapp01”的标签 的 Pod 处于同一拓扑域时,才可以将该 Pod 调度到节点上。 (更确切的说,如果节点 N 具有带有键 yjs 和某个值 V 的标签,则 Pod 有资格在节点 N 上运行,以便集群中至少有一个具有键 yjs 和值为 V 的节点正在运行具有键“app”和值 “myapp01”的标签的 pod。)
#topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑域中。 调度器试图在每个拓扑域中放置数量均衡的 Pod。
#如果 yjs 对应的值不一样就是不同的拓扑域。比如 Pod1 在 yjs=a 的 Node 上,Pod2 在 yjs=b 的 Node 上,Pod3 在 yjs=a 的 Node 上,则 Pod2 和 Pod1、Pod3 不在同一个拓扑域,而Pod1 和 Pod3在同一个拓扑域。
kubectl apply -f pod5.yamlkubectl get pods --show-labels -o wide

最终myapp02会被调度到node02(与myapp01同属yjs=a域)。
在这里插入图片描述

案例2:Pod反亲和性(与myapp01不同节点)
# 示例一
vim pod6.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp10labels:app: myapp10
spec:containers:- name: myapp10image: soscscs/myapp:v1affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01    # 匹配标签app=myapp01的PodtopologyKey: kubernetes.io/hostname  # 拓扑域为节点主机名(即单个节点)#如果节点处于 Pod 所在的同一拓扑域且具有键“app”和值“myapp01”的标签, 则该 pod 不应将其调度到该节点上。 
#(如果 topologyKey 为 kubernetes.io/hostname,则意味着当节点和具有键 “app”和值“myapp01”的 Pod 处于相同的拓扑域,Pod 不能被调度到该节点上。)
kubectl apply -f pod6.yamlkubectl get pods --show-labels -o wide
# 最终myapp10会被调度到与myapp01不同的节点(如node01)

在这里插入图片描述

# 示例二
# 前提:node01和node02都有yjs=a这个标签
vim pod7.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp20labels:app: myapp20
spec:containers:- name: myapp20image: soscscs/myapp:v1affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- myapp01topologyKey: yjs#由于指定 Pod 所在的 node01 节点上具有带有键 yjs 和标签值 a 的标签,node02 也有这个yjs=a的标签,所以 node01 和 node02 是在一个拓扑域中,反亲和要求新 Pod 与指定 Pod 不在同一拓扑域,所以新 Pod 没有可用的 node 节点,即为 Pending 状态。
kubectl apply -f pod7.yamlkubectl get pod --show-labels -owide

在这里插入图片描述

五、污点(Taint)与容忍(Toleration)

节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 Pod。

污点与容忍机制用于实现节点对Pod的排斥例外,节点通过污点拒绝不匹配的Pod,而Pod通过容忍突破排斥。

5.1 污点(Taint)

5.1.1 污点格式与作用

污点格式:key=value:effect,其中effect定义排斥行为,支持以下三种类型:

effect类型描述
NoSchedule拒绝调度新Pod到该节点(已运行的Pod不受影响)
PreferNoSchedule尽量不调度新Pod到该节点(非强制)
NoExecute拒绝新Pod调度,且驱逐已运行的不匹配Pod

5.1.2 污点管理命令

  • 添加污点:kubectl taint node node01 key=value:NoSchedule
  • 查看节点污点:kubectl describe node node01 | grep Taint
  • 删除污点:kubectl taint node node01 key:NoSchedule-
kubectl get nodes
NAME       STATUS   ROLES                  AGE    VERSION
master01   Ready    control-plane,master   3d9h   v1.20.11
node01     Ready    <none>                 3d9h   v1.20.11
node02     Ready    <none>                 3d9h   v1.20.11# master 就是因为有 NoSchedule 污点,k8s 才不会将 Pod 调度到 master 节点上
kubectl describe node master| grep Taint
Taints:             node-role.kubernetes.io/master:NoSchedule
kubectl get pods -o wide
======================================================================================
NAME                     READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
affinity                 1/1     Running   0          48m    10.244.1.43   node01   <none>           <none>
affinity01               1/1     Running   0          44m    10.244.2.49   node02   <none>           <none>
affinity03               1/1     Running   0          23m    10.244.1.45   node01   <none>           <none>
myapp01                  1/1     Running   0          20m    10.244.2.50   node02   <none>           <none>
myapp02                  1/1     Running   0          18m    10.244.2.51   node02   <none>           <none>
myapp10                  1/1     Running   0          11m    10.244.1.46   node01   <none>           <none>
myapp20                  1/1     Running   0          104s   10.244.2.52   node02   <none>           <none>
nginx-5658bdf5d4-28jsk   1/1     Running   0          9s     10.244.1.49   node01   <none>           <none>
nginx-5658bdf5d4-f58gr   1/1     Running   0          9s     10.244.2.53   node02   <none>           <none>
nginx-5658bdf5d4-k2qsj   1/1     Running   0          9s     10.244.2.54   node02   <none>           <none>
nginx-5658bdf5d4-mn7hg   1/1     Running   0          9s     10.244.1.48   node01   <none>           <none>
nginx-5658bdf5d4-q84z6   1/1     Running   0          9s     10.244.1.47   node01   <none>           <none>kubectl taint node node02 check=mycheck:NoExecute# 查看 Pod 状态,会发现 node02 上的 Pod 已经被全部驱逐(注:如果是 Deployment 或者 StatefulSet 资源类型,为了维持副本数量则会在别的 Node 上再创建新的 Pod)
kubectl get pods -o wide
======================================================================================
NAME                     READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
affinity                 1/1     Running   0          49m    10.244.1.43   node01   <none>           <none>
affinity03               1/1     Running   0          24m    10.244.1.45   node01   <none>           <none>
myapp10                  1/1     Running   0          13m    10.244.1.46   node01   <none>           <none>
nginx-5658bdf5d4-28jsk   1/1     Running   0          110s   10.244.1.49   node01   <none>           <none>
nginx-5658bdf5d4-mn7hg   1/1     Running   0          110s   10.244.1.48   node01   <none>           <none>
nginx-5658bdf5d4-q84z6   1/1     Running   0          110s   10.244.1.47   node01   <none>           <none>
nginx-5658bdf5d4-qshrj   1/1     Running   0          14s    10.244.1.50   node01   <none>           <none>
nginx-5658bdf5d4-wwmr7   1/1     Running   0          14s    10.244.1.51   node01   <none>           <none>

5.2 容忍(Toleration)

Pod通过容忍配置可突破节点的污点限制,需与节点污点的keyvalueeffect匹配。

5.2.1 配置示例

kubectl taint node node01 check=mycheck:NoExecute
kubectl apply -f pod3.yaml
# 在两个 Node 上都设置了污点后,此时 Pod 将无法创建成功
kubectl get pods -o wide

在这里插入图片描述

vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1tolerations:- key: "check"operator: "Equal"  #operator: "Equal" #Equal意味着这个值等于value,如果是Exists,则不需要填写value,只要有这个key就容忍value: "mycheck"   # 与污点的value匹配effect: "NoExecute"      # 与污点的effect匹配tolerationSeconds: 3600  # 被驱逐前可在节点上保留的时间(仅对NoExecute有效)#其中的 key、vaule、effect 都要与 Node 上设置的 taint 保持一致
#operator 的值为 Exists 将会忽略 value 值,即存在即可
#tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在 Node 上继续保留运行的时间
kubectl apply -f pod3.yaml# 在设置了容忍之后,Pod 创建成功
kubectl get pods -o wide

在这里插入图片描述

5.2.2 特殊配置

1、当不指定 key 值时,表示容忍所有的污点 key:

tolerations:
- operator: "Exists"  # 忽略key和effect,容忍所有污点

2、容忍指定key的所有effect:

tolerations:
- key: "key"operator: "Exists"  # 忽略effect,容忍key=key的所有effect

3、有多个 Master 存在时,防止资源浪费,可以如下设置

kubectl taint node Master-Name node-role.kubernetes.io/master=:PreferNoSchedule

5.2.3 污点在Node节点更新组件时的作用

# 如果某个 Node 更新升级系统组件,为了防止业务长时间中断,可以先在该 Node 设置 NoExecute 污点,把该 Node 上的 Pod 都驱逐出去
kubectl taint node node01 check=mycheck:NoExecute# 此时如果别的 Node 资源不够用,可临时给 Master 设置 PreferNoSchedule 污点,让 Pod 可在 Master 上临时创建
kubectl taint node master node-role.kubernetes.io/master=:PreferNoSchedule# 待所有 Node 的更新操作都完成后,再去除污点
kubectl taint node node01 check=mycheck:NoExecute-

key、value、effect 必须与 Node 上的污点匹配。
operator: Exists 表示存在即可。

六、节点维护与Pod生命周期

6.1 节点维护操作

当需要对节点进行升级、检修时,可通过以下命令暂时隔离节点并迁移Pod:

命令功能描述
kubectl cordon <node>标记节点为“不可调度”,阻止新Pod调度至此
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data驱逐节点上的Pod(忽略DaemonSet,删除本地数据)
kubectl uncordon <node>恢复节点为“可调度”状态

说明:drain命令等价于“cordon + 驱逐”,适用于节点离线维护场景。

kubectl get po -owide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
affinity03               1/1     Running   0          4m34s   10.244.1.56   node01   <none>           <none>
myapp01                  1/1     Running   0          2m31s   10.244.2.61   node02   <none>           <none>
nginx-5658bdf5d4-kjrvc   1/1     Running   0          5m54s   10.244.1.55   node01   <none>           <none>
nginx-5658bdf5d4-mp599   1/1     Running   0          5m54s   10.244.1.57   node01   <none>           <none>
nginx-5658bdf5d4-pzj4t   1/1     Running   0          5m55s   10.244.1.53   node01   <none>           <none>
nginx-5658bdf5d4-qtt76   1/1     Running   0          5m54s   10.244.1.54   node01   <none>           <none>
nginx-5658bdf5d4-s4rhh   1/1     Running   0          5m54s   10.244.1.58   node01   <none>           <none>
# 标记节点不可调度
kubectl cordon node01
kubectl describe nodes node01 |grep Taint

在这里插入图片描述

# 驱逐node01上的pod
kubectl drain node01 --ignore-daemonsets --delete-emptydir-data --force
kubectl get po -owide

在这里插入图片描述

# 将节点恢复为可调度状态
kubectl uncordon <node>
kubectl describe nodes node01|grep Taint

在这里插入图片描述

Kubernetes 中的驱逐(Eviction)机制是指将运行中的 Pod 从当前节点迁移到其他节点的过程,旨在释放原节点资源供其他用途。主要触发场景包括:

  • 节点维护或升级时需要迁移 Pod
  • 节点资源不足,需通过驱逐现有 Pod 来腾出空间

Kubernetes 通过智能驱逐策略自动管理 Pod 迁移,其决策依据包括:

  • 节点负载情况
  • Pod 优先级设定

驱逐过程遵循标准终止流程:

  1. 发送 SIGTERM 信号通知 Pod
  2. 预留合理终止时间窗口
  3. 超时后强制终止并清理资源

该机制是保障 Kubernetes 集群稳定运行的核心功能,有效提升了:

  • 系统冗余性和可用性
  • 资源利用效率

6.2 Pod生命周期阶段(Phase)

Pod在生命周期中会经历以下阶段,反映其当前状态:

阶段说明
Pending已创建但未调度,或正在拉取镜像
Running至少一个容器运行中(或启动/重启中)
Succeeded所有容器正常终止(如Job类任务完成)
Failed至少一个容器异常终止(非0退出码或被强制终止)
Unknown无法获取状态(通常为通信故障)

phase的可能状态详解

  • Pending:表示 APIServer 已创建 Pod 资源对象并存入 etcd,但尚未完成调度(如未分配到具体节点)或仍在下载镜像过程中。

  • Running:Pod 已成功调度到节点,且所有容器均由 kubelet 创建完成。至少有一个容器处于运行状态或正在启动/重启(注意:处于 Running 状态的 Pod 不一定能正常提供服务)。

  • Succeeded:适用于非持久运行的 Pod(如 Job、CronJob)。当 Pod 中所有容器均成功终止且不再重启时进入此状态,通常用于反馈任务执行结果。

  • Failed:Pod 中所有容器均已终止,且至少有一个容器因故障退出(返回非0状态码或被系统强制终止)。

  • Unknown:表示无法获取 Pod 状态信息,通常由 kube-controller-manager 与 Pod 通信异常导致。

七、故障排查常用命令

操作需求命令示例
查看Pod事件(调度失败原因)kubectl describe pod <pod-name>
查看Pod日志kubectl logs <pod-name> [-c <container-name>]
进入容器执行命令kubectl exec -it <pod-name> -- bash
查看集群状态kubectl cluster-info
查看节点状态kubectl get nodes
查看kubelet日志journalctl -xefu kubelet

总结

Kubernetes调度是集群资源管理的核心,通过组件协作、调度算法、亲和性策略、污点与容忍等机制,实现了Pod的智能分配。本文从基础机制到实践操作,详细介绍了:

  1. 组件通过List-Watch机制协同工作,完成Pod从创建到运行的全流程;
  2. 调度器通过过滤与优选阶段选择最优节点,平衡资源利用率与业务需求;
  3. 节点选择方式从简单的强制绑定(nodeName)到灵活的标签匹配(nodeSelector)、亲和性调度,满足不同场景需求;
  4. 污点与容忍机制实现节点对Pod的精细控制,配合节点维护命令保障集群稳定性。

在实际应用中,需根据业务特点选择合适的调度策略(如核心服务优先使用硬亲和性,弹性服务使用软亲和性),并通过故障排查命令快速定位问题,确保集群高效稳定运行。

一句话总结“调度是吸引,污点是排斥,亲和性是偏好,容忍是例外。”

http://www.dtcms.com/a/482503.html

相关文章:

  • 基于MATLAB的遗传算法优化支持向量机实现
  • k8s(四)Kubernetes 集群调度
  • 如何从 iPhone 中导出视频
  • 关于网站开发的开题报告郑州制作平台网站
  • 吐鲁番做网站godaddy服务器做网站
  • 特色专业建设验收网站如何做网络营销方案策划
  • iBizModel 日历部件(PSSYSCALENDAR)模型体系详解
  • Goroutine间的“灵魂管道”:Channel如何实现数据同步与因果传递?
  • 一个网站上能不能放两个域名 两个备案号沧县做网站价格
  • GPIO 也是一个接口,还有 QEMU GPIODEV 和 GUSE
  • 网站制作公司电话山东专业网站建设公司
  • 第 8 篇:更广阔的世界 - 加载 3D 模型
  • C/C++---_access 和 access 函数 文件/目录状态判断
  • Linux内存管理-缓存系统中的Major和Minor详解
  • 8 读写分离-实战
  • 手机网站建设西安检查网站是否做301
  • 网站Favicon图标:小图标背后的大作用 引言
  • 什么是GEO生成式引擎优化?GEO科普:定义、原理与应用指南
  • 使用 Gensim 进行主题建模(LDA)与词向量训练(Word2Vec)的完整指南
  • 诺奖解码外周免疫耐受,泰克生物以抗体工具链加速机制研究突破
  • 虚幻引擎5 GAS开发俯视角RPG游戏 P05-07 广播效果资产标签
  • 南阳专业做网站抖音代运营平台
  • 网站公司怎么做的好天津海外seo
  • 二级网站建设方案模板做ppt的网站叫什么名字
  • Java优选算法——位运算
  • Linux编辑器vim
  • 大模型-去噪扩散概率模型(DDPM)采样算法详解
  • LeetCode 398:随机数索引
  • 通过公网STUN服务器实现UDP打洞
  • 手机怎样设计网站建设哪个网站有做兼职的