53、Kubernetes Pod 调度的高级技术

Kubernetes Pod 调度的高级技术

在 Kubernetes 集群中,合理地调度 Pod 至关重要,它直接影响着资源的利用率和应用的性能。本文将介绍几种高级的 Pod 调度技术,包括 nodeSelector 、 Node affinity 以及 Taints and tolerations 。

1. 使用 nodeSelector 进行 Pod 调度

nodeSelector 是一种基本的 Pod 调度方法,它允许你将 Pod 仅调度到具有特定标签值的节点上。

1.1 nodeSelector 的应用场景
  • 混合集群 :通过指定操作系统作为调度标准,确保 Windows 容器在 Windows 节点上运行,Linux 容器在 Linux 节点上运行。
  • 资源分配 :将 Pod 调度到具有特定资源(CPU、内存、存储)的节点上,以优化资源利用率。
  • 硬件要求 :仅将需要特殊硬件(如 GPU)的 Pod 调度到具备相应能力的节点上。
  • 安全区域 :使用标签定义安全区域,并使用 nodeSelector 将 Pod 限制在特定区域,以增强安全性。
1.2 默认节点标签

每个 Kubernetes 节点默认都带有一组标签,例如:
- kubernetes.io/arch :描述节点的处理器架构,如 amd64 或 arm 。
- kubernetes.io/os :值为 linux 或 Windows 。
- node-role.kubernetes.io/control-plane :节点在 Kubernetes 集群中的角色。

1.3 操作步骤

以下是使用 nodeSelector 的具体操作步骤:
1. 为集群中的 Node 1 和 Node 2 添加 node-type=superfast 标签:

$ kubectl label nodes minikube-m02 node-type=superfast
node/minikube-m02 labeled
$ kubectl label nodes minikube-m03 node-type=superfast
node/minikube-m03 labeled
  1. 验证节点标签:
$ kubectl get nodes --show-labels |grep superfast
  1. 编辑 02_nodeselector/nginx-deployment.yaml 文件,设置 nodeSelector 为 node-type: superfast :
# 02_nodeselector/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  ...
  template:
    ...
    spec:
      nodeSelector:
        node-type: superfast
  1. 应用配置文件并检查 Pod 状态和节点分配:
$ kubectl apply -f 02_nodeselector/nginx-deployment.yaml
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"
  1. 若将 nodeSelector 设置为 node-type: slow (集群中没有节点具有该标签),则 Pod 将无法调度,Deployment 会卡住。
2. 使用 Node affinity 进行 Pod 调度

Node affinity 扩展了 nodeSelector 的功能,提供了更丰富的语言来定义 Pod 对节点的偏好或排斥。

2.1 Node affinity 的优势
  • 规则表达更丰富 :可以使用 In 、 NotIn 、 Exists 、 DoesNotExist 、 Gt 和 Lt 等操作符来匹配节点标签。
  • 支持 Pod 间亲和性和反亲和性 :可以定义规则使 Pod 被吸引到或排斥某些节点,有助于减少延迟。
  • 支持软亲和性和反亲和性规则 :软规则表示偏好,而不是硬性要求,即使不满足软规则,调度器仍可调度 Pod。
  • 软规则可加权 :可以添加多个具有不同权重值的规则,调度器会综合考虑权重和其他参数来做出调度决策。
2.2 示例演示

为了演示 Node affinity ,我们将尝试为 Deployment 建模以下要求:“尝试仅将 Pod 调度到具有 node-type 标签值为 fast 或 superfast 的节点上,但如果无法实现,则使用任何节点,但严格避免 node-type 标签值为 extremelyslow 的节点。”

操作步骤如下:
1. 为节点添加标签:

$ kubectl label nodes --overwrite minikube node-type=slow
node/minikube labeled
$ kubectl label nodes --overwrite minikube-m02 node-type=fast
node/minikube-m02 labeled
$ kubectl label nodes --overwrite minikube-m03 node-type=superfast
node/minikube-m03 not labeled
  1. 编辑 03_affinity/nginx-deployment.yaml 文件,定义软 Node 亲和性规则:
# 03_affinity/nginx-deployment.yaml
...
spec:
  ...
  template:
    ...
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-type
                operator: NotIn
                values:
                - extremelyslow
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: node-type
                operator: In
                values:
                - fast
                - superfast
  1. 应用配置文件并检查 Pod 状态和节点分配:
$ kubectl apply -f 03_affinity/nginx-deployment.yaml
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"
  1. 重新标记节点并重启 Deployment:
$ kubectl label nodes --overwrite minikube node-type=slow
node/minikube not labeled
$ kubectl label nodes --overwrite minikube-m02 node-type=extremelyslow
node/minikube-m02 labeled
$ kubectl label nodes --overwrite minikube-m03 node-type=extremelyslow
node/minikube-m03 labeled
$ kubectl rollout restart deployment nginx-app
  1. 再次检查 Pod 状态和节点分配:
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"
2.3 Node affinity 流程图
graph TD;
    A[开始] --> B[定义 Node affinity 规则];
    B --> C[应用规则到 Deployment];
    C --> D[检查 Pod 调度结果];
    D --> E{是否满足规则};
    E -- 是 --> F[调度成功];
    E -- 否 --> G[根据软规则调度];
    G --> H[检查资源是否充足];
    H -- 是 --> F;
    H -- 否 --> I[Pod 处于 Pending 状态];

通过以上步骤,我们成功地配置了 Node affinity ,实现了对 Pod 调度的更精细控制。接下来,我们将介绍另一种 Pod 调度技术—— Taints and tolerations 。

3. 使用 Node taints 和 tolerations 进行 Pod 调度

虽然使用 Node 和 Pod 间的亲和性机制进行 Pod 调度非常强大,但有时你需要一种更简单的方法来指定哪些节点应该排斥 Pod。Kubernetes 为此提供了两个稍旧且更简单的功能——污点(Taints)和容忍度(Tolerations)。

3.1 污点和容忍度的概念
  • 污点(Taints) :应用于节点,描述节点的某种限制。所有 Pod 都会避免调度到带有污点的节点,除非 Pod 有相应的容忍度。
  • 容忍度(Tolerations) :定义在 Pod 规范中,允许 Pod 调度到带有特定污点的节点。
3.2 污点的结构和效果

污点的结构为 <key>=<value>:<effect> ,其中 key 和 value 对标识污点, effect 表示污点的效果,有以下几种:
- NoSchedule :kube-scheduler 不会将 Pod 调度到该节点。
- PreferNoSchedule :kube-scheduler 会尽量不将 Pod 调度到该节点。
- NoExecute :kube-scheduler 不会将 Pod 调度到该节点,并会驱逐(终止并重新调度)正在该节点上运行的 Pod。

3.3 内置污点

Kubernetes 会自动管理一些 NoExecute 污点,例如:
- node.kubernetes.io/not-ready :当节点状态为 Ready 为 false 时添加。
- node.kubernetes.io/unreachable :当节点状态为 Ready 为 Unknown 时添加。
- node.kubernetes.io/memory-pressure :节点内存压力过大。
- node.kubernetes.io/disk-pressure :节点磁盘压力过大。
- node.kubernetes.io/network-unavailable :节点网络不可用。
- node.kubernetes.io/unschedulable :节点当前不可调度。
- node.cloudprovider.kubernetes.io/uninitialized :用于由外部云提供商准备的节点,初始化后该污点会被移除。

3.4 操作步骤

以下是使用污点和容忍度的具体操作步骤:
1. 为节点添加污点:

$ kubectl taint node minikube machine-check-exception=memory:NoExecute
node/minikube tainted
  1. 检查 Pod 状态和节点分配:
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"

此时,所有 Deployment Pod 都会处于 Pending 状态,因为 kube-scheduler 无法找到可以运行它们的节点。

  1. 编辑 04_taints/nginx-deployment.yaml 文件,定义污点容忍度:
# 04_taints/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  ...
  template:
    ...
    spec:
      tolerations:
        - key: machine-check-exception
          operator: Equal
          value: memory
          effect: NoExecute
          tolerationSeconds: 60
  1. 应用配置文件并检查 Pod 状态和节点分配:
$ kubectl apply -f 04_taints/nginx-deployment.yaml
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"

此时,你会发现 Pod 可以调度到 Node2 和 Node3,但 Node1 上的 Pod 会每 60 秒进入一次驱逐循环。

  1. 为节点添加 NoSchedule 污点:
$ kubectl taint node minikube machine-check-exception=memory:NoSchedule
node/minikube tainted
  1. 再次检查 Pod 状态和节点分配:
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"

此时,Pods 会均匀分布在 Node2 和 Node3 上。

  1. 移除节点上的污点:
$ kubectl taint node minikube machine-check-exception-
node/minikube untainted
  1. 重启 Deployment 以重新调度 Pod:
$ kubectl rollout restart deployment nginx-app
deployment.apps/nginx-app restarted
  1. 再次检查 Pod 状态和节点分配:
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"

此时,Pods 会再次均匀分布在所有三个节点上。

  1. 再次应用 NoSchedule 和 NoExecute 污点:
$ kubectl taint node minikube machine-check-exception=memory:NoSchedule
node/minikube tainted
$ kubectl taint node minikube machine-check-exception=memory:NoExecute
node/minikube tainted
  1. 观察 Pod 状态和节点分配:
$ kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"

60 秒后,Pods 会被驱逐,并且不会出现驱逐 - 调度循环。

3.5 污点和容忍度的流程图
graph TD;
    A[开始] --> B[为节点添加污点];
    B --> C[检查 Pod 调度状态];
    C --> D{Pod 是否有容忍度};
    D -- 是 --> E{是否有 NoExecute 容忍度};
    E -- 是 --> F{是否设置 tolerationSeconds};
    F -- 是 --> G[在指定时间内容忍污点];
    G --> H[时间到后驱逐 Pod];
    F -- 否 --> I[立即驱逐 Pod];
    E -- 否 --> J[Pod 可调度到节点];
    D -- 否 --> K[Pod 处于 Pending 状态];

通过使用污点和容忍度,我们可以更灵活地控制 Pod 的调度,避免 Pod 被调度到不适合的节点上。

总结

本文介绍了三种高级的 Pod 调度技术: nodeSelector 、 Node affinity 和 Taints and tolerations 。 nodeSelector 是一种简单的调度方法,适用于基本的调度需求; Node affinity 提供了更丰富的调度规则,可实现更精细的调度控制; Taints and tolerations 则允许我们指定节点的限制,使 Pod 能够容忍这些限制。在实际应用中,你可以根据具体需求选择合适的调度技术,以优化资源利用率和应用性能。

Kubernetes Pod 调度的高级技术

4. 三种调度技术对比

为了更清晰地了解 nodeSelector 、 Node affinity 和 Taints and tolerations 这三种调度技术的特点和适用场景,我们可以通过以下表格进行对比:

调度技术 描述 优点 缺点 适用场景
nodeSelector 允许将 Pod 仅调度到具有特定标签值的节点上 简单易懂,易于配置 规则表达能力有限,只能进行简单的相等比较 基本的调度需求,如根据操作系统、硬件类型等进行调度
Node affinity 扩展了 nodeSelector 的功能,提供更丰富的语言来定义 Pod 对节点的偏好或排斥 规则表达丰富,支持多种操作符,可定义软规则和反亲和性 配置相对复杂 需要更精细的调度控制,如根据节点资源、Pod 间关系等进行调度
Taints and tolerations 应用污点到节点,Pod 需要有特定容忍度才能调度到该节点 可简单指定节点排斥 Pod,支持多种污点效果 理解和配置有一定难度,可能导致 Pod 调度问题 需要指定节点的限制,使 Pod 能够容忍这些限制,如隔离特殊节点、处理节点故障等
5. 实际应用中的考虑因素

在实际应用中,选择合适的 Pod 调度技术需要考虑以下因素:

5.1 集群规模和复杂度
  • 小规模集群 :如果集群规模较小,且调度需求相对简单, nodeSelector 可能是一个不错的选择,因为它配置简单,易于理解和维护。
  • 大规模集群 :对于大规模集群,调度需求通常较为复杂,可能需要使用 Node affinity 或 Taints and tolerations 来实现更精细的调度控制。
5.2 资源利用率
  • 优化资源分配 :如果希望优化资源利用率,将 Pod 调度到具有合适资源的节点上,可以使用 Node affinity 或 nodeSelector 根据节点的资源标签进行调度。
  • 处理资源压力 :当节点出现资源压力(如内存压力、磁盘压力等)时,可以使用 Taints and tolerations 来隔离受影响的节点,避免 Pod 被调度到这些节点上。
5.3 应用的特性和需求
  • 对延迟敏感的应用 :对于对延迟敏感的应用,可以使用 Node affinity 或 Pod affinity 来确保 Pod 被调度到与相关服务或数据存储在同一节点或同一区域的节点上,以减少网络延迟。
  • 特殊硬件需求 :如果应用需要特殊硬件(如 GPU、FPGA 等),可以使用 nodeSelector 或 Node affinity 将 Pod 调度到具有相应硬件的节点上。
6. 常见问题及解决方案

在使用这些调度技术时,可能会遇到一些常见问题,以下是一些解决方案:

6.1 Pod 无法调度
  • 原因 :可能是由于 nodeSelector 或 Node affinity 规则设置不合理,导致没有节点满足调度要求;或者是节点上的污点没有对应的容忍度。
  • 解决方案 :检查 nodeSelector 、 Node affinity 规则和 Taints and tolerations 配置,确保规则合理且节点标签和污点设置正确。可以使用 kubectl describe pod 命令查看 Pod 的调度事件,找出问题所在。
6.2 调度效率低下
  • 原因 :可能是由于调度规则过于复杂,导致调度器需要花费大量时间来评估节点;或者是集群中节点资源不均衡,导致调度器难以找到合适的节点。
  • 解决方案 :简化调度规则,避免使用过于复杂的 Node affinity 规则;对集群中的节点进行资源均衡,确保节点资源分布合理。
6.3 驱逐循环问题
  • 原因 :在使用 Taints and tolerations 时,如果只设置了 NoExecute 污点而没有设置 NoSchedule 污点,可能会导致 Pod 被驱逐后又被重新调度到该节点上,形成驱逐循环。
  • 解决方案 :在使用 NoExecute 污点时,同时设置 NoSchedule 污点,避免 Pod 被重新调度到受影响的节点上。
7. 总结与展望

通过本文的介绍,我们了解了三种高级的 Pod 调度技术: nodeSelector 、 Node affinity 和 Taints and tolerations 。这些技术为我们在 Kubernetes 集群中调度 Pod 提供了更多的灵活性和控制能力。

在实际应用中,我们应该根据具体的需求和场景选择合适的调度技术。对于简单的调度需求,可以使用 nodeSelector ;对于需要更精细控制的场景,可以使用 Node affinity ;而当需要处理节点的特殊限制时, Taints and tolerations 则是一个很好的选择。

随着 Kubernetes 的不断发展,未来可能会出现更多高级的调度技术和功能,以满足日益复杂的应用需求。我们需要不断学习和掌握这些新技术,以优化我们的集群资源利用率和应用性能。

同时,我们也应该注意在使用这些调度技术时的一些常见问题,并采取相应的解决方案,以确保 Pod 能够稳定、高效地运行在 Kubernetes 集群中。

附录:常用命令总结

为了方便大家在实际操作中使用,以下是本文中涉及的常用命令总结:

操作 命令
为节点添加标签 kubectl label nodes <nodeName> <labelKey>=<labelValue>
验证节点标签 kubectl get nodes --show-labels
应用 Deployment 配置文件 kubectl apply -f <yamlFile>
查看 Pod 状态和节点分配 kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName"
为节点添加污点 kubectl taint node <nodeName> <key>=<value>:<effect>
移除节点上的污点 kubectl taint node <nodeName> <key>=<value>:<effect>-
重启 Deployment kubectl rollout restart deployment <deploymentName>

相关推荐

SPSS_Process—简单&平行&链式中介模型

本篇文章介绍采用SPSS的插件Process对简单中介、链式中介、平行中介模型进行检验的操作方法及结果解读。

m0_54401011的博客 4万+

1.深入浅出:理解三极管截止、放大和饱和状态!——参考《模拟电子技术基础》清华大学华成英主讲

幼儿园水平理解三极管截止、放大和饱和状态!书上看不懂,听课听不懂的过来! 绕不开的三极管结构 以NPN为例,晶体三极管的结构,这是很多人不想看的,但是确实是非常重要的!不看结构是理解不了工作原理的! (这样记忆:N是negative,负,代表多子为电子;P是positive,正,代表多子为空穴) 注意观察三极管的结构,有助于理解工作时的状态。 两张图结合起来看,略作解释: 1.图中空心为空穴带正...

Hardware_harder的博客 4万+

在虚拟机上搭建FTP服务器

chroot_list_file=/etc/vsftpd/chroot_list # 对chroot_list下用户限制。[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf #打开配置文件。# 指定用户的shell: -s /usr/bin/nologin。# 在配置文件中找到以下几行代码, 去掉注释(去掉 "#"号)# 指定用户主目录:/data/ftp/ftpuser -M。(2)修改配置文件,路径/etc/vsftpd/ 下的文件。

weixin_70753380的博客 3211

格拉姆角场(GAF)实战:用Python实现时间序列图像化处理

本文深入解析了格拉姆角场(GAF)技术,这是一种将一维时间序列转化为二维图像特征的方法,以便利用卷积神经网络(CNN)等图像模型进行深度分析。文章通过Python实战代码,详细演示了GASF和GADF两种核心转换的实现过程,并探讨了其在时序数据分类任务中的应用,为故障预警、金融模式识别等场景提供了强大的图像驱动分析视角。

weixin_29079671的博客 275

AMDGPU SVM VRAM Migration 实现详解

AMD正在基于DRM SVM框架重构SVM实现,该框架即将广泛应用。本文分析了AMD开发者提交的POC验证版本的技术方案。该架构分为三层:AMDGPU SVM映射层、DRM Pagemap通用框架层和AMDGPU迁移后端硬件驱动层。系统涉及三个地址空间转换:VRAM分配器空间、HPA/PFN空间和GPU PTE地址空间。关键数据结构包括设备级迁移基础设施amdgpu_pagemap、迁移临时BO包装器amdgpu_svm_bo等。该方案通过地址空间转换实现VRAM迁移功能,目前仍处于POC阶段,设计可能变更

图形/计算GPU的驱动与虚拟化技术分享园地 871

4、接收天线:接收电压、功率和传输系数

本文详细探讨了接收天线的性能参数,包括接收电压、功率和传输系数,通过建立等效电路模型分析接收偶极子的电流和开路电压,并定义电压和功率传输函数。研究揭示了天线长度、工作频率及极化失配对传输性能的影响,并提出了优化接收天线性能的策略,为天线系统的设计与优化提供了理论支持。

ll5678的博客 235

5分钟用AI搞定顶刊级引言!掌握三段式结构+避坑要点,让你的Introduction更有说服力(附提示词)

说明你是怎么来填补这个缺口的,一句话概括你的研究,再简述你采用了什么新方法、新模型或新视角,也就是创新点,最后说明你的方案是怎么克服第二段提到的缺口的,带来了哪些贡献,注意要确保方案与第二段提到的缺口一一对应。以上三段式引言模板,是非常经典的问题导向型结构,相比传统的结构,这种结构更能吸引是审稿人的注意,希望这篇分享的模板能给在你写论文引言时,提供一点帮助。上一段写好后,就在前人研究的基础上,亮出自己的方案,借助AI说明自己的研究,用了什么新方法/框架/理论/视角来填补这个缺口的。

智能AI让学术科研更容易 747

智能能效管家:基于 ESP32 的智能插座设计与精细化功耗管理实现

针对传统插座无法远程控制、功耗监测缺失、能源浪费严重等问题,本文设计一款基于 ESP32 主控芯片的智能插座。该系统集成 WiFi 无线通信、交流功耗采集、继电器通断控制模块,实现四大核心功能。硬件采用模块化选型与安全接线设计,软件基于 Arduino-ESP32 框架开发,搭载 Mqtt 通信协议与功耗算法,可通过手机 / 云端实时管控设备,有效提升用电安全性与能源利用率。:ESP32;智能插座;功耗管理;远程控制;能耗监测。

weixin_42300449的博客 101

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: 49、飞轮笼摩擦故障识别与转子不平衡测量可追溯性研究
下一篇: 49、NIS与NFS的安全、管理及应用解析
vim8coder
博客等级 码龄1天 0粉丝 1693原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值