k8s中Pod和Node的故事(2):优先级、抢占和驱逐
Pod还可以配置优先级,优先级代表一个pod的重要性。
当高优先级的pod被创建处于悬决状态时,调度器往往会把优先级低的pod驱逐走,让高优先级的pod的“霸占”其节点。
⚠警告:
在一个并非所有用户都是可信任的集群中,恶意用户可能以最高优先级创建 Pod, 导致其他 Pod 被驱逐或者无法被调度。 管理员可以使用 ResourceQuota 来阻止用户创建高优先级的 Pod。
一、认识PriorityClass
k8s集群中,要实现pod优先级和抢占,必须认识和了解PrioritiesClass。
PriorityClass 是一个无命名空间(参照我之前整理的一篇文章来理解)对象,它定义了从优先级类名称到优先级整数值的映射。
请看PriorityClass 示例:
名称在PriorityClass 对象元数据的name字段中指定; 值在必填的 value 字段中指定。值越大,优先级越高。
PriorityClass 对象可以设置任何小于或等于 10 亿的 32 位整数值。 这意味着 PriorityClass 对象的值范围是从 -2,147,483,648 到 1,000,000,000(含)。
1.1 预置的PriorityClass
PriorityClass 对象的名称必须是有效的 DNS 子域名, 并且它不能以 system- 为前缀。
Kubernetes 已经提供了 2 个 PriorityClass: system-cluster-critical 和 system-node-critical。 这些是常见的类,用于确保始终优先调度关键组件。
Kubernetes 核心组件(如 API 服务器、调度器、控制器管理器)在控制平面节点上运行。 但是插件必须在常规集群节点上运行。 其中一些插件对于功能完备的集群至关重要,例如 Heapster、DNS 和 UI。 如果关键插件被逐出(手动或作为升级等其他操作的副作用)或者变成挂起状态,集群可能会停止正常工作。
1.2 两个可选字段
PriorityClass 有两个可选字段:globalDefault 和 description。
- globalDefault 字段表示这个 PriorityClass 的值应该用于没有 priorityClassName 的 Pod。 系统中只能存在一个 globalDefault 设置为 true 的 PriorityClass。
- 如果不存在设置了 globalDefault 的 PriorityClass, 则没有 priorityClassName 的 Pod 的优先级为零。
- description 字段是一个任意字符串。 它用来告诉集群用户何时应该使用此 PriorityClass。
1.3 关于 PodPriority 和现有集群的要点知识
- 如果你升级一个已经存在的但尚未使用此特性的集群,该集群中已经存在的 Pod 的优先级等效于零。
- 添加一个将 globalDefault 设置为 true 的 PriorityClass 不会改变现有 Pod 的优先级。 此类 PriorityClass 的值仅用于添加 PriorityClass 后创建的 Pod。
- 如果你删除了某个 PriorityClass 对象,则使用被删除的 PriorityClass 名称的现有 Pod 保持不变, 但是你不能再创建使用已删除的 PriorityClass名称的 Pod。
二、非抢占式 PriorityClass
配置了 preemptionPolicy: Never 的 Pod 将被放置在调度队列中较低优先级 Pod 之前, 但它们不能抢占其他 Pod。
等待调度的非抢占式 Pod 将留在调度队列中,直到有足够的可用资源, 它才可以被调度。
非抢占式 Pod,像其他 Pod 一样,受调度程序回退的影响。 这意味着如果调度程序尝试这些 Pod