GKE Autopilot中如何强制两个Pod调度至同一节点?
问题根因
你的问题核心在于对Autopilot节点调度逻辑和PodAffinity规则的交互理解有偏差:
Autopilot节点规格的创建逻辑:Autopilot会根据单个Pod的资源请求,选择刚好能容纳该Pod的最小规格节点(扣除系统预留资源后),不会提前预留额外资源给后续Pod。当第一个Pod调度完成后,节点的剩余资源大概率不足以容纳第二个Pod。
PodAffinity的执行顺序问题:你给两个Deployment都配置了相同的
requiredDuringSchedulingIgnoredDuringExecution规则,要求Pod必须和component=app的Pod同节点:- 第一个Pod调度时,集群中没有匹配
component=app的Pod,此时required规则会被判定为满足(无匹配Pod时规则不生效),Autopilot创建对应规格的节点并调度该Pod。 - 第二个Pod调度时,必须调度到第一个Pod所在的节点,但该节点剩余资源不足;而新建节点上没有
component=app的Pod,无法满足亲和规则,最终导致Pod Pending。
- 第一个Pod调度时,集群中没有匹配
Autopilot不会为了满足后续Pod的亲和规则动态调整已创建节点的规格,这是你之前的认知遗漏点。
解决方案
针对你的需求,有几种可行的调整方式:
1. 控制Pod资源请求总和,适配单节点容量
先确认Autopilot支持的节点规格(比如e2-standard-2、e2-standard-4等),计算单个节点扣除系统预留后的可用资源(例如e2-standard-2的可用CPU约1.7核,内存约5.4Gi),然后将两个Pod的CPU、内存请求总和控制在该范围内。部署时可以先启动第一个Pod,待其调度完成后再启动第二个,Autopilot会在第一个节点剩余资源足够的情况下完成调度。
2. 将强制亲和改为软亲和(Preferred规则)
如果允许两个Pod在资源不足时调度到不同节点,可把requiredDuringSchedulingIgnoredDuringExecution替换为preferredDuringSchedulingIgnoredDuringExecution,这样Autopilot会优先尝试将两个Pod放在同一节点,当资源不足时会新建节点调度第二个Pod:
affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: component operator: In values: - app topologyKey: kubernetes.io/hostname
3. 设置锚点Pod的专属标签,明确亲和指向
给其中一个Deployment的Pod添加专属标签(比如app-role: primary),让另一个Deployment的PodAffinity仅匹配这个锚点标签:
- 第一个Deployment的Pod标签:
labels: component: app app-role: primary - 第二个Deployment的PodAffinity规则:
affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app-role operator: In values: - primary topologyKey: kubernetes.io/hostname
同时确保两个Pod的资源请求总和在单个Autopilot节点的可用容量内,这样Autopilot会直接创建足够大的节点来容纳锚点Pod和第二个Pod。
内容的提问来源于stack exchange,提问作者SuPot

