k8s(五)集群调度与PV和PVC

文章目录

  • [一、Kubernetes 集群调度核心体系](#一、Kubernetes 集群调度核心体系)
    • [1.1 集群组件协作与List-Watch机制](#1.1 集群组件协作与List-Watch机制)
      • [1.1.1 核心组件及职责](#1.1.1 核心组件及职责)
      • [1.1.2 List-Watch 工作机制](#1.1.2 List-Watch 工作机制)
    • [1.2 Pod 创建完整流程(基于List-Watch)](#1.2 Pod 创建完整流程(基于List-Watch))
    • [1.3 Scheduler 调度流程](#1.3 Scheduler 调度流程)
      • [1.3.1 核心目标](#1.3.1 核心目标)
      • [1.3.2 调度两阶段](#1.3.2 调度两阶段)
        • [1.3.2.1 过滤阶段(Predicate)](#1.3.2.1 过滤阶段(Predicate))
        • [1.3.2.2 优选阶段(Priorities)](#1.3.2.2 优选阶段(Priorities))
    • [1.4 指定调度节点的方式](#1.4 指定调度节点的方式)
      • [1.4.1 nodeName(强制绑定)](#1.4.1 nodeName(强制绑定))
        • [1.4.1.1 功能说明](#1.4.1.1 功能说明)
        • [1.4.1.2 配置示例及解释](#1.4.1.2 配置示例及解释)
        • [1.4.1.3 执行命令及验证](#1.4.1.3 执行命令及验证)
      • [1.4.2 nodeSelector(标签强制匹配)](#1.4.2 nodeSelector(标签强制匹配))
        • [1.4.2.1 功能说明](#1.4.2.1 功能说明)
        • [1.4.2.2 操作步骤及配置示例](#1.4.2.2 操作步骤及配置示例)
        • [1.4.2.3 标签管理常用命令](#1.4.2.3 标签管理常用命令)
    • [1.5 亲和性与反亲和性调度](#1.5 亲和性与反亲和性调度)
      • [1.5.1 核心概念](#1.5.1 核心概念)
      • [1.5.2 节点亲和性(NodeAffinity)](#1.5.2 节点亲和性(NodeAffinity))
        • [1.5.2.1 硬策略示例](#1.5.2.1 硬策略示例)
        • [1.5.2.2 软策略示例](#1.5.2.2 软策略示例)
        • [1.5.2.3 软硬策略结合示例](#1.5.2.3 软硬策略结合示例)
      • [1.5.3 Pod 亲和性与反亲和性](#1.5.3 Pod 亲和性与反亲和性)
        • [1.5.3.1 Pod 亲和性示例](#1.5.3.1 Pod 亲和性示例)
        • [1.5.3.2 Pod 反亲和性示例](#1.5.3.2 Pod 反亲和性示例)
    • [1.6 污点(Taint)与容忍(Tolerations)](#1.6 污点(Taint)与容忍(Tolerations))
      • [1.6.1 污点核心概念](#1.6.1 污点核心概念)
      • [1.6.2 污点常用命令](#1.6.2 污点常用命令)
      • [1.6.3 容忍配置示例](#1.6.3 容忍配置示例)
    • [1.7 节点维护操作](#1.7 节点维护操作)
      • [1.7.1 核心命令及说明](#1.7.1 核心命令及说明)
      • [1.7.2 应用场景](#1.7.2 应用场景)
    • [1.8 Pod 生命周期阶段](#1.8 Pod 生命周期阶段)
    • [1.9 调度故障排查命令](#1.9 调度故障排查命令)
    • [1.10 核心调度策略总结](#1.10 核心调度策略总结)

一、Kubernetes 集群调度核心体系

1.1 集群组件协作与List-Watch机制

1.1.1 核心组件及职责

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

1.1.2 List-Watch 工作机制

Kubernetes 各核心组件(Controller Manager、Scheduler、kubelet)启动后,会通过 HTTPS 6443 端口监听 APIServer 的资源事件变化:

  • Controller Manager:监听 ReplicaSet、Deployment 等副本控制类对象
  • Scheduler:监听未调度的 Pod
  • kubelet:监听分配到本节点的 Pod
    当 etcd 中资源发生变更(如创建 Pod),会触发事件并同步至 APIServer,各组件通过监听感知变化并执行对应逻辑。

1.2 Pod 创建完整流程(基于List-Watch)

  1. 用户通过 kubectl apply -f pod.yaml 向 APIServer 发送创建 Pod 请求;
  2. APIServer 校验请求后,将 Pod 元数据写入 etcd;
  3. etcd 触发 Create 事件并同步至 APIServer;
  4. Controller Manager 监听到事件后,通过 RC/ReplicaSet 保证 Pod 副本数;
  5. APIServer 更新 Pod 详细信息至 etcd,etcd 再次触发更新事件;
  6. Scheduler 监听至 Pending 状态的 Pod,通过调度算法选择目标 Node;
  7. Scheduler 将 Node 绑定信息写入 APIServer,同步至 etcd;
  8. 目标节点的 kubelet 监听到 Pod 分配事件,调用容器运行时拉取镜像、创建并启动容器;
  9. kubelet 将 Pod 运行状态上报至 APIServer,最终同步至 etcd,Pod 进入 Running 状态。

1.3 Scheduler 调度流程

1.3.1 核心目标

公平性(节点资源均衡)、高效性(资源最大化利用)、效率(批量调度性能)、灵活性(支持自定义策略)。

1.3.2 调度两阶段

1.3.2.1 过滤阶段(Predicate)

过滤掉不满足条件的节点,常见算法:

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

无满足条件节点时,Pod 持续 Pending 并重试调度。

1.3.2.2 优选阶段(Priorities)

对过滤后的节点打分排序,常见算法:

优先级项 描述
LeastRequestedPriority 资源使用率越低,权重越高
BalancedResourceAllocation CPU 与内存使用率越接近越好(通常与上一算法配合使用)
ImageLocalityPriority 优先选择已有目标镜像的节点

最终选择权重最高的节点完成调度。

1.4 指定调度节点的方式

1.4.1 nodeName(强制绑定)

1.4.1.1 功能说明

直接将 Pod 绑定到指定 Node,跳过 Scheduler 调度逻辑,由 kubelet 直接启动容器。

1.4.1.2 配置示例及解释
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp # Deployment 名称
spec:
  replicas: 3 # 副本数
  selector:
    matchLabels:
      app: myapp # 匹配Pod标签
  template:
    metadata:
      labels:
        app: myapp # Pod标签
    spec:
      nodeName: node01 # 强制绑定到node01节点
      containers:
      - name: myapp # 容器名称
        image: soscscs/myapp:v1 # 容器镜像
        ports:
        - containerPort: 80 # 容器暴露端口
1.4.1.3 执行命令及验证
bash 复制代码
# 应用配置文件
kubectl apply -f myapp.yaml
# 查看Pod分布(所有Pod都会运行在node01)
kubectl get pods -o wide
# 查看Pod事件(无Scheduler调度记录)
kubectl describe pod <Pod名称>

1.4.2 nodeSelector(标签强制匹配)

1.4.2.1 功能说明

通过 Node 标签匹配选择节点,由 Scheduler 执行调度,属于强制约束。

1.4.2.2 操作步骤及配置示例
  1. 给 Node 设置标签:
bash 复制代码
# 给node01设置标签yjs=a
kubectl label nodes node01 yjs=a
# 给node02设置标签yjs=b
kubectl label nodes node02 yjs=b
# 查看节点标签
kubectl get nodes --show-labels
  1. 配置 Pod 的 nodeSelector:
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 # 仅匹配标签yjs=a的节点
      containers:
      - name: myapp1
        image: soscscs/myapp:v1
        ports:
        - containerPort: 80
  1. 执行命令及验证:
bash 复制代码
kubectl apply -f myapp1.yaml
kubectl get pods -o wide # 所有Pod运行在node01
kubectl describe pod <Pod名称> # 可看到Scheduler调度记录
1.4.2.3 标签管理常用命令
bash 复制代码
# 修改标签(需加--overwrite)
kubectl label nodes node02 yjs=c --overwrite
# 删除标签(key后加-)
kubectl label nodes node02 yjs-
# 按标签筛选节点
kubectl get node -l yjs=a

1.5 亲和性与反亲和性调度

1.5.1 核心概念

调度策略 匹配对象 操作符 拓扑域支持 调度目标
nodeAffinity 节点标签 In/NotIn/Exists等 指定节点
podAffinity Pod标签 In/NotIn/Exists等 与指定Pod同拓扑域
podAntiAffinity Pod标签 In/NotIn/Exists等 与指定Pod不同拓扑域
  • 硬策略:requiredDuringSchedulingIgnoredDuringExecution(必须满足,否则Pod Pending)
  • 软策略:preferredDuringSchedulingIgnoredDuringExecution(优先满足,不满足也可调度)

1.5.2 节点亲和性(NodeAffinity)

1.5.2.1 硬策略示例
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 # 匹配节点标签键
            operator: NotIn # 标签值不在指定列表
            values:
            - node02 # 排除node02节点

验证:Pod 只会调度到非node02的节点,若所有节点都不满足,Pod 持续 Pending。

1.5.2.2 软策略示例
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,无则调度到其他节点
1.5.2.3 软硬策略结合示例
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:
      # 先满足硬策略:排除node02
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - node02
      # 再满足软策略:优先选择yjs=a的节点
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: yjs
            operator: In
            values:
            - a

1.5.3 Pod 亲和性与反亲和性

1.5.3.1 Pod 亲和性示例
  1. 先创建基准 Pod:
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01 # 基准Pod标签
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  1. 配置 Pod 亲和性(与基准Pod同拓扑域):
yaml 复制代码
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 # 匹配基准Pod标签
        topologyKey: yjs # 拓扑域(同yjs标签值的节点为同一域)

效果:myapp02 仅调度到与 myapp01 同yjs标签的节点。

1.5.3.2 Pod 反亲和性示例
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 # 匹配基准Pod标签
          topologyKey: kubernetes.io/hostname # 拓扑域为节点名称

效果:myapp10 尽量不调度到运行myapp01的节点。

1.6 污点(Taint)与容忍(Tolerations)

1.6.1 污点核心概念

  • 格式:key=value:effect

  • Effect 类型:

    类型 描述
    NoSchedule 不调度新Pod到该节点
    PreferNoSchedule 尽量避免调度新Pod到该节点
    NoExecute 不调度新Pod + 驱逐已运行的Pod

1.6.2 污点常用命令

bash 复制代码
# 给node01设置污点(NoSchedule)
kubectl taint node node01 key1=value1:NoSchedule
# 查看节点污点(Taints字段)
kubectl describe node node01
# 去除污点(key后加effect-)
kubectl taint node node01 key1:NoSchedule-
# 给node02设置NoExecute污点(驱逐已有Pod)
kubectl taint node node02 check=mycheck:NoExecute

1.6.3 容忍配置示例

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  tolerations:
  - key: "check" # 匹配污点的key
    operator: "Equal" # 匹配规则(Equal需值匹配,Exists仅需key存在)
    value: "mycheck" # 匹配污点的value
    effect: "NoExecute" # 匹配污点的effect
    tolerationSeconds: 3600 # 驱逐前保留时间(仅NoExecute生效)

特殊配置:

  1. 容忍所有污点:tolerations: - operator: "Exists"
  2. 容忍所有effect:tolerations: - key: "key" operator: "Exists"

1.7 节点维护操作

1.7.1 核心命令及说明

命令 功能说明
kubectl cordon <node> 标记节点为不可调度(新Pod不调度到该节点,已有Pod保留)
kubectl drain <node> --ignore-daemonsets --delete-local-data --force 驱逐节点上的Pod(忽略守护进程集、删除本地数据、强制驱逐),等价于cordon+驱逐
kubectl uncordon <node> 恢复节点可调度状态

1.7.2 应用场景

  • 节点升级/维护前:先执行 drain 驱逐Pod,避免业务中断;
  • 临时禁用节点调度:执行 cordon,维护完成后执行 uncordon 恢复。

1.8 Pod 生命周期阶段

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

1.9 调度故障排查命令

bash 复制代码
# 查看Pod事件(定位调度失败原因)
kubectl describe pod <Pod名称>
# 查看Pod日志(容器启动失败时)
kubectl logs <Pod名称> [-c 容器名]
# 进入容器排查
kubectl exec -it <Pod名称> bash
# 查看集群状态
kubectl cluster-info
# 查看节点状态
kubectl get nodes
# 查看kubelet日志(节点层面故障)
journalctl -xefu kubelet

1.10 核心调度策略总结

  1. nodeName:直接绑定节点,跳过调度器;
  2. nodeSelector:基于标签强制匹配节点;
  3. 亲和性:按节点/Pod标签设置调度偏好(硬/软策略);
  4. 污点&容忍:节点排斥Pod,容忍的Pod可例外调度;
  5. cordon/drain:节点维护时的Pod迁移与调度控制。

核心逻辑:调度是吸引,污点是排斥,亲和性是偏好,容忍是例外

相关推荐
海鸥812 小时前
K8s 的 command/args 会覆盖 Dockerfile 的 CMD/ENTRYPOINT
云原生·容器·kubernetes
江湖有缘2 小时前
Mikochi + Docker:打造属于你的私有云文件浏览器
运维·docker·容器
db_cy_20622 小时前
Docker+Kubernetes企业级容器化部署解决方案(阶段二)
运维·docker·容器·kubernetes
youxiao_902 小时前
kubernetes(三)-Rancher管理k8s集群
容器·kubernetes·rancher
浮生若梦l2 小时前
docker部署springboot项目记录
spring boot·docker·容器
祁思妙想3 小时前
使用Docker部署Python前后端项目
运维·docker·容器
零度@3 小时前
Java 消息中间件 - 云原生多租户:Pulsar 保姆级全解2026
java·开发语言·云原生
C_心欲无痕3 小时前
Docker 本地部署 SSR 前端项目实战指南
前端·docker·容器
robch3 小时前
k8s service deployment pod 的 label
云原生·容器·kubernetes