《Containerized Workflow Scheduling》阅读笔记

论文阅读:容器环境下,工作流调度的研究。

Posted by Jiajie Wu on July 10, 2019

这是一篇2018年阿姆斯特丹艾萨克大学的研究生论文。文章提出了如何在容器化环境中改变工作流中各个task执行顺序的方法。同时,通过这种方法,在Kubernetes和Docker Swarm两种容器环境下,对比了关键路径(Critical Path)优先调度和Batch方式执行的不同,对工作流总执行时间的影响。


现状和问题

文章开篇,提出了一个现状——部分WMS(Workflow Management System)已经提供了使用容器的操作,但是,几乎没有研究工作将WMS调度算法和容器调度算法结合起来容器+WMS的结合,没有一个规范和标准

容器调度和工作流调度的差异体现在两点:

  1. 先后依赖关系
  2. 执行顺序
  • 先后依赖关系:容器调度程序不考虑容器化task的上下文,既容器调度程序不知道其他task可能依赖于某个容器内的某个task,或者这个task本身依赖于其他容器内的task。

  • 执行顺序:容器调度一般没有严格的先后顺序,而工作流调度通常都会将tasks排序执行。

基于上面这两点,提出了研究的问题——

How can we order the execution of a containerized workflow on a container scheduler?

方法和设计

本文提出的方法是:

  1. 在Kubernetes上,给容器(task)设置优先级。
  2. 在Docker Swarm上,手动分次提交容器(task)。

实验中还设计了:

  1. Python应用程序:1) 用来估计给定时间内task的cpu和memory使用情况(使用Stress);2) 管理工作流中的依赖。分别写了Docker SwarmKubernetes的。
  2. 实验用的工作流:为了能够更好地进行实验,该工作流包含很多个容器化的tasks,且拥有一条明显的关键路径(Critical Path)。

· Python应用程序执行过程:

  1. 提交容器化的task给调度器;
  2. 将执行时间+内存参数传给容器(通过唯一的容器ID)
  3. 提交容器之后,该python应用程序启动一个线程,这个线程在 Consul 中监视这个 key。当 key 被 set,线程返回,这表示任务结束。
  4. 管理workflow的依赖。在task的依赖都就绪时,才提交task

· 实验用的工作流:

能够明显看出,下图中标红的为一条关键路径。 工作流图片

实验和分析

实验

Kubernetes 上执行工作流,使用Job 定义task对应的容器。

Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。

Docker Swarm 没有像Kubernetes一样的资源定义(Job),Ellis在博客中提供了两种方法来解决这一限制。第一种方法,使用他自己维护的Golang CLI;第二种方法,使用Service,并将重启策略(Restart Policy)设置为None。这里使用第二种方法,具体实现可见上一节中Docker Swarm对应的Python应用程序。

另外,文中提到,实验中,Kubernetes和Docker Swarm 中的容器都被设置为「使用各自的资源保留flag来保留tasks所需的Memory」(configure the containers in both Kubernetes and Swarm to reserve the amount of memory the task requires using the respective resource reservation flags)。容器调度程序在调度容器时,会用到这个设置,从而确保容器不会直接竞争资源

分析

· 容器执行顺序

当存在可用节点时,Kubernetes和Docker Swarm都会从队列中选择一个看似 Random 的容器,调度到节点上运行。容器的调度顺序和提交顺序并不一致,这使得容器调度程序的队列成为一种不可预测和不可靠的任务排序方法

· 自定义调度器

Kubernetes 支持自定义调度(Custom Scheduler),但它们和 default scheduler 一样,受到上述情况限制。

Docker Swarm 支持修改调度策略,但只能改变 容器选择节点 的方式。为了应对这一点,文中提出,先提交关键路径上的 task,以及一部分其他 task。之所以还要提交一部分其他的task,是因为考虑到只提交关键路径的 task,不会刚好用尽所有可用资源,资源利用率可能会很低。

· 关键路径优先 vs Batch

在Kubernetes上,进行两个实验。第一个实验,优先调度关键路上的task;第二个实验,公平调度所有task。对比两个实验的workflow总执行时间。因为实验进行多次,所以结果取平均执行时间。

实验图片1

在Docker Swarm上,进行三个实验。第二个实验,提交所有task;第二个实验,保留5个task,直到关键路径的第一个task执行结束;第三个实验,保留10个task,直到关键路径的第一个task执行结束。

实验图片2

实验结果表明:

  1. 在Kubernetes上,工作流总执行时间,整体上比在Docker Swarm上要快。结果表明,关键路径优先能提高工作流执行效率(实验中提高了16s)。
  2. Doccker Swarm上,效果不明显,无法证明该方法能够有效提高工作流执行效率。

相关工作

尝试将 WFS 和 Container 结合的相关工作还有这些:

  1. Makeflow + Mesos:Makeflow是圣母大学CCL实验室开发的一个工作流管理系统,Work Queue是他们开发的一个跨机器构建大型应用的框架。他们为Mesos实现了一个批处理作业系统,并将其连接到 MakeFlow 和 Work Queue。。
  2. Applatix Argo:基于Kubernetes,但受到Kubernetes容器调度的限制
  3. Apache Airflow:正在尝试和Kubernetes结合

总结和感想

容器化工作流调度是一个较新的研究领域。相比传统的虚拟机,容器+工作流的结合势必会对工作流执行时间、资源利用率等等方面有很大的影响和改变。但是,我感觉在这方面的研究,目前似乎也不是很多,找到的相关论文相对比较少,大部分还是基于虚拟机环境,或者云环境。

这篇文章里提到的容器调度和工作流调度的不同,如何在 Kubernetes 和 Docker Swarm 上改变 task-容器 的执行顺序,个人觉得对之后这方面的研究会有很大的帮助和启发。

-END-

附论文连接:《Containerized Workflow Scheduling》


第一次尝试将阅读的论文写成博客,加上部署Git Page,在本地搭建jekyll,磕磕绊绊弄了三天(Mac本地部署遇到了好多别人都没遇到的问题,拖慢了工作计划)。期间,又重新回顾了好几次论文,写起来也不是特别顺,感觉问题还是有很多,不过总算是迈出了一小步。

最后,有什么问题,欢迎一起讨论~