想象你是大学宿舍楼的管理员。新学期开始,几十位新生提着行李排队登记,每个人都有自己的小愿望:有人希望和同班同学住同一楼层,方便一起上课;有人明确说“我打呼噜,千万别让我和睡眠浅的人住隔壁”;还有人只想要朝南带阳台的房间。你的任务是在有限的房间(节点)里,把几百个学生(Pod)安排得既满足硬性要求,又不至于浪费资源。Kubernetes 的调度器就是这位“宿管阿姨”,而亲和性与反亲和性,就是她手里的那张“入住偏好表”。 本文用“宿舍分配”这条故事线,带你从零看懂 K8s 的调度策略:什么是节点亲和、Pod 亲和,什么是硬亲和、软亲和,拓扑域又是什么。读完你会明白,调度器如何先过滤掉不合格的房间,再给剩余房间打分排序,最终把每个 Pod 放到最合适的位置,让整个集群资源用得更高效、服务更稳定。

岗位关联

对 AI 从业者来说,掌握亲和性与反亲和性,意味着你能像控制微服务分布一样精细地控制模型推理 Pod 的位置,让 GPU 节点、数据节点和计算节点各就各位,是优化集群资源利用率和服务可用性的必备技能。

目录
  1. 可视化演示
  2. 调度器基础
  3. 亲和性概念
  4. 节点亲和
  5. Pod亲和
  6. 反亲和性
  7. 调度场景
  8. 实践验证
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Kubernetes调度器的节点过滤打分流程、亲和与反亲和的Pod分布对比、以及拓扑域maxSkew约束效果,切换模式查看不同调度策略。

本节配有交互动效(进入视口后自动加载,约 3KB)。

调度两阶段:Filter与Score Filter阶段排除不满足硬约束的节点 Score阶段对候选节点按亲和权重打分 最高分节点获得Pod放置权 Score = Σ(weight × match) 硬约束过滤+软约束打分选出最优节点

调度器基础

宿管阿姨分配宿舍时,心里有一本账:这间屋还有几个空床位、空调功率够不够、离热水房近不近。她不会直接把新生塞进一个满员的宿舍,也不会让 8 个人挤进 4 人间。Kubernetes 的调度器 kube-scheduler 做的事一模一样:它不停发现“等待入住”的 Pod,先看哪些节点满足硬性资源需求,再对候选节点排序,最后挑一个最合适的。

这里的“硬性需求”就是 Pod 声明的 CPU、内存、GPU 等资源请求。调度器先做预选(Filter),把资源不够的节点直接排除;再做优选(Prioritize),给剩余节点按空闲资源比例打分。分数高不代表一定被选中,但它是重要参考。

资源评分只是基础。宿管阿姨还要看更细的偏好:这位同学想和谁住、想离谁远一点。于是,亲和性规则登场了。

Score(n)=0.5×Cfree(n)Ctotal(n)+0.5×Mfree(n)Mtotal(n)\displaystyle Score(n) = 0.5 \times \frac{C_{free}(n)}{C_{total}(n)} + 0.5 \times \frac{M_{free}(n)}{M_{total}(n)}
这个评分公式告诉我们,调度器喜欢“资源余量更充足”的节点,就像宿管阿姨更喜欢把新生分到还没住满的宿舍。
  1. 节点评分 Score(n)对候选节点 n 进行综合打分,得分越高越优先。
    Score(n)\displaystyle Score(n)
  2. 权重 0.5假设 CPU 和内存同等重要,各占一半权重;实际调度器里权重可配置。
    0.5×Cfree(n)Ctotal(n)\displaystyle 0.5 \times \frac{C_{free}(n)}{C_{total}(n)}
  3. CPU 空闲率节点上还可分配的 CPU 除以总 CPU,体现“床位剩余比例”。
    Cfree(n)Ctotal(n)\displaystyle \frac{C_{free}(n)}{C_{total}(n)}
  4. 内存空闲率用同样的方式衡量内存余量,避免某个维度成为瓶颈。
    Mfree(n)Mtotal(n)\displaystyle \frac{M_{free}(n)}{M_{total}(n)}

亲和性概念

新同学登记入住时,会填一张“住宿偏好表”:想和同班同学同楼层,不想和打呼噜的同学隔壁。K8s 里,节点和 Pod 可以被贴上各种“标签”(Label),比如 zone=az1(所在片区)、app=web(属于哪个应用),而亲和性规则就是用来描述“我想接近哪些标签”或“我想远离哪些标签”的选择器。

亲和性分为硬亲和和软亲和。硬亲和的英文是 requiredDuringSchedulingIgnoredDuringExecution,意思是调度时必须满足,不满足就不把 Pod 放在这个节点上;软亲和是 preferredDuringSchedulingIgnoredDuringExecution,意思是“最好能满足”,满足的话加分,不满足也没关系,只要没有更糟。

明白了标签与匹配,我们就能继续往下看:到底怎么让“人”靠近“房间”或靠近“人”。

Match(p,s)=⋀(k,v)∈s(k∈Labels(p)∧Labels(p)[k]=v)\displaystyle Match(p, s) = \bigwedge_{(k, v) \in s} \left( k \in Labels(p) \land Labels(p)[k] = v \right)
这个公式描述的是“匹配”的本质:Pod 或节点的一组标签,能否全部命中规则里列出的键值对。
  1. 匹配函数 Match(p, s)判断 Pod/节点 p 的标签是否满足选择器 s 的规则。
    Match(p,s)\displaystyle Match(p, s)
  2. 全称合取规则里的每一项都成立,整体才算匹配,只要有一个不满足就失败。
    ⋀(k,v)∈s\displaystyle \bigwedge_{(k, v) \in s}
  3. 键存在性先检查标签里有没有这个键 k,没有键自然匹配失败。
    k∈Labels(p)\displaystyle k \in Labels(p)
  4. 值相等性再检查 k 对应的值是否等于规则要求的值 v。
    Labels(p)[k]=v\displaystyle Labels(p)[k] = v

节点亲和

有同学说:“我只住朝南带阳台的房间。”这对应的就是节点亲和 nodeAffinity:让 Pod 按节点的标签来筛选和加分。它比老式的 nodeSelector 更灵活,因为不仅支持“等于某个值”,还支持 In(属于某个列表)、NotIn(不属于)、Exists(键存在)等操作符。

节点亲和也有硬性和软性之分。英文名里的 requiredDuringSchedulingIgnoredDuringExecution 是硬条件,必须满足;preferredDuringSchedulingIgnoredDuringExecution 是软条件,只影响打分。硬条件负责“过滤”,软条件负责“加分”。

节点亲和解决的是“房间好不好”的问题,但同学还关心“邻居是谁”,这就是 Pod 亲和要解决的事。

Anode(n)=∑r∈Prefwr⋅1[Match(r,Labels(n))],且⋀r∈ReqMatch(r,Labels(n))\displaystyle A_{node}(n) = \sum_{r \in Pref} w_r \cdot \mathbf{1}\big[ Match(r, Labels(n)) \big], \quad \text{且} \quad \bigwedge_{r \in Req} Match(r, Labels(n))
节点亲和先保证所有硬性规则都满足,再为满足软性规则的节点累加权重分。
  1. 硬性规则检查Req 里的每条规则都必须匹配,否则节点被直接淘汰。
    ⋀r∈ReqMatch(r,Labels(n))\displaystyle \bigwedge_{r \in Req} Match(r, Labels(n))
  2. 软性规则遍历遍历 Pref 中的每一条软规则 r。
    ∑r∈Pref\displaystyle \sum_{r \in Pref}
  3. 条件指示器1[条件] 表示条件成立时取 1,否则取 0。
    1[Match(r,Labels(n))]\displaystyle \mathbf{1}\big[ Match(r, Labels(n)) \big]
  4. 加权求和每条软规则有自己的权重 w_r,所有命中规则的权重相加得到节点亲和得分。
    wr⋅1[Match(r,Labels(n))]\displaystyle w_r \cdot \mathbf{1}\big[ Match(r, Labels(n)) \big]

Pod亲和

有的同学说:“我想和我的好朋友住同一楼层,下课一起走。”K8s 里这叫 Pod 亲和 podAffinity:让新 Pod 靠近一组已经在运行的目标 Pod。这里最重要的一个概念是拓扑域(Topology Domain),它决定了“同一范围”如何定义——是同一个节点,还是同一个可用区,甚至同一个机房。

topologyKey 就是拓扑域的“刻度尺”。比如 kubernetes.io/hostname 表示“同一节点才算近”;topology.kubernetes.io/zone 表示“同一可用区就算近”。Pod 亲和通过 podSelector 选中目标 Pod,只要目标 Pod 落在某个拓扑域内,新 Pod 在调度时就会给这个域的节点加分。

有“想靠近的”,自然就有“想远离的”。下一个概念,就是反亲和性。

Apod(n)=∑q∈Pdomain(n)1[Selector(q)]\displaystyle A_{pod}(n) = \sum_{q \in P_{domain}(n)} \mathbf{1}\big[ Selector(q) \big]
这个公式统计的是:和节点 n 处于同一拓扑域的所有 Pod 中,有多少个命中了你要靠近的目标 Pod 选择器。
  1. 同域 Pod 集合P_{domain}(n) 表示所有与节点 n 在同一个拓扑域里运行的 Pod。
    Pdomain(n)\displaystyle P_{domain}(n)
  2. 对每个 Pod 判断遍历这些 Pod,逐个看它们是否满足 Selector。
    ∑q∈Pdomain(n)\displaystyle \sum_{q \in P_{domain}(n)}
  3. 指示器取值1[Selector(q)] 命中目标 Pod 得 1,不命中得 0。
    1[Selector(q)]\displaystyle \mathbf{1}\big[ Selector(q) \big]

反亲和性

宿舍里最怕两件事:同寝室两人都打呼噜,或者两个半夜开黑的人凑一起熬夜。管理员在分配时,会特意把“热闹型”的同学拆开。K8s 的 反亲和性 podAntiAffinity 干的就是这件事:让 Pod 不跟某些 Pod 挤在同一个拓扑域。

反亲和性最典型的应用是高可用。比如订单服务有 3 个副本,如果 3 个 Pod 都跑在同一台机器上,机器一宕机服务就全挂了。用反亲和性把它们分散到不同节点、不同可用区,单点故障就不会拖垮整个应用。

亲和与反亲和都摆在面前了,宿管阿姨该怎么综合决策呢?下一节我们把所有规则揉在一起。

Danti(n)=∑q∈Pdomain(n)wq⋅1[AntiSelector(q)]\displaystyle D_{anti}(n) = \sum_{q \in P_{domain}(n)} w_q \cdot \mathbf{1}\big[ AntiSelector(q) \big]
反亲和性的分数和 Pod 亲和很像,但它用于“扣分”或者“过滤”,让调度器避开已经挤满“冲突 Pod”的拓扑域。
  1. 冲突 Pod 统计D_{anti}(n) 用来累计同一个拓扑域内“我不想靠近”的 Pod 数量。
    Danti(n)\displaystyle D_{anti}(n)
  2. 遍历同域 Pod和 Pod 亲和一样,先拿到同一个拓扑域里的所有 Pod。
    ∑q∈Pdomain(n)\displaystyle \sum_{q \in P_{domain}(n)}
  3. 反选器匹配AntiSelector(q) 命中代表这个 Pod 是我们想避开的对象。
    1[AntiSelector(q)]\displaystyle \mathbf{1}\big[ AntiSelector(q) \big]
  4. 权重影响不同冲突 Pod 的“讨厌程度”可能不同,用 w_q 表达。
    wq⋅1[AntiSelector(q)]\displaystyle w_q \cdot \mathbf{1}\big[ AntiSelector(q) \big]

调度场景

真正的宿舍分配,从来不是只看一条规则。姓张的同学要求朝南,又想和同班同学同楼层,还不想和打呼噜的住隔壁。宿管阿姨的做法是:先用硬性规则把不合格的房间全部划掉,再用软性规则给剩余房间打分,最后选出总分最高的那个。

K8s 调度器也是这样:nodeAffinity、podAffinity、podAntiAffinity 可以同时出现在一个 Pod 的调度规则里。硬性规则作为过滤器,任一不满足就排除;软性规则进入评分环节,按权重累加。比如计算任务可以“尽量靠近数据所在的节点”,同时“必须避开 CPU 已经被占满的机器”。

规则设计得再好,也要在真实集群里验证。最后一节我们聊聊如何用 kubectl 检查和调试。

Total(n)=wn⋅Anode(n)+wp⋅Apod(n)−wa⋅Danti(n)\displaystyle Total(n) = w_n \cdot A_{node}(n) + w_p \cdot A_{pod}(n) - w_a \cdot D_{anti}(n)
总得分 = 节点亲和加分 + Pod 亲和加分 − 反亲和扣分。多个软规则相互权衡,最终选出“综合最顺眼”的节点。
  1. 节点亲和得分A_{node}(n) 来自节点标签匹配的加分,权重为 w_n。
    wn⋅Anode(n)\displaystyle w_n \cdot A_{node}(n)
  2. Pod 亲和得分A_{pod}(n) 是靠近目标 Pod 的加分,权重为 w_p。
    wp⋅Apod(n)\displaystyle w_p \cdot A_{pod}(n)
  3. 反亲和扣分D_{anti}(n) 是冲突 Pod 带来的扣分项,权重为 w_a。
    −wa⋅Danti(n)\displaystyle - w_a \cdot D_{anti}(n)
  4. 总分汇总三者相加,决定最终节点的优先级。
    Total(n)\displaystyle Total(n)

实践验证

宿管阿姨分配完宿舍,还要拿着名单挨个确认:谁住进了哪一间?有没有人和要求不符?运维同学手里也有一把“钥匙”:kubectl get pods -o wide 可以看到每个 Pod 最终落在哪个节点;kubectl get nodes --show-labels 可以确认节点的标签值;kubectl describe pod <name> 能看到调度器给出的失败原因,比如 0/3 nodes are available: 2 Insufficient cpu, 1 node(s) didn't match node selector。

最常见的问题有三个:节点标签写错了、Pod 的选择器写错了、拓扑域定义得和实际部署不一致。只要耐心看 Events 和标签,大部分调度问题都能快速定位。

从“调度器如何选房间”到“如何用 kubectl 查作业”,你已经掌握了亲和性调度的完整地图。接下来,我们看看这些能力在真实 AI 工程里的用武之地。

Violations=∑p∈ScheduledPods1[HardRuleFails(p)∨AntiAffinityConflict(p)]\displaystyle Violations = \sum_{p \in ScheduledPods} \mathbf{1}\big[ HardRuleFails(p) \lor AntiAffinityConflict(p) \big]
这个公式提醒我们,验证阶段的核心就是检查:每个已调度 Pod 是否违反了硬性规则,或是否和反亲和规则产生了冲突。
  1. 已调度 Pod 集合遍历集群中所有已经完成调度的 Pod。
    ScheduledPods\displaystyle ScheduledPods
  2. 检查硬规则失败HardRuleFails(p) 为真表示 Pod 的硬亲和条件没有被满足。
    HardRuleFails(p)\displaystyle HardRuleFails(p)
  3. 检查反亲和冲突AntiAffinityConflict(p) 为真表示它和不该共存的 Pod 同居了一个拓扑域。
    AntiAffinityConflict(p)\displaystyle AntiAffinityConflict(p)
  4. 统计违规数把每一个违规 Pod 累计求和,得到 Violations。
    ∑p∈ScheduledPods1[⋯ ]\displaystyle \sum_{p \in ScheduledPods} \mathbf{1}[\cdots]

AI 应用场景

微服务同机房低延迟部署

阶段:模型服务部署与流量调度

解决的问题:AI 推理链路通常包含网关、鉴权、模型推理等多个微服务,如果它们跨机房调用,延迟会明显升高。传统做法是手动指定节点,维护成本高且容易出错。用 podAffinity 把推理 Pod 调度到已经运行着网关 Pod 的同拓扑域节点上,就能自动保证“物理距离”很近。

具体案例:某推荐系统在华东双可用区部署,网关和推理服务通过 podAffinity + topology.kubernetes.io/zone 绑定同一可用区,P99 延迟从 120ms 降到 68ms。

多副本高可用反亲和

阶段:模型服务容灾与稳定性保障

解决的问题:模型推理副本如果堆在同一台 GPU 节点,节点故障会造成全部副本失联。通过 podAntiAffinity 的 requiredDuringSchedulingIgnoredDuringExecution,强制让同一模型的副本分散在不同节点或不同可用区,实现故障域隔离。

具体案例:大模型推理服务有 4 个 Pod,配置反亲和键 app=llm-server,topologyKey 用 topology.kubernetes.io/zone,保证 4 个副本落在至少 3 个可用区,单可用区故障时服务不中断。

数据本地性优化

阶段:分布式训练和数据处理

解决的问题:Spark 或 Ray 这类计算框架需要尽量把计算任务调度到“数据所在的节点”上,减少网络传输。通过 nodeAffinity 选择带有 data=local 标签的节点,或者用 podAffinity 靠近数据服务 Pod,可以显著提升数据读取效率。

具体案例:离线训练集群给湖存储节点打上 storage=fast 标签,训练 Pod 声明 nodeAffinity 的 preferred 规则指向该标签,任务读写延迟降低约 35%。

Python 演示

python58 行
def match(labels, selector):    for key, val in selector.items():        if key not in labels:            return False        if isinstance(val, list) and labels[key] not in val:            return False        if isinstance(val, str) and labels[key] != val:            return False    return True  class Pod:    def __init__(self, name, labels, hard_node=None, pref_node=None):        self.name = name        self.labels = labels        self.hard_node = hard_node or {}        self.pref_node = pref_node or {}        self.node = None  class Scheduler:    def __init__(self, nodes):        self.nodes = nodes  # list of dict: {'name': str, 'labels': dict}        self.placements = []     def score(self, node, pod):        if pod.hard_node and not match(node['labels'], pod.hard_node):            return -1        s = 0.5        if match(node['labels'], pod.pref_node):            s += 0.5        return s     def schedule(self, pod):        best = None        for node in self.nodes:            s = self.score(node, pod)            if s > 0 and (best is None or s > best[1]):                best = (node['name'], s)        if best:            pod.node = best[0]            self.placements.append((pod.name, pod.node))        else:            pod.node = None        return pod.node  if __name__ == '__main__':    nodes = [        {'name': 'node-a', 'labels': {'zone': 'az1', 'ssd': 'true'}},        {'name': 'node-b', 'labels': {'zone': 'az1', 'ssd': 'false'}},        {'name': 'node-c', 'labels': {'zone': 'az2', 'ssd': 'true'}},    ]    sc = Scheduler(nodes)    p1 = Pod('web-1', {'app': 'web'}, {'zone': 'az1'}, {'ssd': 'true'})    p2 = Pod('db-1', {'app': 'db'}, {'zone': 'az2'})    for p in (p1, p2):        print(p.name, '->', sc.schedule(p))
目的:用 30 行左右的代码还原 K8s 调度器“先硬过滤、再按偏好打分”的简化流程,帮助你直观理解 nodeAffinity 的 required 与 preferred 是如何协作的。
  1. def match(labels, selector):最基础的标签匹配函数,遍历选择器里所有键值对。
  2. if isinstance(val, list) and labels[key] not in val:支持 In 操作符的简化版:值列表里没有就算不匹配。
  3. if pod.hard_node and not match(node['labels'], pod.hard_node):硬亲和不满足,直接返回 -1,表示节点被过滤。
  4. s = 0.5基础分,代表“房间已经可住”,后续软偏好在此基础上加分。
  5. if match(node['labels'], pod.pref_node): s += 0.5软亲和命中,给节点加分,对应 preferred 规则。
  6. best = (node['name'], s)记录当前得分最高的节点。
  7. for node in self.nodes:遍历所有候选节点,模拟调度器的优选阶段。

常见误区

误区“既然 nodeSelector 也能按节点标签选节点,那还要 nodeAffinity 干嘛?”

正解nodeSelector 只能表达“键值完全相等”这种最简单的匹配,做不到“值属于某几个选项”“键存在即可”这种表达,也分不清硬条件和软偏好。nodeAffinity 更像表达力更强的“升级版选择器”,支持 In、NotIn、Exists 等操作符,还能用 preferred 给节点加分,而不是一票否决。

为何常见:因为两者都用节点标签作为依据,初学时容易被“看起来差不多”的外表迷惑。

误区“我写了 preferred 亲和规则,如果节点没有这个标签,Pod 为什么还是被调度上去了?是不是配置失效了?”

正解preferredDuringSchedulingIgnoredDuringExecution 本身就是“软”的宿主偏好,它不会阻止调度,只会在打分时影响优先级。真正起强制过滤作用的是 requiredDuringSchedulingIgnoredDuringExecution。软亲和不满足时,调度器只会感叹“可惜”,然后把 Pod 放到别处。

为何常见:名字太长,大家容易忽略 preferred 与 required 的语义差异,以为写了任意亲和规则就会强制生效。

误区“只要我写了 podAffinity,Pod 自然就会和指定 Pod 跑到同一台机器上,topologyKey 随便写个 hostname 就行。”

正解topologyKey 决定了“同一拓扑域”的边界。如果用它表示 kubernetes.io/hostname,调度器会把“同一节点”视为同一域;如果用它表示 topology.kubernetes.io/zone,则会把整个可用区视为一个域。乱填不存在的标签键,会导致调度器永远找不到同域 Pod,亲和规则静默失效。

为何常见:拓扑域这个概念比较抽象,初学者容易把它当成一个普通参数,忽视了它和节点标签的强绑定关系。

误区“我用 podAntiAffinity 设置了副本分散,为什么两个副本还是落在了同一个节点?”

正解如果用的是 preferred 反亲和,调度器会尽量分散,但不保证;即便用了 required 反亲和,也要看是否存在“无解”的情况。比如集群里只有一个节点,Pod 的 required 反亲和要求不能共节点,调度器只能让 Pod 一直 Pending。另外,如果 topologyKey 选得太粗,比如用 zone,同一可用区里不同节点也算“同一域”,副本自然会挤在一起。

为何常见:高可用场景下大家默认“反亲和=一定会分开”,却忽略了 required/preferred 和拓扑域粒度共同决定最终结果。

误区“我把某个节点的标签改了,为什么已经跑在上面的 Pod 没有重新调度到别处?”

正解亲和性规则名字里的 DuringSchedulingIgnoredDuringExecution 已经说明了语义:只在“调度过程中”生效,执行阶段被忽略。Pod 一旦被调度到节点上,即使节点标签后来变了,也不会触发重新调度;只有 Pod 被删除重建,或通过其他机制触发重新调度,新规则才会生效。

为何常见:这个英文名太长,大多数人只记住了前半段“DuringScheduling”,忽略了后半段“IgnoredDuringExecution”。

面试题

Q1. Kubernetes 中负责把 Pod 调度到合适节点上的核心组件是?

单选题 · easy

  • A.kubelet
  • B.kube-scheduler← 正确答案
  • C.kube-proxy
  • D.etcd 存储

答案:B。kubelet 只在节点上运行容器,kube-proxy 负责网络代理,etcd 负责存储集群状态。只有 kube-scheduler 专门负责为待调度的 Pod 寻找合适的节点,就像宿管阿姨专门负责分宿舍。

Q2. 如果一个 Pod 声明了 required 硬亲和规则,但所有节点都不满足,调度器会怎么做?

单选题 · easy

  • A.选择打分最高的节点硬凑
  • B.让 Pod 一直处于 Pending 状态← 正确答案
  • C.自动删除该规则
  • D.把 Pod 调度到控制平面节点

答案:B。required 是硬性条件,没有节点满足时调度器不会安排任何节点,Pod 会留在待调度队列中并持续报错。这就像宿管阿姨发现没有朝南房间,就只能让这位同学继续在等待区等着。

Q3. nodeAffinity 的 matchExpressions 中,operator 为 In 表示什么?

单选题 · mid

  • A.节点的标签值不能等于列表里任意值
  • B.只要标签键存在就算匹配
  • C.节点的标签值必须属于给定列表← 正确答案
  • D.节点不能有该标签

答案:C。In 是“属于”语义,要求节点标签的值在给定列表里才匹配。Exists 只关心键存在,NotIn 则正好相反。

Q4. 下面哪个 topologyKey 最适合实现“跨可用区高可用反亲和”?

单选题 · mid

  • A.kubernetes.io/hostname
  • B.topology.kubernetes.io/zone← 正确答案
  • C.beta.kubernetes.io/arch
  • D.kubernetes.io/os

答案:B。topology.kubernetes.io/zone 代表可用区,用它做拓扑域,反亲和规则会把 Pod 分散到不同可用区,而不是仅仅分散到不同节点。

Q5. requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution 的关键区别是?

单选题 · mid

  • A.两个名字不同但效果完全相同
  • B.required 不满足就不调度,preferred 只影响打分← 正确答案
  • C.preferred 优先级更高
  • D.required 只能用于节点亲和

答案:B。required 是硬条件,参与过滤;preferred 是软偏好,参与评分。preferred 不满足也能调度,只是优先级降低,类似“最好有阳台,但实在没有就算了”。

Q6. 当 topologyKey 为 kubernetes.io/hostname 时,两个 Pod 落在同一节点才算同一个拓扑域,这种反亲和主要用于?

单选题 · mid

  • A.节点级副本分散← 正确答案
  • B.可用区级容灾
  • C.跨集群部署
  • D.资源超卖控制

答案:A。hostname 指节点本身,因此反亲和会在节点粒度上把 Pod 拆开,避免所有副本挤在同一台机器上。

Q7. 以下关于硬亲和和软亲和共同作用的说法,正确的是?

单选题 · hard

  • A.硬亲和规则直接参与加分,软亲和规则参与过滤
  • B.硬亲和规则必须满足,软亲和规则在满足后加分← 正确答案
  • C.硬亲和只在节点资源不足时启用
  • D.软亲和规则不满足时 Pod 无法被调度

答案:B。完整调度过程是“先过滤后打分”:硬规则决定节点有没有资格,软规则决定候选节点的名次。硬规则和软规则分工明确,不能互换。

Q8. 亲和性调度可以用于哪些实际场景?(多选)

多选题 · mid

  • A.将网关调度到同机房← 正确答案
  • B.让数据库副本跨故障域分散← 正确答案
  • C.强制所有 Pod 挤同一个节点
  • D.提升数据本地性访问速度← 正确答案

答案:ABD。A 是 Pod 亲和降低延迟,B 是反亲和提升高可用,D 是亲和调度实现数据本地性。C 违反反亲和与资源利用的基本目标,不是合理场景。

Q9. 下列哪些 operator 可以用于 nodeAffinity 的 matchExpressions?(多选)

多选题 · hard

  • A.In 值列表匹配← 正确答案
  • B.NotIn 排除列表← 正确答案
  • C.Exists 键存在判定← 正确答案
  • D.SHA256 校验摘要

答案:ABC。nodeAffinity 支持 In、NotIn、Exists、DoesNotExist 等操作符,它们配合标签实现集合和存在性判断。SHA256 是哈希算法,和标签匹配无关。

Q10. 关于 podAffinity 的 topologyKey,下面说法正确的是?(多选)

多选题 · hard

  • A.必须是节点上的标签键← 正确答案
  • B.可以使用 zone 实现跨区亲和← 正确答案
  • C.只能用 hostname 作为 key
  • D.可以和 nodeAffinity 混用← 正确答案

答案:ABD。topologyKey 的值来自节点标签,不能用任意字符串;zone 是常用拓扑键之一;podAffinity 和 nodeAffinity 可以同时配置。hostname 只是其中一种选择,并非唯一。