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

kubernetes 核心技术-调度器

在 Kubernetes 集群中,调度器扮演着至关重要的角色。它负责决定将哪些 Pod 放置到哪些节点上运行,以确保集群资源得到高效利用的同时满足各种约束条件。调度器不仅要考虑 CPU 和内存等基本资源的需求,还需要处理诸如亲和性、反亲和性、污点与容忍度等高级特性。本文将深入探讨 Kubernetes 调度器的工作原理及其核心概念,并介绍如何自定义调度策略来优化您的应用部署。

什么是 Kubernetes 调度器?

定义与背景

Kubernetes 调度器是一个控制平面组件,它根据一系列规则和策略选择最合适的节点来运行新的 Pods。其主要职责包括但不限于:

  • 资源分配:基于请求的资源量(如 CPU、内存)匹配合适的节点。
  • 服务质量保证:支持不同级别的服务质量(QoS),确保关键业务优先获得资源。
  • 约束满足:遵守用户指定的各种软硬性约束,比如节点亲和性、Pod 亲和性和反亲和性等。
  • 故障恢复:当某个节点出现故障时,重新调度受影响的 Pods 到健康的节点上。

关键特性

  • 智能决策:通过复杂的算法评估每个节点的适用性,寻找最优解。
  • 扩展能力:允许开发者自定义调度逻辑,满足特定需求。
  • 高可用设计:即使面对大规模集群,也能保证高效的调度性能。

调度流程详解

Kubernetes 调度过程大致可以分为两个阶段:过滤(Filtering)评分(Scoring)

过滤阶段

在此阶段,调度器会遍历集群中的所有节点,剔除那些不符合 Pod 声明要求的节点。这些要求可能包括但不限于:

  • 资源需求匹配:确保节点有足够的可用资源(CPU、内存等)来承载 Pod。
  • 节点标签筛选:如果 Pod 指定了 nodeSelector 或者使用了节点亲和性规则,则只有符合条件的节点才会被保留。
  • 污点与容忍度检查:如果一个节点设置了污点(Taints),那么除非 Pod 明确声明了相应的容忍度(Tolerations),否则该 Pod 将不会被调度到这个节点上。
示例

假设我们有一个 Pod 定义如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  nodeSelector:
    disktype: ssd

在这个例子中,除了常规的资源请求外,还指定了 nodeSelector 来限制 Pod 只能部署到带有 disktype=ssd 标签的节点上。这意味着,在过滤阶段,所有未标记为 SSD 的节点都将被排除在外。

评分阶段

经过过滤后剩下的候选节点将进入评分阶段。此时,调度器会对每个节点进行打分,分数越高表示越适合运行目标 Pod。常用的评分依据包括:

  • 资源利用率:倾向于选择那些资源使用率较低的节点,以便更好地平衡负载。
  • 亲和性偏好:如果有配置 Pod 亲和性或反亲和性规则,则会根据这些规则调整得分。
  • 其他自定义规则:开发者可以通过插件机制添加额外的评分标准。

最终,得分最高的节点会被选中作为 Pod 的宿主节点。

自定义调度策略

虽然默认的调度器已经非常强大,但在某些情况下,您可能希望进一步定制化调度行为。Kubernetes 提供了几种方式来实现这一点:

节点亲和性(Node Affinity)

节点亲和性允许您更灵活地指定 Pod 应该部署在哪类节点上。它有两种形式:

  • requiredDuringSchedulingIgnoredDuringExecution:必须满足的条件,类似于硬性约束。
  • preferredDuringSchedulingIgnoredDuringExecution:优先考虑但非强制性的条件,属于软性约束。
示例
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: k8s.gcr.io/pause:2.0

Pod 亲和性与反亲和性(Pod Affinity & Anti-Affinity)

Pod 亲和性和反亲和性使您可以基于现有 Pods 的位置来指导新 Pod 的放置。例如,为了提高性能,您可能想要让某些服务的实例尽可能靠近彼此;相反地,为了避免单点故障,您也可能希望它们分布在不同的节点上。

示例
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: security
          operator: In
          values:
          - S1
      topologyKey: failure-domain.beta.kubernetes.io/zone
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S2
        topologyKey: kubernetes.io/hostname

自定义调度器

对于需要高度定制化的场景,Kubernetes 还支持创建完全自定义的调度器。这通常涉及到开发一个新的可执行文件,并将其部署到集群中作为一个独立的服务。然后,您可以通过在 Pod 规范中指定 .spec.schedulerName 字段来选择使用哪个调度器。

实战演练

接下来我们将通过几个实际的例子来展示如何运用上述概念优化 Kubernetes 中的应用部署。

使用节点亲和性部署应用

假设我们要部署一个对磁盘 I/O 敏感的应用程序,并且只希望将其部署到具有 SSD 存储的节点上。我们可以这样做:

apiVersion: v1
kind: Pod
metadata:
  name: io-sensitive-app
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: app-container
    image: myregistry/myapp:v1

这样,只有标记了 disktype=ssd 的节点才有可能成为该 Pod 的宿主。

实现跨区域容错部署

为了增强服务的可靠性,我们可以利用 Pod 反亲和性规则,确保同一服务的不同实例不会同时位于同一个区域内的相同节点上:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-server
  template:
    metadata:
      labels:
        app: web-server
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-server
            topologyKey: topology.kubernetes.io/zone
      containers:
      - name: web-server
        image: nginx:latest

这段代码确保了三个副本的 Web 服务器 Pod 不会在同一个区域内运行在同一节点上,从而提高了系统的容错能力。

结语

感谢您的阅读!如果您对调度器或 Kubernetes 有任何疑问或见解,欢迎继续探讨。


http://www.kler.cn/a/522794.html

相关文章:

  • 登录授权流程
  • scratch学习教程
  • 【10.2】队列-设计循环队列
  • Coze,Dify,FastGPT,对比
  • Java基于SSM框架的互助学习平台小程序【附源码、文档】
  • WPS数据分析000005
  • 公式与函数的应用
  • 【前端SEO】使用Vue.js + Nuxt 框架构建服务端渲染 (SSR) 应用满足SEO需求
  • 基于 PyTorch 的深度学习模型开发实战
  • 搭建 docxify 静态博客教程
  • 13、Java JDBC 编程:连接数据库的桥梁
  • Java并发编程实战:深入探索线程池与Executor框架
  • WordPress Web Directory Free插件本地包含漏洞复现(附脚本)(CVE-2024-3673)
  • 更换keil工程芯片到103c8t6(HAL库版本)
  • 豆包MarsCode:字符串字符类型排序问题
  • JS宏进阶:控件与事件
  • java:read weather info from openweathermap.org
  • 书生大模型实战营2
  • Semaphore 与 线程池 Executor 有什么区别?
  • 嵌入式知识点总结 Linux驱动 (三)-文件系统
  • Linux 35.6 + JetPack v5.1.4之编译器升级
  • 在Rust应用中访问.ini格式的配置文件
  • vim如何解决‘’文件非法关闭后,遗留交换文件‘’的问题
  • 第3章 基于三电平空间矢量的中点电位平衡策略
  • 无人机+固定机巢 ,空地协同作业技术详解
  • Hive:Hive Shell技巧