在运营Kubernetes时,您可能会遇到“咦?这个怎么会出现在这里?”的时刻。最常见的误解就是认为“Pod会均匀地(Round-Robin)分布到各个节点上。”
今天,我将通过我亲身经历的“Pod集中现象”,深入剖析Kubernetes调度器实际如何打分和选择节点,揭示其看不见的逻辑。🚀

0. 问题情况:“明明有多个节点…”
为了测试,我依次创建了MySQL、Nginx和httpd的Pod。我们自然而然的期望是“节点1、节点2、节点3…会这样友好地分配开来吧?”
但现实却不同。
$ kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODEmysql 1/1 Running 0 66m 10.16.2.12 gke-cluster-1-default-pool-rr03 nx 1/1 Running 0 16m 10.16.2.13 gke-cluster-1-default-pool-rr03 nx1 1/1 Running 0 6s 10.16.2.14 gke-cluster-1-default-pool-rr03 httpd 1/1 Running 0 4s 10.16.2.15 gke-cluster-1-default-pool-rr03
如您所见,mysql、nx,甚至不同的镜像httpd,都持续不断地只在rr03这一个节点上创建。而其他节点却空空如也!😱
原因是什么呢?调度器是不是坏了?
1. 解开误解:调度器不懂ABC顺序 ❌
很多人认为调度器采用‘轮询(Round-Robin)’方式,就会按照节点名称顺序(A->B->C)进行部署。然而,Kubernetes调度器是完全基于‘分数(Score)’来运作的。
- Filtering: 不符合条件的节点被淘汰
- Scoring: 给剩余节点打分(0~100分)
- Ranking: 选择得分最高的节点
也就是说,rr03节点之所以一直被选中,并非因为顺序,而是在调度器看来,rr03一直都是‘最佳候选’。
2. 嫌犯分析:为什么一个已满的节点会成为第一名? 🤔
在有空节点的情况下,一个已经有3个Pod的节点却成为第一名,这是两种设置的共同作用。
① 未设置资源请求(Requests)= 被视为“透明人”
我在创建Pod时没有设置`resources.requests`(CPU/内存请求量)。
- 调度器的视角:“这个Pod使用0 CPU,0内存?”
- 判断:无论rr03节点上有100个还是1000个Pod,如果只有未设置Request的Pod,那么在调度器看来,该节点的利用率仍然是‘0%’。
- 结果:“空节点和rr03反正都一样空闲?(资源分数平局)”
② 决定性一击:镜像本地性(Image Locality)与层共享
这里产生了一个疑问:“如果分数平局,应该随机选择才对,为什么偏偏是rr03?”
罪魁祸首是ImageLocality的加分。
- 部署Nginx时:因为mysql,去已经下载了镜像的节点会更快,所以选择了rr03(可以理解)
- 部署Httpd时:“咦?这是一个新镜像啊?”
- 然而,Docker镜像具有层(Layer)结构。
- mysql、nginx和httpd虽然不同,但它们极有可能共享底层的基础镜像(如Debian、Alpine等)或公共库层。
- 最终判定:
- 空节点:“需要从头开始下载所有基础层” -> 无加分
- rr03节点:“咦?旁边那些Pod用的基础层已经有了?赚到了!” -> 获得加分(+)
最终,资源分数平局(0分影响),但在镜像缓存分数上rr03略微领先,从而成为了一个不断吸纳Pod的黑洞。🕳️
3. 解决方案:如何分散Pod? 🛠️
如何才能阻止这种现象,并将Pod均匀地分散到整个集群中呢?
✅ 方法1:明确指定资源请求(Requests)(推荐)
给Pod贴上“我需要这么多资源!”的标签。
resources: requests: cpu: "200m" # 请求0.2核心
这样,调度器就会正常判断“啊,rr03已经满了。应该发送到空节点!”,从而启动负载均衡(Least Allocated)逻辑。
✅ 方法2:设置反亲和性(Anti-Affinity)
这是一种强制设置,表示“我不喜欢和与我相同的Pod待在一起!”。
podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: ...
使用此选项,Pod将强制不重叠地部署,与分数计算无关。
4. 结论 📝
- Kubernetes调度器不按ABC顺序部署。
- 如果未设置requests,调度器会将Pod的大小视为‘0’。
- 在这种情况下,即使只有少量镜像层残留的节点也会获得加分,导致Pod集中在一个地方。
- 为了稳定运行,设置Resource Requests并非可选项,而是必需项!
今天的摸索到此结束!希望这能帮助您理解这位高傲的调度器的心思。👋
发表回复