这是K8s中最核心、最实用的实验之一,直接决定了你能否在生产环境中精准控制Pod的运行位置。所有的高可用部署、资源隔离、性能优化都离不开这些调度策略。我会按照**“概念→实验步骤→原理→生产实践”**的逻辑,把每个知识点讲透。

一、实验核心目标

通过亲手操作,彻底搞懂:

  1. 标签(Label) 是什么,为什么它是K8s所有调度和管理的基础
  2. 如何用nodeName和nodeSelector实现简单的节点调度
  3. 节点亲和性、Pod亲和性、Pod反亲和性的区别和使用场景
  4. 污点(Taint)和容忍度(Toleration) 的工作原理,如何实现节点的主动排斥
  5. Pod的常见状态重启策略,以及如何排查Pod调度失败的问题

二、实验前置准备

✅ 已经完成K8s集群搭建(1个master+2个worker节点)
✅ 所有节点状态为Ready
✅ Calico网络插件正常运行
✅ 已经导入以下镜像到所有worker节点:

  • tomcat:8.5-jre8-alpine
  • busybox:latest
  • ikubernetes/myapp:v1

三、实验分步详解

实验1:标签(Label)的基本操作

标签是K8s的灵魂,所有的资源管理和调度都是基于标签实现的。

1. 什么是标签?

大白话解释
标签就是给K8s资源(Pod、Node、Service等)打上的**“便签”**,是一个键值对(key=value)。你可以给任何资源打任意数量的标签,然后通过标签来筛选和管理这些资源。

典型应用场景

  • 给Pod打标签:app=tomcatenv=prodversion=v1
  • 给Node打标签:disk=ssdzone=beijinggpu=true
  • 然后通过标签选择器,把Pod调度到符合条件的节点上
2. 标签的基本操作
# 1. 创建一个测试Pod
kubectl apply -f pod-first.yaml

# 2. 给已经存在的Pod打标签
kubectl label pods tomcat-test release=v1

# 3. 查看Pod的标签
kubectl get pods tomcat-test --show-labels

# 4. 查看所有Pod的标签
kubectl get pods --show-labels

# 5. 筛选带有特定标签的Pod
# 筛选有release标签的Pod
kubectl get pods -l release
# 筛选release标签值为v1的Pod
kubectl get pods -l release=v1
# 筛选release标签值不为v1的Pod
kubectl get pods -l release!=v1

# 6. 同时筛选多个标签
kubectl get pods -l app=tomcat,release=v1

# 7. 修改标签
kubectl label pods tomcat-test release=v2 --overwrite

# 8. 删除标签
kubectl label pods tomcat-test release-

重要结论
标签是非唯一的,多个资源可以有相同的标签。通过标签,K8s可以将资源进行逻辑分组,实现灵活的管理和调度。


实验2:节点选择器(Node Selector)

节点选择器是最简单的Pod调度方式,它可以让Pod只运行在符合特定标签的节点上。

1. nodeName:直接指定节点

nodeName是最直接的调度方式,直接指定Pod要运行在哪个节点上。

实验步骤

  1. 创建pod-node.yaml文件:
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  labels:
    app: myapp
spec:
  nodeName: xianchaonode1  # 直接指定Pod运行在xianchaonode1上
  containers:
  - name: tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh", "-c", "sleep 3600"]
  1. 创建Pod并查看调度结果:
kubectl apply -f pod-node.yaml
kubectl get pods -o wide

你会看到

NAME       READY   STATUS    RESTARTS   AGE   IP              NODE            
demo-pod   2/2     Running   0          10s   10.244.121.45   xianchaonode1   

Pod确实运行在了我们指定的xianchaonode1节点上。

缺点

  • 太死板,如果指定的节点不存在或者资源不足,Pod会调度失败
  • 不适合大规模集群
2. nodeSelector:基于标签选择节点

nodeSelectornodeName更灵活,它可以让Pod运行在所有带有特定标签的节点上。

实验步骤

  1. xianchaonode2节点打标签:
kubectl label nodes xianchaonode2 disk=ceph
  1. 查看节点标签:
kubectl get nodes --show-labels
  1. 创建pod-1.yaml文件:
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod-1
  labels:
    app: myapp
spec:
  nodeSelector:  # 选择带有disk=ceph标签的节点
    disk: ceph
  containers:
  - name: tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080
  1. 创建Pod并查看调度结果:
kubectl apply -f pod-1.yaml
kubectl get pods -o wide

你会看到

NAME         READY   STATUS    RESTARTS   AGE   IP              NODE            
demo-pod-1   1/1     Running   0          10s   10.244.102.79   xianchaonode2   

Pod运行在了带有disk=ceph标签的xianchaonode2节点上。

3. 同时使用nodeName和nodeSelector

如果同时指定了nodeNamenodeSelector,那么两个条件必须同时满足,否则Pod会调度失败。

实验验证

  1. 删除xianchaonode2的标签:
kubectl label nodes xianchaonode2 disk-
  1. 创建同时指定两者的Pod:
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod-2
  labels:
    app: myapp
spec:
  nodeName: xianchaonode2
  nodeSelector:
    disk: ceph
  containers:
  - name: tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  1. 查看Pod状态:
kubectl apply -f pod-2.yaml
kubectl describe pods demo-pod-2

你会看到报错

Warning  NodeAffinity  17s   kubelet  Predicate NodeAffinity failed

因为xianchaonode2现在没有disk=ceph标签,不满足nodeSelector的条件,所以调度失败。


实验3:亲和性(Affinity)

亲和性是比节点选择器更强大、更灵活的调度方式,它支持更复杂的逻辑表达式软/硬限制

亲和性分为三种:

  • 节点亲和性(Node Affinity):Pod倾向于运行在哪些节点上
  • Pod亲和性(Pod Affinity):Pod倾向于和哪些Pod运行在一起
  • Pod反亲和性(Pod Anti-Affinity):Pod倾向于不和哪些Pod运行在一起

每种亲和性又分为两种:

  • 硬亲和性(required):必须满足条件,否则Pod调度失败
  • 软亲和性(preferred):尽量满足条件,不满足也能调度
1. 节点亲和性(Node Affinity)

节点亲和性是nodeSelector的升级版,支持更复杂的匹配规则。

实验1:硬亲和性(requiredDuringSchedulingIgnoredDuringExecution)
硬亲和性表示必须满足条件,否则Pod无法调度。

  1. 创建pod-nodeaffinity-demo.yaml文件:
apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity-demo
  labels:
    app: myapp
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: zone
            operator: In
            values: 
            - foo
            - bar
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent

参数解释

  • requiredDuringSchedulingIgnoredDuringExecution:硬亲和性
  • nodeSelectorTerms:节点选择条件,多个条件之间是**或(OR)**的关系
  • matchExpressions:匹配表达式,多个表达式之间是**与(AND)**的关系
  • operator: In:标签值在指定的列表中
  • values: ["foo", "bar"]:标签值可以是foo或者bar
  1. 创建Pod并查看状态:
kubectl apply -f pod-nodeaffinity-demo.yaml
kubectl get pods -o wide

你会看到

NAME                     READY   STATUS    RESTARTS   AGE   IP       NODE            
pod-node-affinity-demo   0/1     Pending   0          10s   <none>   <none>

Pod处于Pending状态,因为没有任何节点带有zone=foozone=bar的标签,不满足硬亲和性的条件。

  1. xianchaonode1打标签:
kubectl label nodes xianchaonode1 zone=foo
  1. 再次查看Pod状态:
kubectl get pods -o wide

你会看到

NAME                     READY   STATUS    RESTARTS   AGE   IP              NODE            
pod-node-affinity-demo   1/1     Running   0          30s   10.244.121.46   xianchaonode1   

Pod现在成功调度到了xianchaonode1节点上。

实验2:软亲和性(preferredDuringSchedulingIgnoredDuringExecution)
软亲和性表示尽量满足条件,如果不满足,Pod也能调度到其他节点上。

  1. 创建pod-nodeaffinity-demo-2.yaml文件:
apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity-demo-2
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - preference:
          matchExpressions: 
          - key: zone1
            operator: In
            values:
            - foo1
            - bar1
        weight: 10
      - preference:
          matchExpressions:
          - key: zone2
            operator: In
            values:
            - foo2
            - bar2
        weight: 20

参数解释

  • preferredDuringSchedulingIgnoredDuringExecution:软亲和性
  • weight:权重,范围是1-100,权重越高,优先级越高
  1. 创建Pod并查看状态:
kubectl apply -f pod-nodeaffinity-demo-2.yaml
kubectl get pods -o wide

你会看到

NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE            
pod-node-affinity-demo-2   1/1     Running   0          10s   10.244.121.47   xianchaonode1   

虽然没有任何节点带有zone1zone2的标签,但是因为是软亲和性,所以Pod仍然可以调度。

  1. 验证权重:
# 给两个节点分别打标签
kubectl label nodes xianchaonode1 zone1=foo1
kubectl label nodes xianchaonode2 zone2=foo2

# 删除并重新创建Pod
kubectl delete -f pod-nodeaffinity-demo-2.yaml
kubectl apply -f pod-nodeaffinity-demo-2.yaml

# 查看调度结果
kubectl get pods -o wide

你会看到

NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE            
pod-node-affinity-demo-2   1/1     Running   0          10s   10.244.102.80   xianchaonode2   

Pod调度到了xianchaonode2节点上,因为zone2=foo2的权重(20)比zone1=foo1的权重(10)高。

2. Pod亲和性(Pod Affinity)

Pod亲和性表示一个Pod倾向于和另一个Pod运行在同一个拓扑域中

什么是拓扑域?
拓扑域是一个逻辑上的区域,可以是:

  • 一个节点(kubernetes.io/hostname)
  • 一个机架(rack)
  • 一个可用区(zone)
  • 一个地域(region)

通过topologyKey来指定拓扑域的标签,拓扑域即为node的标签的key,value由系统自动根据目标pod的所在进行查找。

实验:Pod硬亲和性

  1. 创建第一个Pod作为基准:
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app2: myapp2
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
kubectl apply -f pod-required-affinity-demo-1.yaml
kubectl get pods -o wide

假设第一个Pod调度到了xianchaonode2节点上,我们发现node2节点的标签是kubernetes.io/hostname。

  1. 创建第二个Pod,要求和第一个Pod运行在同一个节点上:
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["sh","-c","sleep 3600"]
    imagePullPolicy: IfNotPresent
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app2
            operator: In
            values: ["myapp2"]
        topologyKey: kubernetes.io/hostname

参数解释

  • podAffinity:Pod亲和性
  • labelSelector:选择要亲和的Pod
  • topologyKey: kubernetes.io/hostname:拓扑域是节点,即要求两个Pod运行在同一个节点上
  1. 创建第二个Pod并查看调度结果:
kubectl apply -f pod-required-affinity-demo-2.yaml
kubectl get pods -o wide

你会看到

NAME        READY   STATUS    RESTARTS   AGE   IP              NODE            
pod-first   1/1     Running   0          1m    10.244.102.81   xianchaonode2   
pod-second  1/1     Running   0          10s   10.244.102.82   xianchaonode2   

两个Pod确实运行在了同一个节点上。

3. Pod反亲和性(Pod Anti-Affinity)

Pod反亲和性表示一个Pod倾向于不和另一个Pod运行在同一个拓扑域中

实验:Pod硬反亲和性

  1. 创建第一个Pod作为基准:
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app1: myapp1
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
kubectl apply -f pod-required-anti-affinity-demo-1.yaml
kubectl get pods -o wide

假设第一个Pod调度到了xianchaonode1节点上。

  1. 创建第二个Pod,要求和第一个Pod运行在不同的节点上:
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["sh","-c","sleep 3600"]
    imagePullPolicy: IfNotPresent
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app1
            operator: In
            values: ["myapp1"]
        topologyKey: kubernetes.io/hostname
  1. 创建第二个Pod并查看调度结果:
kubectl apply -f pod-required-anti-affinity-demo-2.yaml
kubectl get pods -o wide

你会看到

NAME        READY   STATUS    RESTARTS   AGE   IP              NODE            
pod-first   1/1     Running   0          1m    10.244.121.48   xianchaonode1   
pod-second  1/1     Running   0          10s   10.244.102.83   xianchaonode2   

两个Pod运行在了不同的节点上。

生产实践
Pod反亲和性是实现高可用部署的核心技术。比如,你可以让同一个Deployment的多个Pod分散在不同的节点、不同的机架甚至不同的可用区,这样即使某个节点或机架故障,也不会影响整个应用的可用性。


实验4:污点(Taint)和容忍度(Toleration)

亲和性是Pod主动选择节点,而污点是节点主动排斥Pod

1. 什么是污点和容忍度?

大白话解释

  • 污点(Taint):给节点打上的一个"标记",表示这个节点有一些"特殊情况",会排斥那些不能容忍这些情况的Pod
  • 容忍度(Toleration):给Pod打上的一个"标记",表示这个Pod能够容忍节点的某些污点

污点的三种效果(Effect)

效果含义
NoSchedule硬限制:仅影响新调度的 Pod,无法容忍该污点的 Pod 不能调度到该节点已运行在节点上的 Pod 不受影响,不会被驱逐
PreferNoSchedule软限制:尽量不将无法容忍该污点的 Pod 调度到该节点;如果集群资源不足,允许调度
NoExecute强驱逐:既禁止无法容忍该污点的新 Pod 调度,已在节点上的无法容忍 Pod 会被立即驱逐
2. 查看节点的污点
# 查看master节点的污点
kubectl describe nodes xianchaomaster1 | grep Taints

输出

Taints:             node-role.kubernetes.io/control-plane:NoSchedule

这就是为什么普通Pod不会调度到master节点上的原因!master节点默认有一个NoSchedule类型的污点,而普通Pod没有对应的容忍度。

3. 给节点打污点
# 给xianchaonode2打污点,类型是NoSchedule
kubectl taint node xianchaonode2 node-type=production:NoSchedule
4. 验证污点的效果
  1. 创建一个普通Pod:
apiVersion: v1
kind: Pod
metadata:
  name: taint-pod
spec:
  containers:
  - name: tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
kubectl apply -f pod-taint.yaml
kubectl get pods -o wide

你会看到

NAME        READY   STATUS    RESTARTS   AGE   IP              NODE            
taint-pod   1/1     Running   0          10s   10.244.121.49   xianchaonode1   

Pod调度到了xianchaonode1节点上,因为xianchaonode2有污点,而这个Pod没有对应的容忍度。

  1. xianchaonode1NoExecute类型的污点:
kubectl taint node xianchaonode1 node-type=dev:NoExecute
  1. 再次查看Pod状态:
kubectl get pods -o wide

你会看到

NAME        READY   STATUS        RESTARTS   AGE   IP       NODE            
taint-pod   1/1     Terminating   0          1m    <none>   xianchaonode1   

Pod被驱逐了!因为NoExecute类型的污点会驱逐已经在节点上的不能容忍的Pod。

5. 给Pod加容忍度

现在我们创建一个能够容忍xianchaonode2污点的Pod:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-deploy
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "node-type"
    operator: "Equal"
    value: "production"
    effect: "NoSchedule"

参数解释

  • tolerations:Pod的容忍度列表
  • key:要容忍的污点的键
  • operator:匹配方式,Equal表示等值匹配,Exists表示只要键存在就匹配
  • value:要容忍的污点的值
  • effect:要容忍的污点的效果
kubectl apply -f pod-demo-1.yaml
kubectl get pods -o wide

你会看到

NAME           READY   STATUS    RESTARTS   AGE   IP              NODE            
myapp-deploy   1/1     Running   0          10s   10.244.102.84   xianchaonode2   

Pod成功调度到了有污点的xianchaonode2节点上。

6. 删除污点
# 删除xianchaonode1的污点
kubectl taint nodes xianchaonode1 node-type:NoExecute-

# 删除xianchaonode2的污点
kubectl taint nodes xianchaonode2 node-type-

实验5:Pod的常见状态和重启策略

1. Pod的常见状态
状态含义常见原因
PendingPod已经被创建,但还没有调度到节点上1. 没有满足条件的节点
2. 镜像拉取失败
3. 存储挂载失败
RunningPod已经调度到节点上,所有容器都已经启动并正常运行-
SucceededPod中的所有容器都已经成功终止,并且不会再重启一次性任务(Job)执行完成
FailedPod中的所有容器都已经终止,并且至少有一个容器是异常终止(退出码非0)应用崩溃、配置错误、依赖缺失
Unknown无法获取Pod的状态节点故障、kubelet无法与apiserver通信
ImagePullBackOff镜像拉取失败,正在重试镜像不存在、网络不通、镜像仓库认证失败
CrashLoopBackOff容器启动后又异常退出,正在重试应用启动失败、健康检查失败
EvictedPod被节点驱逐节点资源不足(内存、磁盘)
![[Pasted image 20260603205529.png]]
2. Pod的重启策略

Pod的重启策略应用于Pod内的所有容器,当容器异常退出时,kubelet会根据重启策略进行相应的操作。

Pod有三种重启策略:

重启策略含义适用场景
Always只要容器退出,就重启它长期运行的服务(如Web服务器、数据库)
OnFailure只有当容器异常退出(退出码非0)时,才重启它一次性任务(Job)
Never无论容器如何退出,都不重启它一次性任务,执行完成后就结束

实验1:Always重启策略(默认)

  1. 创建Pod:
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  restartPolicy: Always
  containers:
  - name: tomcat
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent
  1. 正常停止容器内的tomcat服务:
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
  1. 查看Pod状态:
kubectl get pod

你会看到

NAME       READY   STATUS    RESTARTS     AGE
demo-pod   1/1     Running   1 (5s ago)   3m24s

容器重启了一次,重启次数增加了1。

实验2:Never重启策略

  1. 修改Pod的重启策略为Never
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  restartPolicy: Never
  containers:
  - name: tomcat
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent
  1. 正常停止容器内的tomcat服务:
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
  1. 查看Pod状态:
kubectl get pod

你会看到

NAME       READY   STATUS      RESTARTS   AGE
demo-pod   0/1     Completed   0          3m24s

容器没有重启,Pod状态变为Completed

实验3:OnFailure重启策略

  1. 修改Pod的重启策略为OnFailure
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  restartPolicy: OnFailure
  containers:
  - name: tomcat
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent
  1. 正常停止容器内的tomcat服务(退出码为0):
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
  1. 查看Pod状态:
kubectl get pod

你会看到

NAME       READY   STATUS      RESTARTS   AGE
demo-pod   0/1     Completed   0          3m24s

容器没有重启,因为是正常退出。

  1. 重新创建Pod,然后强制杀死容器内的进程(退出码非0):
kubectl delete -f pod.yaml
kubectl apply -f pod.yaml
kubectl exec -it demo-pod -- /bin/bash
kill 1
exit
  1. 查看Pod状态:
kubectl get pod

你会看到

NAME       READY   STATUS    RESTARTS     AGE
demo-pod   1/1     Running   1 (5s ago)   3m24s

容器重启了一次,因为是异常退出。

四、实验核心原理深度解析

1. K8s调度器的工作流程

K8s的调度器(kube-scheduler)负责将Pod调度到合适的节点上,它的工作流程分为三个阶段:

  1. 过滤阶段(Predicate):过滤掉所有不满足条件的节点。比如:

    • 节点资源不足
    • 节点有污点,Pod没有对应的容忍度
    • 不满足节点亲和性或Pod亲和性的条件
  2. 打分阶段(Priority):给剩下的节点打分,选出得分最高的节点。打分的依据包括:

    • 节点的资源使用率
    • 软亲和性的权重
    • 节点的负载情况
  3. 绑定阶段(Bind):将Pod绑定到得分最高的节点上,并更新etcd中的信息。

2. 各种调度方式的对比

调度方式灵活性复杂度适用场景
nodeName最低最简单测试环境,临时指定节点
nodeSelector简单简单的标签匹配场景
节点亲和性中等复杂的节点选择场景
Pod亲和性/反亲和性最高复杂Pod之间的依赖或隔离场景
污点和容忍度中等节点的主动排斥,资源隔离

3. 生产环境最佳实践

  1. 优先使用亲和性而不是nodeSelector:亲和性更灵活,支持软限制和复杂的逻辑表达式
  2. 使用Pod反亲和性实现高可用:让同一个应用的多个Pod分散在不同的节点和可用区
  3. 合理使用污点和容忍度
    • 给特殊用途的节点打污点(如GPU节点、大数据节点)
    • 只有对应的应用才能容忍这些污点,运行在这些节点上
  4. 避免使用nodeName:太死板,不适合大规模集群
  5. 根据应用类型选择合适的重启策略
    • 长期运行的服务使用Always
    • 一次性任务使用OnFailureNever

五、实验常见问题及解决方法

问题1:Pod一直处于Pending状态

排查步骤

  1. 查看Pod的详细信息:kubectl describe pods <pod-name>
  2. 查看Events部分,根据错误提示解决问题:
    • 0/2 nodes are available: 2 node(s) didn't match node selector:没有满足nodeSelector条件的节点
    • 0/2 nodes are available: 2 node(s) had taint {xxx:xxx}, that the pod didn't tolerate:节点有污点,Pod没有对应的容忍度
    • ImagePullBackOff:镜像拉取失败,检查镜像名称、网络和镜像仓库认证
    • PersistentVolumeClaim is not bound:存储卷挂载失败,检查PVC是否存在

问题2:Pod一直处于CrashLoopBackOff状态

排查步骤

  1. 查看容器日志:kubectl logs <pod-name>
  2. 查看Pod的详细信息:kubectl describe pods <pod-name>
  3. 常见原因:
    • 应用启动失败(配置错误、依赖缺失)
    • 健康检查失败
    • 资源限制不足
    • 容器启动命令错误

问题3:Pod被驱逐(Evicted)

原因:节点资源不足(内存、磁盘)
解决方法

  1. 清理节点上的无用资源(镜像、容器、日志)
  2. 增加节点的资源
  3. 调整Pod的资源请求和限制

六、实验总结

通过这个实验,你应该掌握了K8s中所有核心的调度策略:

  1. 标签是K8s的基础,所有的调度和管理都是基于标签实现的
  2. nodeName和nodeSelector是最简单的调度方式,适合简单场景
  3. 亲和性是最强大的调度方式,支持复杂的逻辑表达式和软/硬限制
  4. 污点和容忍度实现了节点的主动排斥,用于资源隔离和特殊节点管理
  5. 了解Pod的常见状态和重启策略,能够快速排查Pod的问题

这些调度策略是K8s生产环境部署的核心,掌握了它们,你就能够根据实际需求,灵活地控制Pod的运行位置,实现应用的高可用、高性能和资源的合理利用。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐