云其它

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > 云其它 > Kubernetes调度机制与策略实验

Kubernetes调度机制与策略实验详解

作者:π大星星️

本文通过实际操作,详细介绍了Kubernetes调度机制的核心原理和常用调度策略的配置方法,包括节点选择、亲和性与反亲和性、污点与容忍等,实验环境为Kubernetes集群,并通过一系列步骤验证了这些调度策略的实际应用

实验目的

通过实际操作,理解 Kubernetes 调度机制的核心原理和常用调度策略的配置方法,包括节点选择、亲和性与反亲和性、污点与容忍等。

实验环境

实验步骤

步骤 1:查看集群节点信息

目的:了解集群中可用的节点及其状态。

kubectl get nodes -o wide

输出示例

NAME         STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION   CONTAINER-RUNTIME
k8s-master   Ready    control-plane   1d    v1.28.0   192.168.1.10  <none>        Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12
k8s-node1    Ready    <none>          1d    v1.28.0   192.168.1.11  <none>        Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12
k8s-node2    Ready    <none>          1d    v1.28.0   192.168.1.12  <none>        Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12

说明:确保所有节点状态为 Ready,表示集群正常运行。

步骤 2:使用nodeName调度 Pod

目的:理解 nodeName 的作用,即直接指定 Pod 调度到特定节点。

创建 Pod 配置文件 (pod-nodeName.yaml):

apiVersion: v1
kind: Pod
metadata:
  name: pod-node1
spec:
  nodeName: k8s-node1
  containers:
  - name: nginx
    image: nginx

应用配置文件

kubectl apply -f pod-nodeName.yaml

验证 Pod 是否运行在指定节点

kubectl get pods -o wide

输出示例

说明nodeName 是最简单的调度方式,适用于调试或测试场景。

步骤 3:使用nodeSelector调度 Pod

目的:理解 nodeSelector 的作用,即通过节点标签选择目标节点。

为节点添加标签

kubectl label nodes k8s-node1 disk=ssd
kubectl label nodes k8s-node2 disk=hdd

创建 Pod 配置文件 (pod-nodeSelector.yaml):

apiVersion: v1
kind: Pod
metadata:
  name: pod-ssd
spec:
  nodeSelector:
    disk: ssd
  containers:
  - name: nginx
    image: nginx

应用配置文件

kubectl apply -f pod-nodeSelector.yaml

验证 Pod 是否运行在带有指定标签的节点

kubectl get pods -o wide

输出示例

说明nodeSelector 是基于节点标签的调度方式,适用于根据节点特性(如硬件类型)进行调度。

步骤 4:使用节点亲和性(nodeAffinity)调度 Pod

目的:理解节点亲和性的作用,即通过复杂的标签匹配规则选择目标节点。

kubectl label pod pod-node-affinity role=frontend

创建 Pod 配置文件 (pod-nodeAffinity.yaml):

这个配置文件的目的是创建一个名为 pod-node-affinity 的 Pod,并通过节点亲和性规则将它调度到带有 disk=ssd 标签的节点上

apiVersion: v1  # 指定 Kubernetes API 的版本,这里使用的是 v1 版本。
kind: Pod       # 指定资源类型,这里是 Pod。
metadata:       # 定义 Pod 的元数据,包括名称、标签等。
  name: pod-node-affinity  # Pod 的名称,用于标识这个 Pod。
spec:           # 定义 Pod 的规格,包括调度策略和容器配置。
  affinity:     # 定义 Pod 的亲和性规则,用于控制调度行为。
    nodeAffinity:  # 节点亲和性规则,用于根据节点的标签选择目标节点。
      requiredDuringSchedulingIgnoredDuringExecution:  # 必须满足的节点亲和性约束。
        nodeSelectorTerms:  # 定义节点选择条件的列表,调度器会检查这些条件。
        - matchExpressions:  # 定义匹配表达式,用于匹配节点标签。
          - key: disk  # 节点标签的键,这里匹配节点的 "disk" 标签。
            operator: In  # 操作符,表示 "包含在",即节点的 "disk" 标签值必须在 values 列表中。
            values:  # 定义允许的标签值列表。
            - ssd  # 允许的标签值之一,表示节点的 "disk" 标签值为 "ssd"。
  containers:  # 定义 Pod 中的容器列表。
  - name: nginx  # 容器的名称,这里是 "nginx"。
    image: nginx  # 容器使用的镜像,这里是官方的 nginx 镜像。

应用配置文件

kubectl apply -f pod-nodeAffinity.yaml

验证 Pod 是否运行在符合条件的节点

kubectl get pods -o wide

说明:节点亲和性比 nodeSelector 更灵活,支持复杂的匹配规则。

步骤 5:使用 Pod 亲和性与反亲和性调度 Pod

目的:理解 Pod 亲和性与反亲和性的作用,即通过 Pod 标签选择调度位置。

kubectl label pod pod-node-affinity role=frontend

创建带有亲和性的 Pod 配置文件 (pod-affinity.yaml):

这个配置文件的目的是创建一个名为 pod-affinity 的 Pod,并通过 Pod 亲和性 规则将它调度到与已存在的、带有 role=frontend 标签的 Pod 相同的节点上。

关键点解释

apiVersion: v1  # 指定 Kubernetes API 的版本,这里使用的是 v1 版本。
kind: Pod       # 指定资源类型为 Pod。
metadata:       # 定义 Pod 的元数据。
  name: pod-affinity  # Pod 的名称,用于标识这个 Pod。
  labels:       # Pod 的标签,用于标识 Pod 的角色或其他属性。
    role: frontend   # 定义一个标签,键为 "role",值为 "frontend"。
spec:           # 定义 Pod 的规格,包括调度策略和容器配置。
  affinity:     # 定义 Pod 的亲和性规则。
    podAffinity:  # 定义 Pod 亲和性规则,用于根据其他 Pod 的标签选择调度位置。
      requiredDuringSchedulingIgnoredDuringExecution:  # 必须满足的 Pod 亲和性约束。
      - labelSelector:  # 定义用于选择目标 Pod 的标签选择器。
          matchExpressions:  # 定义匹配表达式,用于匹配目标 Pod 的标签。
          - key: role  # 目标 Pod 的标签键,这里匹配 "role" 标签。
            operator: In  # 操作符,表示 "包含在",即目标 Pod 的 "role" 标签值必须在 values 列表中。
            values:  # 定义允许的标签值列表。
            - frontend  # 允许的标签值之一,表示目标 Pod 的 "role" 标签值为 "frontend"。
        topologyKey: kubernetes.io/hostname  # 定义亲和性约束的拓扑域,这里是节点的主机名。
  containers:  # 定义 Pod 中的容器列表。
  - name: nginx  # 容器的名称,这里是 "nginx"。
    image: nginx  # 容器使用的镜像,这里是官方的 nginx 镜像。

创建带有反亲和性的 Pod 配置文件 (pod-antiAffinity.yaml):

这个配置文件的目的是创建一个名为 pod-anti-affinity 的 Pod,并通过 Pod 反亲和性 规则将其调度到与带有 role=frontend 标签的 Pod 不同 的节点上。

apiVersion: v1  # 指定使用的 Kubernetes API 版本为 v1。
kind: Pod       # 指定资源类型为 Pod。
metadata:       # 定义 Pod 的元数据,包括名称和标签。
  name: pod-anti-affinity  # Pod 的名称,用于标识这个 Pod。
  labels:       # 定义 Pod 的标签。
    role: backend  # 为 Pod 添加一个标签,键为 "role",值为 "backend"。
spec:           # 定义 Pod 的规格,包括容器配置和调度策略。
  affinity:     # 定义 Pod 的亲和性规则。
    podAntiAffinity:  # 定义 Pod 的反亲和性规则。
      requiredDuringSchedulingIgnoredDuringExecution:  # 定义必须满足的反亲和性约束。
      - labelSelector:  # 定义用于选择目标 Pod 的标签选择器。
          matchExpressions:  # 定义匹配表达式,用于匹配目标 Pod 的标签。
          - key: role  # 目标 Pod 的标签键,这里匹配 "role" 标签。
            operator: In  # 操作符,表示 "包含在",即目标 Pod 的 "role" 标签值必须在 values 列表中。
            values:  # 定义允许的标签值列表。
            - frontend  # 允许的标签值之一,表示目标 Pod 的 "role" 标签值为 "frontend"。
        topologyKey: kubernetes.io/hostname  # 定义反亲和性约束的拓扑域,这里是节点的主机名。
  containers:  # 定义 Pod 中的容器列表。
  - name: nginx  # 定义容器的名称,这里是 "nginx"。
    image: nginx  # 定义容器使用的镜像,这里是官方的 nginx 镜像。

应用配置文件

kubectl apply -f pod-affinity.yaml
kubectl apply -f pod-antiAffinity.yaml

验证 Pod 是否运行在符合条件的位置

kubectl get pods -o wide

输出示例

说明:Pod 亲和性用于将 Pod 调度到与指定 Pod 相同的节点,而 Pod 反亲和性用于避免将 Pod 调度到与指定 Pod 相同的节点。

步骤 6:使用污点与容忍调度 Pod

目的:理解污点与容忍的作用,即通过节点上的污点限制 Pod 调度,并通过容忍允许 Pod 调度到带有特定污点的节点。

为节点添加污点

kubectl taint nodes k8s-node1 special=true:NoSchedule

创建带有容忍的 Pod 配置文件 (pod-tolerations.yaml):

这个配置文件的目的是创建一个名为 pod-tolerations 的 Pod,并通过 容忍(Tolerations) 规则使其能够被调度到带有特定污点(special=true:NoSchedule)的节点上。

apiVersion: v1  # 指定 Kubernetes API 的版本,这里使用的是 v1。
kind: Pod       # 指定资源类型为 Pod。
metadata:       # 定义 Pod 的元数据。
  name: pod-tolerations  # Pod 的名称,用于标识这个 Pod。
spec:           # 定义 Pod 的规格,包括容器配置和调度策略。
  containers:   # 定义 Pod 中的容器列表。
  - name: nginx  # 容器的名称,这里是 "nginx"。
    image: nginx  # 容器使用的镜像,这里是官方的 nginx 镜像。
  tolerations:  # 定义 Pod 的容忍(Tolerations)规则。
  - key: "special"  # 容忍的键,表示节点上污点的键。
    operator: "Equal"  # 操作符,表示容忍的条件是键值对相等。
    value: "true"  # 容忍的值,表示节点上污点的值。
    effect: "NoSchedule"  # 容忍的效果,表示容忍节点上的 "NoSchedule" 污点。

应用配置文件

kubectl apply -f pod-tolerations.yaml

验证 Pod 是否运行在带有污点的节点

kubectl get pods -o wide

输出示例

说明:污点与容忍用于实现灵活的调度策略,例如隔离特殊节点或允许 Pod 调度到带有特定污点的节点。

步骤 7:使用调度优先级(Priority Classes)调度 Pod

目的:理解调度优先级的作用,即为 Pod 分配优先级,高优先级的 Pod 优先调度。

创建优先级类 (priority-class.yaml):

这个配置文件的目的是创建一个名为 high-priority优先级类(PriorityClass),其优先级值为 1000000

优先级类用于定义 Pod 的调度优先级,调度器会根据 Pod 的优先级来决定调度顺序

apiVersion: scheduling.k8s.io/v1  # 指定使用的 Kubernetes API 版本,这里使用的是 scheduling.k8s.io/v1,适用于优先级类。
kind: PriorityClass               # 指定资源类型为 PriorityClass,用于定义 Pod 的优先级。
metadata:                         # 定义优先级类的元数据。
  name: high-priority             # 优先级类的名称,用于标识这个优先级类。
value: 1000000                    # 定义优先级的数值,数值越大,优先级越高。这里设置为 1000000,表示这是一个高优先级。

应用优先级类

kubectl apply -f priority-class.yaml

创建带有高优先级的 Pod 配置文件 (pod-priority.yaml):

这个配置文件的目的是创建一个名为 pod-priority 的 Pod,并为其设置一个高优先级。调度器在调度 Pod 时会根据其优先级进行排序,优先级高的 Pod 会优先调度。如果集群资源有限,高优先级的 Pod 甚至可以抢占低优先级的 Pod。

apiVersion: v1  # 指定 Kubernetes API 的版本,这里使用的是 v1,适用于 Pod 资源。
kind: Pod       # 指定资源类型为 Pod,即 Kubernetes 中的最小部署单元。
metadata:       # 定义 Pod 的元数据,包括名称和其他标识信息。
  name: pod-priority  # Pod 的名称,用于标识这个 Pod。在同一个命名空间中,Pod 的名称必须是唯一的。
spec:           # 定义 Pod 的规格,包括容器配置和调度策略。
  priorityClassName: high-priority  # 引用一个名为 "high-priority" 的优先级类(PriorityClass)。
                                    # 这个优先级类必须已经存在于集群中,否则 Pod 无法正常调度。
                                    # 优先级类定义了 Pod 的调度优先级,数值越高,优先级越高。
  containers:   # 定义 Pod 中的容器列表,一个 Pod 可以包含一个或多个容器。
  - name: nginx  # 定义容器的名称,这里是 "nginx"。
    image: nginx  # 定义容器使用的镜像,这里是官方的 nginx 镜像。

应用配置文件

kubectl apply -f pod-priority.yaml

验证 Pod 是否优先调度

kubectl get pods -o wide

输出示例

说明:调度优先级允许为 Pod 分配优先级,高优先级的 Pod 会优先调度。

步骤 8:清理实验环境

目的:清理实验中创建的资源,恢复集群的初始状态。

删除创建的 Pod

kubectl delete pod pod-node1 pod-ssd pod-node-affinity pod-anti-affinity pod-tolerations pod-priority

删除优先级类

kubectl delete priorityclass high-priority

删除节点标签和污点

kubectl label nodes k8s-node1 disk-
kubectl label nodes k8s-node2 disk-
kubectl taint nodes k8s-node1 special:NoSchedule-

实验总结

通过以上实验,我们详细验证了 Kubernetes 调度机制的核心原理和常用调度策略的实际应用。以下是关键知识点的总结:

调度器的作用:将 Pod 分配到合适的节点,确保资源合理利用和应用高可用性。

调度方法

  1. 调度器优化:通过调整调度策略文件或参数优化调度器性能。
  2. 监控调度器:使用 Prometheus 和 Grafana 监控调度器性能指标。

通过实践这些调度策略,你可以根据应用需求优化 Kubernetes 集群的资源分配和应用部署。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文