专栏首页01ZOO任务流引擎简介
原创

任务流引擎简介

任务流简介

任务比如 k8s 概念中的 job,一般指的是短期的会结束的一个离线任务,而人物流就是将一组任务组织起来的流程。比如下面的这个流程。

image.png
  • 任务流中除了支持简单的串行处理之外,通常还会支持 并发,条件,skip 等影响执行流程的功能
  • 任务流一般是 DAG,即不支持有环操作,在大部分场合这也能满足绝大部分需求了
  • 每个 Step 通常除了 action 之外,通常还会有输入输出,这种输入输出 可能是一段数据,也可能是一个打包好的文件,甚至一个 测试生成的 html 页面等等
  • 任务流的启动 可以是手动触发,也可能是各种事件处罚,比如一个 github merge事件。也可能是 cron 处罚,即周期执行。

任务流的例子

Jenkins

最早接触任务流工具应该是在 jenkins, 实际上 CI/CD 也是任务流最常见的场景之一,不过 jenkins 并不局限于 ci/cd (大部分 ci/cd 工具也是这种设计,采用 通用工作流 + 业务插件的形式支持具体的业务)

image.png

jenkins 的任务流有几种表达方式

  • 在页面上配置
  • 使用 JenkinsFile 表达,而 JenkinsFile 表达也有两种形式,一种成为 描述性语法:Declarative Pipeline,语法比较简单易用,另一种为脚本语法 Scripted Pipeline,内部使用 Groovy 语言进行编辑,有一定的上手门槛,但是非常灵活,功能强大
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any 
    stages {
        stage('Build') { 
            steps {
                // 
            }
        }
        stage('Test') { 
            steps {
                // 
            }
        }
        stage('Deploy') { 
            steps {
                // 
            }
        }
    }
}
Jenkinsfile (Scripted Pipeline)
node {  
    stage('Build') { 
        // 
    }
    stage('Test') { 
        // 
    }
    stage('Deploy') { 
        // 
    }
}

事实上 Jenkins 还是 CI/CD 领域应用最多的任务流工具,其强大的社区,各种强大的插件体系,使得他在十多年后依然不过时( Jenkins 的前身 Hudson 是在 2004 发布的),最近几年 Jenkins 又支持了 容器,K8S 的支持,使得他依然是这个领域最好用的工具。

在这个领域的的工具还有很多,比如在 github 上就内置了官方的 github actions工具,circle ci 等等,在这个 容器盛行的时代,构建这样一个 CI/CD 工具远没有当年构建 Jenkins 的门槛那么高了,相关的一些基于容器、K8S 主打灵活,高性能的开源工作流工具也层出不穷。

Drone

drone 是容器时代的任务流工具中最有代表性的开源工具之一,他的任务流的表达方式和其他同时期的产品非常类型,都是 yaml 的形式。顺应时代,drone 支持在 docker, kubernetes 或者直接利用 ssh 方式运行,不过我们这里只关注 docker 和 kubernetes 类型。

  • 每一个 Step其实都是一个容器,在 kubernetes 上则是一个 pod,drone 的插件体系也是基于此构建。所谓插件 就是一个定制的镜像,接受一些参数(从环境变量)进行操作,输出参数,这种设计使得定制、增加插件的成本非常低,这可能也是 drone 活跃的重要原因之一(其实这种做法现在已经非常常见了)
  • Step 之间使用 环境变量传递元数据
  • Step 通过内置的一个内存消息队列进行驱动,不依赖外部组件
name: default

kind: pipeline
type: docker

steps:
- name: backend
  image: golang
  commands:
    - go get
    - go build
    - go test

- name: frontend
  image: node:6
  commands:
    - npm install
    - npm test

- name: publish
  image: plugins/docker
  settings:
    repo: octocat/hello-world
    tags: [ 1, 1.1, latest ]
    registry: index.docker.io

- name: notify
  image: plugins/slack
  settings:
    channel: developers
    username: drone

argo 和 tekton

argo 和 Tekton 都是 Kubernetes 原生的工具,两者的实现上也很类似。

argo

argo 的也是用 yaml 描述工作流,除了传统的 dag 模式,argo 也支持 workflow 模式。相比而言,dag 模式一般比较简单,大部分 ci/cd 场合也比较够用,实现的事情用下面的 几行代码 就可以描述

start
for node in nodes:
    if all(node's dependency is done):
        do(node)
done 

而 workflow 模式则是一个状态机, workflow 模式的实现更为复杂,也更灵活。用这种模式可以实现有环的任务,比如 执行一个任务,直到某条件满足。

if node's State is not start:
    start(node)
if node's State is not done:
    do(node's Next)

下面是 argo workflow 的一个具体例子

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: steps-
spec:
  entrypoint: hello-hello-hello

  # This spec contains two templates: hello-hello-hello and whalesay
  templates:
  - name: hello-hello-hello
    # Instead of just running a container
    # This template has a sequence of steps
    steps:
    - - name: hello1            # hello1 is run before the following steps
        template: whalesay
        arguments:
          parameters:
          - name: message
            value: "hello1"
    - - name: hello2a           # double dash => run after previous step
        template: whalesay
        arguments:
          parameters:
          - name: message
            value: "hello2a"
      - name: hello2b           # single dash => run in parallel with previous step
        template: whalesay
        arguments:
          parameters:
          - name: message
            value: "hello2b"

  # This is the same template as from the previous example
  - name: whalesay
    inputs:
      parameters:
      - name: message
    container:
      image: docker/whalesay
      command: [cowsay]
      args: ["{{inputs.parameters.message}}"]

argo 的 workflow 里面也是类似 drone,step 由容器实现,并且做得更为直接。

在 argo 上,kubeflow 社区就实现了针对机器学习领域的 pipeline 工具 KubeFlow-Pipeline

更多关于 argo 的原理可以参考这篇文章

tekton

tekton 来自Knative的build模块 做的事情和 argo 也大同小异,他扩展比较灵活,可以用来快速定制实现所需功能。tekton 的描述语法例子如下

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: echo-hello-world
spec:
  steps:
    - name: echo
      image: ubuntu
      command:
        - echo
      args:
        - "Hello World"

除了 task,tekton 还定义了 如 PipelineResource, TaskRun 等多种资源,描述性语法。目前由于实现原理的限制(通过扩展 kubernetes api resources,watch 资源变化实现,类似 operator),决定了 argo 和 tekton 都不能水平扩容,这一点限制了系统的 scale 能力,吞吐量有一定限制,但是对于 ci/cd 的场景,应该是很够用了。

关于 tekton 的特点,这篇文章 做了详细的对比

brigade

brigade 也是一个基于 kubernetes 的 pipeline 工具,作者是大名鼎鼎的 helm(公司被微软收购) 的作者,这个工具值得一提的原因是其设计非常有趣,他的语法不使用常见的 yaml 描述,而是采用 js 的方式描述。比如下面这个例子。

const { events, Job } = require("brigadier");

events.on("simpleevent", (e, p) => {  // handler for a SimpleEvent
  var echo = new Job("echosimpleevent", "alpine:3.8");
  echo.tasks = [
    "echo Project " + p.name,
    "echo event type: $EVENT_TYPE",
    "echo payload " + JSON.stringify(e.payload)
  ];
  echo.env = {
    "EVENT_TYPE": e.type
  };
  echo.run();
});

由于 kubernetes 对于部署和标准化环境的控制,以及 kubenetes 提供基础设施的强大能力,使得在 kubernetes 上实现类似的工具变得门槛很低,笔者也在早年也做过类似的玩具项目 https://github.com/arlert/kubepipe,看一下他的语法,是不是更 tekton/argo 有些相似呢。

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  restartPolicy: Never
  containers:
  - name: c
    image: alpine
    command: ["sh", "-c", "echo running pod1"]
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  restartPolicy: Never
  containers:
  - name: c
    image: alpine
    command: ["sh", "-c", "echo running pod2"]
---
apiVersion: v1
kind: Pod
metadata:
  name: pod3
spec:
  restartPolicy: Never
  containers:
  - name: c
    image: alpine
    command: ["sh", "-c", "echo running pod3"]
---
apiVersion: v1
kind: Pipe
metadata:
  name: pipe
spec:
  stages:
  - name: stage1
    jobs: 
    - pod1
  - name: stage2
    jobs: 
    - pod2
  - name: stage3
    jobs: 
    - pod3

总结

上面讲的工具大部分是 pipeline工具,使用的场景也在 ci/cd 上(尽管大部分工具实际也可以用来干别的事情),这种工具非常多,各大云厂商也提供了各种 workflow/pipeline 引擎比如 aws的 Simple WorkFlow,AWS Step Functions,Azure的 Pipeline 服务,ML Pipeline。

成熟的任务流引擎,应该有如下4层架构(图和分层方式来自 https://juejin.im/post/5ee2f6ece51d457848686ef8

image.png
  • 第一层:用户交互层。如:模板语法规则,Console界面等
  • 第二层:API持久化层。如:模板记录,历史执行记录等
  • 第三层:引擎实例层。如:能否水平扩容,流程是否有优先级等
  • 第四层:驱动层。如:一个步骤能干什么活。跑一个容器还是跑一个Spark任务。

选择或者实现一个任务流引擎的时候需要从这四方面判断它的优劣,比如大部分开源工具 在第一层和第二层的支持较好,但是 argo 和 tekton 不能水平扩容,第三层的实现有些不足。同时 这两个工具又局限于 kubernetes 语境,其第四层的设计也比较局限。不过第四层的设计一般取决于具体的场景,比如在云上,云厂商首先会支持一个通用 serveless 函数,在机器学习平台,会支持运行一个 spark 任务等等。

由于任务流工具应用的广阔场景,CNCF 也忍不住指定了基于云原生的 workflow 标准

看下 cncf 的 spec 可以看出 cncf的标准指定得还是比较复杂, 支持 subflow,foreach,delay, paralle 等特性,而云产商如 aws 实现的类似产品 spec 则更为简单. 目前还没有知名的 cncf 标准的 workflow 实现出现,不过可以预期,以 cncf 的影响力,类似的开源项目很快就会出现,这个领域还有很多机会。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用 go 实现 lua 虚拟机

    下面依次介绍上面的一些步骤,本文旨在一篇文章写清楚大概流程,具体的细节将会忽略,实际的实现也会尽可能的简化,本文主要参考 自己动手实现 lua,和 gopher...

    王磊-AI基础
  • yarn 学习笔记(对比 kubernetes 调度)

    ApplicationMaster(AM),用户提交的每个应用程序都需要包含一个AM, 作用为:

    王磊-AI基础
  • DDIA 笔记

    王磊-AI基础
  • python变量,输入、输出、判断、循环

    声明变量 name = 'ajune' 变量赋值 name = 'ajune' name1 = name

    py3study
  • redis缓存数据库

    NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应...

    菲宇
  • 安静100分钟理解js面向对象

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head>...

    前朝楚水
  • Echart在Openlayers的应用-航班的炫光特效

    在前两篇文章中讲到了echart在openlayers2中的应用,地图统计图与热力图的实现,在本文中介绍openlayers中结合echart实现航班的炫光特效...

    lzugis
  • 【python】redis模块

    windows下载地址:https://github.com/MSOpenTech/redis/releases

    py3study
  • python PAM30 PAMIE

    安装PAM30,由于没有直接的安装文件 需要下载压缩包 然后把压缩吧解压至python/Lib/site-package/下

    py3study
  • 【Python基础】函数的返回

    很多时候,函数并非直接输出,相反,它可以处理一些数据,并返回一个值或者一组值,称之为返回值。

    DataScience

扫码关注云+社区

领取腾讯云代金券