Kubernetes 集群调度

目录

[一、Kubernetes 集群调度](#一、Kubernetes 集群调度)

[1、Kubernetes 组件协作机制](#1、Kubernetes 组件协作机制)

关键组件关系:

[2、Pod 创建与工作机制流程](#2、Pod 创建与工作机制流程)

[典型创建过程(List-Watch 模型)](#典型创建过程(List-Watch 模型))

(1)三大组件启动监听(List-Watch)

3、调度流程

[3.1 过滤阶段(Predicate)](#3.1 过滤阶段(Predicate))

[3.2 优选阶段(Priorities)](#3.2 优选阶段(Priorities))

指定调度节点方式

nodeName(强制绑定)

ymal文件

查看调度节点

nodeSelector(基于标签匹配)

当前的节点

[给对应的 node 设置标签分别为 yjs=a 和 yjs=b](#给对应的 node 设置标签分别为 yjs=a 和 yjs=b)

展示标签

修改label的值

删除标签

[修改成 nodeSelector 调度方式](#修改成 nodeSelector 调度方式)

查看详细事件

[节点亲和性与 Pod 亲和性](#节点亲和性与 Pod 亲和性)

定义

类比举例子

硬策略

yaml文件

查看pod节点

删除所有的容器并不会被创建的命令

软策略

查看节点信息

软策略加硬策略

查看信息

[Pod 亲和性与反亲和性](#Pod 亲和性与反亲和性)

[Pod 亲和性调度](#Pod 亲和性调度)

[创建一个标签为 app=myapp01 的 Pod](#创建一个标签为 app=myapp01 的 Pod)

[使用 Pod 亲和性调度,创建多个 Pod 资源](#使用 Pod 亲和性调度,创建多个 Pod 资源)

[Pod 反亲和性调度](#Pod 反亲和性调度)

[污点(Taint) 和 容忍(Tolerations)](#污点(Taint) 和 容忍(Tolerations))

命令示例

污点(Taint)

容忍 (Tolerations)

仍然能运行起来


一、Kubernetes 集群调度


1、Kubernetes 组件协作机制

Kubernetes 通过 List-Watch 机制使各个组件协作、数据同步,从而实现解耦与实时一致性。

关键组件关系:

组件 职责
kubectl / API 客户端 向 APIServer 发起资源创建或管理请求
APIServer 负责 API 调用、权限校验、存储交互,是集群控制的核心入口
etcd 存储集群所有状态信息
Controller Manager 维持副本数、执行自愈逻辑(扩容、重建等)
Scheduler 调度器,将未分配节点的 Pod 分配到合适的 Node
kubelet 节点代理,负责 Pod 生命周期管理和容器运行状态上报

用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。

APIServer 经过 API 调用,权限控制,调用资源和存储资源的过程,实际上还没有真正开始部署应用。这里 需要 Controller Manager、Scheduler 和 kubelet 的协助才能完成整个部署过程。

在 Kubernetes 中,所有部署的信息都会写到 etcd 中保存。实际上 etcd 在存储部署信息的时候,会发送 Create 事件给 APIServer,而 APIServer 会通过监听(Watch)etcd 发过来的事件。其他组件也会监听(Watch)APIServer 发出来的事件。

2、Pod 创建与工作机制流程

Pod 创建的整个生命周期由多组件配合完成:

典型创建过程(List-Watch 模型)

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

    • Controller Manager:监听副本控制类对象(如 ReplicaSet、Deployment)

    • Scheduler:监听未调度的 Pod

    • kubelet:监听分配到本节点的 Pod

3、调度流程

3.1 过滤阶段(Predicate)

过滤掉不满足条件的节点。

常见过滤算法:

算法名 功能描述
PodFitsResources 检查节点剩余资源是否满足 Pod 需求
PodFitsHost 检查 NodeName 是否匹配
PodFitsHostPorts 检查端口冲突
PodSelectorMatches label 匹配
NoDiskConflict Volume 挂载冲突检测

若无节点满足条件,Pod 进入 Pending 状态,不断重试。

如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。 经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。


3.2 优选阶段(Priorities)

对可行节点进行打分排序。

常见算法:

优先级项 描述
LeastRequestedPriority 资源使用率越低,权重越高
BalancedResourceAllocation CPU 与内存使用率越接近越好(这个一般和上面的一起使用,不单独使用。比如 node01 的 CPU 和 Memory 使用率 20:60,node02 的 CPU 和 Memory 使用率 50:50,虽然 node01 的总使用率比 node02 低,但 node02 的 CPU 和 Memory 使用率更接近,从而调度时会优选 node02。)
ImageLocalityPriority 优先节点上已有目标镜像的节点

指定调度节点方式

nodeName(强制绑定)

ymal文件

复制代码
vim myapp.yaml

apiVersion: apps/v1  
kind: Deployment   # pod
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      nodeName: node01
      containers:
      - name: myapp
        image: soscscs/myapp:v1
        ports:
        - containerPort: 80

kubectl apply -f myapp.yaml

查看调度节点

复制代码
kubectl get pods -o wide
复制代码
 kubectl describe pod myapp-699655c7fd-5qrp2|tail -6

nodeSelector(基于标签匹配)

当前的节点

给对应的 node 设置标签分别为 yjs=a 和 yjs=b

复制代码
kubectl label nodes node01 yjs=a

kubectl label nodes node02 yjs=b

展示标签

复制代码
kubectl get node --show-labels

修改label的值

复制代码
kubectl label node node02 yjs=c --overwrite

删除标签

复制代码
kubectl label nodes node02 yjs-

修改成 nodeSelector 调度方式

复制代码
vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment  
metadata:
  name: myapp1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp1
  template:
    metadata:
      labels:
        app: myapp1
    spec:
      nodeSelector:
	    yjs: a
      containers:
      - name: myapp1
        image: soscscs/myapp:v1
        ports:
        - containerPort: 80 
        
kubectl apply -f myapp1.yaml 

获取pod信息

复制代码
kubectl get pods -o wide

查看详细事件

复制代码
kubectl describe pod myapp1-64c58784f9-42ctc|tail -10

节点亲和性与 Pod 亲和性

定义

复制代码
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:   # 硬策略
    preferredDuringSchedulingIgnoredDuringExecution:  # 软策略

类比举例子

你更"想去"陈老师的班(软策略),还是"必须去"陈老师的班(硬策略)

运算符 含义 通俗理解 示例
In label 的值在列表中 "只要它的值在我列的名单里,就选上它" env In (dev, test) → 选出 env=devenv=test 的 Pod
NotIn label 的值不在列表中 "黑名单里的不要" env NotIn (prod) → 除了生产环境都选上
Gt label 的值大于某个数 "比这个数字大的才要" version Gt 3 → 选出 version=4,5,6... 的 Pod
Lt label 的值小于某个数 "比这个数字小的才要" version Lt 3 → 选出 version=1,2 的 Pod
Exists label 存在即可 "只要有这个标签就算数,不管值是啥" Exists zone → 只要有 zone 这个标签
DoesNotExist label 不存在 "没有这个标签的才要" DoesNotExist debug → 没有 debug 标签的 Pod

硬策略

复制代码
kubectl get nodes --show-labels

yaml文件

复制代码
vim pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname    #指定node的标签
            operator: NotIn #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
            values:
            - node02

kubectl apply -f pod1.yaml

查看pod节点

删除所有的容器并不会被创建的命令

复制代码
kubectl delete deployments --all

软策略

复制代码
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1   #如果有多个软策略选项的话,数值越小,权重越大,优先级越高
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - node03   # 这里没有node03这个节点

kubectl apply -f pod2.yaml

查看节点信息

软策略加硬策略

复制代码
vim demo2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: affinity1
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:   #先满足硬策略,排除有kubernetes.io/hostname=node02标签的节点
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - node02
      preferredDuringSchedulingIgnoredDuringExecution:  #再满足软策略,优先选择有yjsc=a标签的节点
	  - weight: 1
        preference:
          matchExpressions:
          - key: yjs
            operator: In
            values:
            - a

kubectl apply -f pod2.yaml

查看信息

Pod 亲和性与反亲和性

调度策略 匹配标签 操作符 拓扑域支持 调度目标
nodeAffinity 主机 IIn, NotIn, Exists,DoesNotExist, Gt, Lt 指定主机
podAffinity Pod In, NotIn, Exists,DoesNotExist 与指定 Pod 同域
podAntiAffinity Pod In, NotIn, Exists,DoesNotExist 与指定 Pod 不同域

Pod 亲和性调度

创建一个标签为 app=myapp01 的 Pod

复制代码
vim pod3.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1

kubectl apply -f pod3.yaml

使用 Pod 亲和性调度,创建多个 Pod 资源

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp02
  labels:
    app: myapp02
spec:
  containers:
  - name: myapp02
    image: soscscs/myapp:v1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - myapp01
        topologyKey: yjs

Pod 反亲和性调度

复制代码
vim pod5.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp10
  labels:
    app: myapp10
spec:
  containers:
  - name: myapp10
    image: soscscs/myapp:v1
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - myapp01
          topologyKey: kubernetes.io/hostname

反亲和调度

复制代码
vim pod6.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp20
  labels:
    app: myapp20
spec:
  containers:
  - name: myapp20
    image: soscscs/myapp:v1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - myapp01
        topologyKey: yjs

kubectl apply -f pod6.yaml

污点(Taint) 和 容忍(Tolerations)

类型 描述
NoSchedule 不调度到此节点
PreferNoSchedule 尽量避免调度具有该污点的 Node 上
NoExecute 不调度 + 驱逐已存在 Pod(只是将pod放到其他的node上面)

命令示例

复制代码
# 主节点的污点
kubectl describe node master|grep Taint
Taints:             node-role.kubernetes.io/master:NoSchedule

# node01设置污点
kubectl taint node node01 key1=value1:NoSchedule
kubectl describe node node01|grep Taint
Taints:             key1=value1:NoSchedule


# 去除污点
kubectl taint node node01 key1:NoSchedule-
kubectl describe node node01|grep Taint
Taints:             <none>

污点(Taint)

复制代码
kubectl taint node node02 check=mycheck:NoExecute

容忍 (Tolerations)

复制代码
# 先给两个节点设置污点
kubectl taint node node01 key1=value1:NoSchedule
kubectl taint node node02 key1=value1:NoSchedule

按常理来说,镜像运行不起来

但是我们在文件中加上toleration的参数

复制代码
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  tolerations:
  - key: "check"
    operator: "Equal"  #operator: "Equal" #Equal意味着这个值等于value,如果是Exists,则不需要填写value,只要有这个key就容忍
    value: "mycheck"
    effect: "NoExecute"
    tolerationSeconds: 3600

仍然能运行起来

复制代码
kubectl get pod -owide
相关推荐
编程岁月3 小时前
java面试-0203-java集合并发修改异常、快速/安全失败原理、解决方法?
java·开发语言·面试
aodunsoft3 小时前
安全月报 | 傲盾DDoS攻击防御2025年9月简报
网络·安全·ddos
杂化轨道VSEPR3 小时前
基站计数器与KPI:移动通信网络性能评估的核心引擎
运维·服务器·网络·5g·信息与通信
小张数码3 小时前
随身WiFi技术深探:通信芯片/信号增益原理解析+开源方案参考!随身WiFi建议买吗?随身WiFi品牌哪个网速快信号稳定?格行随身WiFi怎么样?
网络·物联网
Starry_hello world3 小时前
Linux 进程地址空间
linux·笔记·有问必答
whltaoin3 小时前
AI 超级智能体全栈项目阶段五:RAG 四大流程详解、最佳实践与调优(基于 Spring AI 实现)
java·人工智能·spring·rag·springai
junnhwan3 小时前
【苍穹外卖笔记】Day05--Redis入门与店铺营业状态设置
java·数据库·redis·笔记·后端·苍穹外卖
m0_464608264 小时前
Kubernetes 集群调度与PV和PVC
云原生·容器·kubernetes
撬动未来的支点4 小时前
【Linux】Linux驱动开发与BSP开发:嵌入式系统的两大基石
linux·驱动开发