Kubernetes学习笔记——Pod调度

0x01. Deployment/RC 全自动调度

效果:在集群内始终维持用户指定的副本数量

使用:spec.replicas

原理:系统自动调度算法。由 Master 的 Scheduler 经过一系列算法计算得出,用户无法干预调度过程和结果。

0x02. NodeSelector

效果:通过 Node 的标签和 Pod 的 nodeSelector 属性进行匹配,将 Pod 调度到指定的 Node 上

使用:

  1. 为目标 Node 打标签
1
kubectl label nodes <node-name> <label-key>=<label-value>
  1. 在 Pod 定义中加上 nodeSelector 的设置
1
2
3
4
#pod.yaml
---
nodeSelector:
<label-key>: <your-selected-label-name>

补充:

  • 如果多个 Node 定义了相同的标签,则会根据调度算法从这组 Node 中挑选一个可用的 Node 进行调度
  • 若 Pod 指定的 nodeSelector 条件集群中不存在符合的节点,则该 Pod 无法被成功调度,即使集群中还有可用的 Node

0x03. 亲和性调度

篇幅原因,另外一篇单独记录

0x04. 污点(Taints)和容忍(Tolerations)

效果:Pod 无法在标记了 Taint 属性的节点上运行, 同时,设置了 Tolerations 的 Pod 可以运行在标注了 Taint 的 Node 上

使用:

  1. 为 Node 设置 Taint 信息
1
kubectl taint nodes node1 key1=value1:NoSchedule
  1. 在 Pod 的配置文件中配置 tolerations 属性
1
2
3
4
5
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchdule"

补充:

  • Taint 和 Toleration 声明需要保持对应一致,且 operator 需要为 Exists 或者 Equal(Equal 需要指定相等 value);
  • 空 key 配合 Exists 能够匹配所有键值,空 effect 匹配所有 effect;
  • effect 取值也可以设置为 Prefer,例如 PreferNoSchedule,视为软限制;
  • 同个 Node 可以设置多个 Taint,对应的,Pod 也可以设置多个 Toleration。

0x05. DaemonSet

效果:在每个 Node 上调度运行同一个(种)Pod,例如日志采集、性能监控、存储的 Daemon 进程

使用:

1
2
apiVersion: extensions/v1beta1
kind: DaemonSet

补充:

除了使用系统内置算法在每台 Node 上调度外,也可以在 Pod 定义中使用 NodeSelector 或者 NodeAffinity 来指定满足料件的 Node 范围进行调度

0x06. 批处理调度

效果:并行/串行启动多个计算进程去处理一批工作项(Work Item,下称 WI),处理完成后,批处理任务结束

任务模式分类:

  • Job Template Expansion 模式:Job 和 WI 一对一对应,适用于 WI 数量少,但是单 WI 处理数据量大的场景;
  • Queue with Pod Per Work Item 模式:使用一个任务队列存放 WI,Job 作为 Consumer 去完成 WI(对应的,Job 会启动多个 Pod,每个 Pod 对应一个 WI),可用 MQ 实现;
  • Queue with Variable Pod Count 模式:与 2 模式类似,但是 Job 启动的 Pod 数量是可变的,可用 Redis 或数据库实现;
  • Single Job with Static Work Assignment 模式:一个 Job 产生多个 Pod,但是采用程序静态方式分配任务(Kubernetes 不支持,书中所写)。

Job 分类:

  • Non-parallel Jobs:一个 Job 启动一个 Pod,Pod 正常结束则 Job 结束。
  • Parallel Jobs with a fixed completion count:Job 会启动多个 Pod(数目为 spec.completions),正常结束的 Pod 达到这个数目后 Job 结束。spec.parallelism 可以用来控制并行度。
  • Parallel Jobs with a work queue:WI 在 Queue 中存放,无法设置并行度参数。每个 Pod 都能够独立判断是否还有任务需要处理,同时,一个 Pod 成功结束则其他 Pod 必定处于即将结束、退出的状态,且 Job 不会再启动新的 Po)。所有 Pod 结束,且至少一个 Pod 成功结束则 Job 算成功结束。

(个人理解:上述的规则说明其实是在说所有 Pod 表现为同一整体,Pod 启动失败会重启是一种容错机制。然而从整个过程的跨度来看,无需关心失败启动的数目,只要不是所有 Pod 全部失败结束,只需存在一个成功结束的 Pod 即表明 Job 流程内的其他划分任务都正常完成,整体任务也已成功完成。)

0x07. 定时任务

效果:定期触发任务执行

使用:

  1. 在 API Server 启动进程上添加配置参数
1
--runtime-config=batch/v2alpha1=true
  1. 编写 Cron Job 配置文件
1
2
3
4
5
6
#cron.yaml
apiVersion: batch/v2alpha1
kind: CronJob
---
spec:
schedule: "*/1 * * * *"
  1. schedule 格式如下
1
Min Hour DayOfMonth Month DayOfWeek
  1. *表示任意值,即每个时间单元节点都会触发

/表示开始触发的时间,例如 5/20,表明第一次触发在第 5 个时间单位,此后每隔 20 个时间单位触发

0x08. 自定义调度器

在 Pod 中提供自定义的调度器名称,则默认调度器就会失效,转而使用指定的调度器完成对应 Pod 的调度,自定义的调度器需要通过 kube-proxy 来运行,如果自定义调度器始终未启动,则 Pod 将会卡 Pending 状态。

1
2
3
4
5
apiVersion: v1
kind: Pod
---
spec:
schedulerName: my-scheduler

0x09. 补充

  • Admission controller 需要仔细研究
  • TaintBasedEviction 和 Eureka 中的驱逐机制(包括 SELF PRESERVATION)是否在设计层面上有一定的共通点
  • 自定义调度器实现有时间需要手动验证一次