K8s 调度策略完整实验详解K8s 调度策略完整实验详解(标签 + 节点选择器 + 亲和性 + 污点容忍度 + Pod 状态)
这是K8s中最核心、最实用的实验之一,直接决定了你能否在生产环境中精准控制Pod的运行位置。所有的高可用部署、资源隔离、性能优化都离不开这些调度策略。我会按照**“概念→实验步骤→原理→生产实践”**的逻辑,把每个知识点讲透。
一、实验核心目标
通过亲手操作,彻底搞懂:
- 标签(Label) 是什么,为什么它是K8s所有调度和管理的基础
- 如何用nodeName和nodeSelector实现简单的节点调度
- 节点亲和性、Pod亲和性、Pod反亲和性的区别和使用场景
- 污点(Taint)和容忍度(Toleration) 的工作原理,如何实现节点的主动排斥
- Pod的常见状态和重启策略,以及如何排查Pod调度失败的问题
二、实验前置准备
✅ 已经完成K8s集群搭建(1个master+2个worker节点)
✅ 所有节点状态为Ready
✅ Calico网络插件正常运行
✅ 已经导入以下镜像到所有worker节点:
tomcat:8.5-jre8-alpinebusybox:latestikubernetes/myapp:v1
三、实验分步详解
实验1:标签(Label)的基本操作
标签是K8s的灵魂,所有的资源管理和调度都是基于标签实现的。
1. 什么是标签?
大白话解释:
标签就是给K8s资源(Pod、Node、Service等)打上的**“便签”**,是一个键值对(key=value)。你可以给任何资源打任意数量的标签,然后通过标签来筛选和管理这些资源。
典型应用场景:
- 给Pod打标签:
app=tomcat、env=prod、version=v1 - 给Node打标签:
disk=ssd、zone=beijing、gpu=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要运行在哪个节点上。
实验步骤:
- 创建
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"]
- 创建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:基于标签选择节点
nodeSelector比nodeName更灵活,它可以让Pod运行在所有带有特定标签的节点上。
实验步骤:
- 给
xianchaonode2节点打标签:
kubectl label nodes xianchaonode2 disk=ceph
- 查看节点标签:
kubectl get nodes --show-labels
- 创建
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
- 创建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
如果同时指定了nodeName和nodeSelector,那么两个条件必须同时满足,否则Pod会调度失败。
实验验证:
- 删除
xianchaonode2的标签:
kubectl label nodes xianchaonode2 disk-
- 创建同时指定两者的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
- 查看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无法调度。
- 创建
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
- 创建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=foo或zone=bar的标签,不满足硬亲和性的条件。
- 给
xianchaonode1打标签:
kubectl label nodes xianchaonode1 zone=foo
- 再次查看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也能调度到其他节点上。
- 创建
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,权重越高,优先级越高
- 创建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
虽然没有任何节点带有zone1或zone2的标签,但是因为是软亲和性,所以Pod仍然可以调度。
- 验证权重:
# 给两个节点分别打标签
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硬亲和性
- 创建第一个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。
- 创建第二个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:选择要亲和的PodtopologyKey: kubernetes.io/hostname:拓扑域是节点,即要求两个Pod运行在同一个节点上
- 创建第二个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硬反亲和性
- 创建第一个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节点上。
- 创建第二个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
- 创建第二个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. 验证污点的效果
- 创建一个普通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没有对应的容忍度。
- 给
xianchaonode1打NoExecute类型的污点:
kubectl taint node xianchaonode1 node-type=dev:NoExecute
- 再次查看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的常见状态
| 状态 | 含义 | 常见原因 |
|---|---|---|
| Pending | Pod已经被创建,但还没有调度到节点上 | 1. 没有满足条件的节点 2. 镜像拉取失败 3. 存储挂载失败 |
| Running | Pod已经调度到节点上,所有容器都已经启动并正常运行 | - |
| Succeeded | Pod中的所有容器都已经成功终止,并且不会再重启 | 一次性任务(Job)执行完成 |
| Failed | Pod中的所有容器都已经终止,并且至少有一个容器是异常终止(退出码非0) | 应用崩溃、配置错误、依赖缺失 |
| Unknown | 无法获取Pod的状态 | 节点故障、kubelet无法与apiserver通信 |
| ImagePullBackOff | 镜像拉取失败,正在重试 | 镜像不存在、网络不通、镜像仓库认证失败 |
| CrashLoopBackOff | 容器启动后又异常退出,正在重试 | 应用启动失败、健康检查失败 |
| Evicted | Pod被节点驱逐 | 节点资源不足(内存、磁盘) |
| ![[Pasted image 20260603205529.png]] |
2. Pod的重启策略
Pod的重启策略应用于Pod内的所有容器,当容器异常退出时,kubelet会根据重启策略进行相应的操作。
Pod有三种重启策略:
| 重启策略 | 含义 | 适用场景 |
|---|---|---|
| Always | 只要容器退出,就重启它 | 长期运行的服务(如Web服务器、数据库) |
| OnFailure | 只有当容器异常退出(退出码非0)时,才重启它 | 一次性任务(Job) |
| Never | 无论容器如何退出,都不重启它 | 一次性任务,执行完成后就结束 |
实验1:Always重启策略(默认)
- 创建Pod:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
restartPolicy: Always
containers:
- name: tomcat
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
- 正常停止容器内的tomcat服务:
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
- 查看Pod状态:
kubectl get pod
你会看到:
NAME READY STATUS RESTARTS AGE
demo-pod 1/1 Running 1 (5s ago) 3m24s
容器重启了一次,重启次数增加了1。
实验2:Never重启策略
- 修改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
- 正常停止容器内的tomcat服务:
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
- 查看Pod状态:
kubectl get pod
你会看到:
NAME READY STATUS RESTARTS AGE
demo-pod 0/1 Completed 0 3m24s
容器没有重启,Pod状态变为Completed。
实验3:OnFailure重启策略
- 修改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
- 正常停止容器内的tomcat服务(退出码为0):
kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh
exit
- 查看Pod状态:
kubectl get pod
你会看到:
NAME READY STATUS RESTARTS AGE
demo-pod 0/1 Completed 0 3m24s
容器没有重启,因为是正常退出。
- 重新创建Pod,然后强制杀死容器内的进程(退出码非0):
kubectl delete -f pod.yaml
kubectl apply -f pod.yaml
kubectl exec -it demo-pod -- /bin/bash
kill 1
exit
- 查看Pod状态:
kubectl get pod
你会看到:
NAME READY STATUS RESTARTS AGE
demo-pod 1/1 Running 1 (5s ago) 3m24s
容器重启了一次,因为是异常退出。
四、实验核心原理深度解析
1. K8s调度器的工作流程
K8s的调度器(kube-scheduler)负责将Pod调度到合适的节点上,它的工作流程分为三个阶段:
-
过滤阶段(Predicate):过滤掉所有不满足条件的节点。比如:
- 节点资源不足
- 节点有污点,Pod没有对应的容忍度
- 不满足节点亲和性或Pod亲和性的条件
-
打分阶段(Priority):给剩下的节点打分,选出得分最高的节点。打分的依据包括:
- 节点的资源使用率
- 软亲和性的权重
- 节点的负载情况
-
绑定阶段(Bind):将Pod绑定到得分最高的节点上,并更新etcd中的信息。
2. 各种调度方式的对比
| 调度方式 | 灵活性 | 复杂度 | 适用场景 |
|---|---|---|---|
| nodeName | 最低 | 最简单 | 测试环境,临时指定节点 |
| nodeSelector | 低 | 简单 | 简单的标签匹配场景 |
| 节点亲和性 | 高 | 中等 | 复杂的节点选择场景 |
| Pod亲和性/反亲和性 | 最高 | 复杂 | Pod之间的依赖或隔离场景 |
| 污点和容忍度 | 高 | 中等 | 节点的主动排斥,资源隔离 |
3. 生产环境最佳实践
- 优先使用亲和性而不是nodeSelector:亲和性更灵活,支持软限制和复杂的逻辑表达式
- 使用Pod反亲和性实现高可用:让同一个应用的多个Pod分散在不同的节点和可用区
- 合理使用污点和容忍度:
- 给特殊用途的节点打污点(如GPU节点、大数据节点)
- 只有对应的应用才能容忍这些污点,运行在这些节点上
- 避免使用nodeName:太死板,不适合大规模集群
- 根据应用类型选择合适的重启策略:
- 长期运行的服务使用
Always - 一次性任务使用
OnFailure或Never
- 长期运行的服务使用
五、实验常见问题及解决方法
问题1:Pod一直处于Pending状态
排查步骤:
- 查看Pod的详细信息:
kubectl describe pods <pod-name> - 查看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状态
排查步骤:
- 查看容器日志:
kubectl logs <pod-name> - 查看Pod的详细信息:
kubectl describe pods <pod-name> - 常见原因:
- 应用启动失败(配置错误、依赖缺失)
- 健康检查失败
- 资源限制不足
- 容器启动命令错误
问题3:Pod被驱逐(Evicted)
原因:节点资源不足(内存、磁盘)
解决方法:
- 清理节点上的无用资源(镜像、容器、日志)
- 增加节点的资源
- 调整Pod的资源请求和限制
六、实验总结
通过这个实验,你应该掌握了K8s中所有核心的调度策略:
- 标签是K8s的基础,所有的调度和管理都是基于标签实现的
- nodeName和nodeSelector是最简单的调度方式,适合简单场景
- 亲和性是最强大的调度方式,支持复杂的逻辑表达式和软/硬限制
- 污点和容忍度实现了节点的主动排斥,用于资源隔离和特殊节点管理
- 了解Pod的常见状态和重启策略,能够快速排查Pod的问题
这些调度策略是K8s生产环境部署的核心,掌握了它们,你就能够根据实际需求,灵活地控制Pod的运行位置,实现应用的高可用、高性能和资源的合理利用。
更多推荐


所有评论(0)