昄依三宝 發表於 2025-12-22 15:15:46

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

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">实验目的</a></li><li><a href="#_label1">实验环境</a></li><li><a href="#_label2">实验步骤</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">步骤 1:查看集群节点信息</a></li><li><a href="#_lab2_2_1">步骤 2:使用nodeName调度 Pod</a></li><li><a href="#_lab2_2_2">步骤 3:使用nodeSelector调度 Pod</a></li><li><a href="#_lab2_2_3">步骤 4:使用节点亲和性(nodeAffinity)调度 Pod</a></li><li><a href="#_lab2_2_4">步骤 5:使用 Pod 亲和性与反亲和性调度 Pod</a></li><ul class="third_class_ul"><li><a href="#_label3_2_4_0">关键点解释</a></li></ul><li><a href="#_lab2_2_5">步骤 6:使用污点与容忍调度 Pod</a></li><ul class="third_class_ul"></ul><li><a href="#_lab2_2_6">步骤 7:使用调度优先级(Priority Classes)调度 Pod</a></li><ul class="third_class_ul"></ul><li><a href="#_lab2_2_7">步骤 8:清理实验环境</a></li><ul class="third_class_ul"></ul></ul><li><a href="#_label3">实验总结</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>实验目的</h2>
<p>通过实际操作,理解 Kubernetes 调度机制的核心原理和常用调度策略的配置方法,包括节点选择、亲和性与反亲和性、污点与容忍等。</p>
<p class="maodian"><a name="_label1"></a></p><h2>实验环境</h2>
<ul><li>Kubernetes 集群(至少包含一个 Master 节点和两个 Worker 节点)。</li><li>kubectl 命令行工具。</li><li>Docker 镜像(如 <code>nginx</code> 或其他简单应用镜像)。</li></ul>
<p class="maodian"><a name="_label2"></a></p><h2>实验步骤</h2>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>步骤 1:查看集群节点信息</h3>
<p><strong>目的</strong>:了解集群中可用的节点及其状态。</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get nodes -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">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&lt;none&gt;      Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12
k8s-node1    Ready    &lt;none&gt;          1d    v1.28.0   192.168.1.11&lt;none&gt;      Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12
k8s-node2    Ready    &lt;none&gt;          1d    v1.28.0   192.168.1.12&lt;none&gt;      Ubuntu 22.04   5.15.0-46-generic   docker://20.10.12</pre></div>
<p><strong>说明</strong>:确保所有节点状态为 <code>Ready</code>,表示集群正常运行。</p>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>步骤 2:使用nodeName调度 Pod</h3>
<p><strong>目的</strong>:理解 <code>nodeName</code> 的作用,即直接指定 Pod 调度到特定节点。</p>
<p><strong>创建 Pod 配置文件</strong> (<code>pod-nodeName.yaml</code>):</p>
<div class="jb51code"><pre class="brush:yaml;">apiVersion: v1
kind: Pod
metadata:
name: pod-node1
spec:
nodeName: k8s-node1
containers:
- name: nginx
    image: nginx</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-nodeName.yaml</pre></div>
<p><strong>验证 Pod 是否运行在指定节点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060792.png" /></p>
<p><strong>说明</strong>:<code>nodeName</code> 是最简单的调度方式,适用于调试或测试场景。</p>
<p class="maodian"><a name="_lab2_2_2"></a></p><h3>步骤 3:使用nodeSelector调度 Pod</h3>
<p><strong>目的</strong>:理解 <code>nodeSelector</code> 的作用,即通过节点标签选择目标节点。</p>
<p><strong>为节点添加标签</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl label nodes k8s-node1 disk=ssd
kubectl label nodes k8s-node2 disk=hdd</pre></div>
<p><strong>创建 Pod 配置文件</strong> (<code>pod-nodeSelector.yaml</code>):</p>
<div class="jb51code"><pre class="brush:yaml;">apiVersion: v1
kind: Pod
metadata:
name: pod-ssd
spec:
nodeSelector:
    disk: ssd
containers:
- name: nginx
    image: nginx</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-nodeSelector.yaml</pre></div>
<p><strong>验证 Pod 是否运行在带有指定标签的节点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060889.png" /></p>
<p><strong>说明</strong>:<code>nodeSelector</code> 是基于节点标签的调度方式,适用于根据节点特性(如硬件类型)进行调度。</p>
<p class="maodian"><a name="_lab2_2_3"></a></p><h3>步骤 4:使用节点亲和性(nodeAffinity)调度 Pod</h3>
<p><strong>目的</strong>:理解节点亲和性的作用,即通过复杂的标签匹配规则选择目标节点。</p>
<div class="jb51code"><pre class="brush:bash;">kubectl label pod pod-node-affinity role=frontend</pre></div>
<p><strong>创建 Pod 配置文件</strong> (<code>pod-nodeAffinity.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>pod-node-affinity</code> 的 Pod,并通过节点亲和性规则将它调度到带有 <code>disk=ssd</code> 标签的节点上</p>
<div class="jb51code"><pre class="brush:yaml;">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 镜像。</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-nodeAffinity.yaml</pre></div>
<p><strong>验证 Pod 是否运行在符合条件的节点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<ul><li><strong>输出示例</strong>:</li></ul>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060765.png" /></p>
<p><strong>说明</strong>:节点亲和性比 <code>nodeSelector</code> 更灵活,支持复杂的匹配规则。</p>
<p class="maodian"><a name="_lab2_2_4"></a></p><h3>步骤 5:使用 Pod 亲和性与反亲和性调度 Pod</h3>
<p><strong>目的</strong>:理解 Pod 亲和性与反亲和性的作用,即通过 Pod 标签选择调度位置。</p>
<div class="jb51code"><pre class="brush:bash;">kubectl label pod pod-node-affinity role=frontend</pre></div>
<p><strong>创建带有亲和性的 Pod 配置文件</strong> (<code>pod-affinity.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>pod-affinity</code> 的 Pod,并通过 <strong>Pod 亲和性</strong> 规则将它调度到与已存在的、带有 <code>role=frontend</code> 标签的 Pod 相同的节点上。</p>
<p class="maodian"><a name="_label3_2_4_0"></a></p><h4>关键点解释</h4>
<div class="jb51code"><pre class="brush:yaml;">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 镜像。</pre></div>
<p><strong>创建带有反亲和性的 Pod 配置文件</strong> (<code>pod-antiAffinity.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>pod-anti-affinity</code> 的 Pod,并通过 <strong>Pod 反亲和性</strong> 规则将其调度到与带有 <code>role=frontend</code> 标签的 Pod <strong>不同</strong> 的节点上。</p>
<div class="jb51code"><pre class="brush:bash;">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 镜像。</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-affinity.yaml
kubectl apply -f pod-antiAffinity.yaml</pre></div>
<p><strong>验证 Pod 是否运行在符合条件的位置</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060745.png" /></p>
<p><strong>说明</strong>:Pod 亲和性用于将 Pod 调度到与指定 Pod 相同的节点,而 Pod 反亲和性用于避免将 Pod 调度到与指定 Pod 相同的节点。</p>
<p class="maodian"><a name="_lab2_2_5"></a></p><h3>步骤 6:使用污点与容忍调度 Pod</h3>
<p><strong>目的</strong>:理解污点与容忍的作用,即通过节点上的污点限制 Pod 调度,并通过容忍允许 Pod 调度到带有特定污点的节点。</p>
<p><strong>为节点添加污点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl taint nodes k8s-node1 special=true:NoSchedule</pre></div>
<p><strong>创建带有容忍的 Pod 配置文件</strong> (<code>pod-tolerations.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>pod-tolerations</code> 的 Pod,并通过 <strong>容忍(Tolerations)</strong> 规则使其能够被调度到带有特定污点(<code>special=true:NoSchedule</code>)的节点上。</p>
<div class="jb51code"><pre class="brush:bash;">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" 污点。</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-tolerations.yaml</pre></div>
<p><strong>验证 Pod 是否运行在带有污点的节点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060794.png" /></p>
<p><strong>说明</strong>:污点与容忍用于实现灵活的调度策略,例如隔离特殊节点或允许 Pod 调度到带有特定污点的节点。</p>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>步骤 7:使用调度优先级(Priority Classes)调度 Pod</h3>
<p><strong>目的</strong>:理解调度优先级的作用,即为 Pod 分配优先级,高优先级的 Pod 优先调度。</p>
<p><strong>创建优先级类</strong> (<code>priority-class.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>high-priority</code> 的 <strong>优先级类(PriorityClass)</strong>,其优先级值为 <code>1000000</code>。</p>
<p>优先级类用于定义 Pod 的调度优先级,调度器会根据 Pod 的优先级来决定调度顺序</p>
<div class="jb51code"><pre class="brush:bash;">apiVersion: scheduling.k8s.io/v1# 指定使用的 Kubernetes API 版本,这里使用的是 scheduling.k8s.io/v1,适用于优先级类。
kind: PriorityClass               # 指定资源类型为 PriorityClass,用于定义 Pod 的优先级。
metadata:                         # 定义优先级类的元数据。
name: high-priority             # 优先级类的名称,用于标识这个优先级类。
value: 1000000                  # 定义优先级的数值,数值越大,优先级越高。这里设置为 1000000,表示这是一个高优先级。</pre></div>
<p><strong>应用优先级类</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f priority-class.yaml</pre></div>
<p><strong>创建带有高优先级的 Pod 配置文件</strong> (<code>pod-priority.yaml</code>):</p>
<p>这个配置文件的目的是创建一个名为 <code>pod-priority</code> 的 Pod,并为其设置一个高优先级。调度器在调度 Pod 时会根据其优先级进行排序,优先级高的 Pod 会优先调度。如果集群资源有限,高优先级的 Pod 甚至可以抢占低优先级的 Pod。</p>
<div class="jb51code"><pre class="brush:bash;">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 镜像。</pre></div>
<p><strong>应用配置文件</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl apply -f pod-priority.yaml</pre></div>
<p><strong>验证 Pod 是否优先调度</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl get pods -o wide</pre></div>
<p><strong>输出示例</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202512/2025122215060857.png" /></p>
<p><strong>说明</strong>:调度优先级允许为 Pod 分配优先级,高优先级的 Pod 会优先调度。</p>
<p class="maodian"><a name="_lab2_2_7"></a></p><h3>步骤 8:清理实验环境</h3>
<p><strong>目的</strong>:清理实验中创建的资源,恢复集群的初始状态。</p>
<p><strong>删除创建的 Pod</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl delete pod pod-node1 pod-ssd pod-node-affinity pod-anti-affinity pod-tolerations pod-priority</pre></div>
<p><strong>删除优先级类</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl delete priorityclass high-priority</pre></div>
<p><strong>删除节点标签和污点</strong>:</p>
<div class="jb51code"><pre class="brush:bash;">kubectl label nodes k8s-node1 disk-
kubectl label nodes k8s-node2 disk-
kubectl taint nodes k8s-node1 special:NoSchedule-</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>实验总结</h2>
<p>通过以上实验,我们详细验证了 Kubernetes 调度机制的核心原理和常用调度策略的实际应用。以下是关键知识点的总结:</p>
<p><strong><span>调度器的作用</span></strong>:将 Pod 分配到合适的节点,确保资源合理利用和应用高可用性。</p>
<p><strong><span>调度方法</span></strong><span>:</span></p>
<ul><li><strong>nodeName</strong>:直接指定节点,适用于调试或测试。</li><li><strong>nodeSelector</strong>:通过节点标签选择目标节点,适用于根据硬件类型或地理位置调度。</li><li><strong>节点亲和性(nodeAffinity)</strong>:支持复杂的标签匹配规则,更灵活。</li><li><strong>Pod 亲和性与反亲和性(podAffinity/podAntiAffinity)</strong>:根据 Pod 标签选择调度位置。</li><li><strong>污点与容忍(Taints &amp; Tolerations)</strong>:通过污点限制调度,并通过容忍允许调度到带有特定污点的节点。</li><li><strong>调度优先级(Priority Classes)</strong>:为 Pod 分配优先级,高优先级的 Pod 优先调度。</li></ul>
<ol><li><strong>调度器优化</strong>:通过调整调度策略文件或参数优化调度器性能。</li><li><strong>监控调度器</strong>:使用 Prometheus 和 Grafana 监控调度器性能指标。</li></ol>
<p>通过实践这些调度策略,你可以根据应用需求优化 Kubernetes 集群的资源分配和应用部署。</p>
<p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持琼殿技术社区。</p>
頁: [1]
查看完整版本: Kubernetes调度机制与策略实验详解