Kubernetes 原生 CI/CD 构建框架 Argo 详解!

2021年11月23日 阅读数:1
这篇文章主要向大家介绍Kubernetes 原生 CI/CD 构建框架 Argo 详解!,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

做者:FogDong(才云)python

编辑:Bach(才云)git

什么是流水线?

在计算机中,流水线是把一个重复的过程分解为若干个子过程,使每一个子过程与其余子过程并行进行的技术,也叫 Pipeline。因为这种 s工做方式与工厂中的生产流水线十分类似, 所以也被称为流水线技术。从本质上讲,流水线技术是一种时间并行技术。以“构建镜像”过程为例:github

image.png

在每一次构建镜像中,咱们都须要拉下代码仓库中的代码,进行代码编译,构建镜像,最后推往镜像仓库。在每一次代码更改事后,这一过程都是不变的。使用流水线工具能够极大的提高这一过程的效率,只须要进行简单的配置即可以轻松的完成重复性的工做。这样的过程也被称之为 CI。docker

上图流程中使用的是 Jenkins。Jenkins 做为老牌流水线框架被你们所熟知。在云原生时代,Jenkins 推出了 Jenkins X 做为基于 Kubernetes 的新一代流水线,另外云原生时代还诞生了两大流水线框架—— Argo 和 Tekton。本文就详细介绍了 Argo 的相关内容。bash

《Kubernetes 原生 CI/CD 构建框架 Tekton 详解!》详细介绍了 Tekton 的相关内容。app

Argo

Argo Workflows 是一个开源的容器原生的工做流引擎,可在 Kubernetes 上编排并行做业。Argo Workflows 实现为 Kubernetes CRD。框架

Quick Start

Argo 基于 Kubernetes,能够直接使用 kubectl 安装,安装的组件主要包括了一些 CRD 以及对应的 controller 和一个 server。机器学习

image.png

注意,上述安装只会执行同 namespace 内的 Workflow,cluster install 详见文档。文档地址:https://github.com/argoproj/argo/blob/master/docs/installation.mdide

三级定义

要了解 Argo 定义的 CRD,先从其中的三级定义入手。概念上的从大到小分别为 WorkflowTemplate、Workflow、template,这些资源的命名有些类似,要注意分辨。工具

Template

从最简单的 template 提及,一个 template 有多种类型,分别为 container、script、dag、steps、resource 以及 suspend。对于 template,咱们能够简单的将其理解为一个 Pod ——container/script/resource 类型的 template 都会去实际控制一个 Pod,而 dag/steps 类型的 template 则是由多个基础类型的 template (container/script/resource)组成的。

  • container:最多见的模板类型,与 Kubernetes container spec 保持一致。

  • script:该类型基于 Container,支持用户在 template 定义一段脚本,另有一个 Source 字段来表示脚本的运行环境。

  • resource:该类型支持咱们在 template 中对 kubernetes 的资源进行操做,有一个 action 字段能够指定操做类型,如 create, apply, delete 等,而且支持设定相关的成功与失败条件用于判断该 template 的成功与失败。

  • suspend:Suspend template 将在一段时间内或在手动恢复执行以前暂停执行。能够从 CLI (使用 argo resume)、API 或 UI 恢复执行。

  • steps:Steps Template 容许用户以一系列步骤定义任务。在 Steps 中,[--] 表明顺序执行,[-] 表明并行执行。

  • dag:DAG template 容许用户将任务定义为带依赖的有向无环图。在 DAG 中,经过 dependencies设置在特定任务开始以前必须完成的其余任务。没有任何依赖项的任务将当即运行。有关 DAG 的详细逻辑可见源码 https://github.com/argoproj/argo/blob/master/workflow/controller/dag.go#L204

Workflow

在一个 Workflow 中,其 spec 中有一个名为 templates 的字段,在其中至少须要一个 template 做为其组成的任务。

一个最简单的 hello world 例子以下:

image.png

在这个例子中,该 Workflow 的 templates 字段中指定了一个类型为 container 的 template,使用了 whalesay 镜像。

下面是一个稍微复杂的 workflow:

image.png

WorkflowTemplate

WorkflowTemplate 至关于 Workflow 的模板库,和 Workflow 同样,也由 template 组成。用户在建立完 WorkflowTemplate 后,能够经过直接提交它们来执行 Workflow。

image.png

Workflow Overview

image.png

在了解了 Argo 的三级定义后,咱们首先来深刻一下 Argo 中最为关键的定义,Workflow。Workflow 是 Argo 中最重要的资源,有两个重要的功能:

  • 定义了要执行的工做流。

  • 存储了工做流的状态。

因为这些双重职责,Workflow 应该被视为一个 Active 的对象。它不只是一个静态定义,也是上述定义的一个“实例”。

Workflow Template 的定义与 Workflow 几乎一致,除了类型不一样。正由于 Workflow 既能够是一个定义也能够是一个实例,因此才须要 WorkflowTemplate 做为 Workflow 的模板,WorkflowTemplate 在定义后能够经过提交(Submit)来建立一个 Workflow。

而 Workflow 由一个 entrypoint 及一系列 template 组成,entrypoint 定义了这个 workflow 执行的入口,而 template 会实际去执行一个 Pod,其中,用户定义的内容会在 Pod 中以 Main Container 体现。此外,还有两个 Sidecar 来辅助运行。

Sidecar

在 Argo 中,这些 Sidecar 的镜像都是 argoexec。Argo 经过这个 executor 来完成一些流程控制。

Init

当用户的 template 中须要使用到 inputs 中的 artifact 或者是 script 类型时(script 类型须要注入脚本),Argo 都会为这个 pod 加上一个 Init Container —— 其镜像为 argoexec,命令是 argoexec init。

在这个 Init Container 中,主要工做就是加载 artifact:

image.png

Wait

除了 Resource 类型外的 template,Argo 都会注入一个 Wait Container,用于等待 Main Container 的完成并结束全部 Sidecar。这个 Wait Container 的镜像一样为 argoexec,命令是 argoexec wait。(Resource 类型的不须要是由于 Resource 类型的 template 直接使用 argoexec 做为 Main Container 运行)

image.png

Inputs and Outputs

在运行 Workflow 时,一个常见的场景是输出产物的传递。一般,一个 Step 的输出产物能够用做后续步骤的输入产物。在 Argo 中,产物能够经过 Artifact 或是 Parameter 传递。

Artifact

要使用 Argo 的 Artifact,首先必须配置和使用 Artifact 存储仓库。具体的配置方式能够经过修改存有 Artifact Repository 信息的默认 Config Map 或者在 Workflow 中显示指定,详见 配置文档,在此不作赘述。下表为 Argo 支持的仓库类型。

image.png

一个简单的使用了 Artifact 的例子以下:

image.png

默认状况下,Artifact 被打包为 tar 包和 gzip 包,咱们也可使用 archive 字段指定存档策略。

在上面的例子里,名为 whalesay 的 template 使用 cowsay 命令生成一个名为 /tmp/hello-world.txt 的文件,而后将该文件做为一个名为 hello-art 的 Artifact 输出。名为 print-message 的 template 接受一个名为 message 的输入 Artifact,在 /tmp/message 的路径上解包它,而后使用 cat 命令打印 /tmp/message 的内容。

在前面 Sidecar 介绍中提到过,Init Container 主要用于拉取 Artifact 产物。这些 Sidecar 正是产物传递的关键。下面,咱们经过介绍另外一种产物传递的方式来体验 Argo 中传递产物的关键。

Scripts

先来看一个简单的例子:

image.png

在上面的例子中,有两个类型为 script 的 template,script 容许使用 source 规范脚本主体。这将建立一个包含脚本主体的临时文件,而后将临时文件的名称做为最后一个参数传递给 command(执行脚本主体的解释器),这样即可以方便的执行不一样类型的脚本(bash、python、js etc)。

Script template 会将脚本的标准输出分配给一个名为 result 的特殊输出参数从而被其余 template 调用。在这里,经过 {{steps.generate.outputs.result}} 便可获取到名为 generate 的 template 的脚本输出。

{{xxx}} 是 Argo 固定的变量替换格式:

那么,容器内部应该如何获取这个脚本输出呢?

咱们回到 Sidecar,在 Wait Container 中,有这样一段逻辑:

image.png
image.png

再来看看这个 Wait Container 的 Volume Mount 状况:

image.png

如今就十分明确了,Wait Container 经过挂载 docker.sock 以及 service account,获取到 Main Container 中的输出结果,并保存到 Workflow 中。固然,由于 Workflow 中保存了大量的信息,当一个 Workflow 的 Step 过多时,整个 Workflow 的结构会过于庞大。

Parameter

Parameter 提供了一种通用机制,能够将步骤的结果用做参数。Parameter 的工做原理与脚本结果相似,除了输出参数的值会被设置为生成文件的内容,而不是 stdout 的内容。如:
image.png

Volume

这并非 Argo 处理产物传递的一种标准方式,可是经过共享存储,咱们显然也能达到共通产物的结果。固然,若是使用 Volume,咱们则无需借助 Inputs 和 Outputs。

在 Workflow 的 Spec 中,咱们定义一个 Volume 模板:

image.png

并在其余的 template 中 mount 该 volume:

image.png

其余流程控制功能

循环

在编写 Workflow 时,可以循环迭代一组输入一般是很是有用的,以下例所示:

image.png

在源码实现中,将会去判断 withItems,若是存在,则对其中的每一个元素进行一次 step 的扩展。

image.png

条件判断

经过 when 关键字指定:

image.png

错误重尝

image.png

递归

Template 能够递归地相互调用,这是一个很是实用的功能。例如在机器学习场景中:能够设定准确率必须知足一个值,不然就持续进行训练。在下面这个抛硬币例子中,咱们能够持续抛硬币,直到出现正面才结束整个工做流。

image.png

如下是两次执行的结果,第一次执行直接抛到正面,结束流程;第二次重复三次后才抛到正面,结束流程。

image.png

退出处理

退出处理是一个指定在 workflow 结束时执行的 template,不管成功或失败。

image.png

对比 Tekton

相较于 Tekton 而言,Argo 的流程控制功能更加丰富。拥有着循环、递归等功能,这对于一些机器学习的场景都是十分适用的。而 Argo 社区对本身的定位也是 MLOps、AIOps、Data/Batch Processing,这也正是 Kubeflow Pipeline 底层基于 Argo 的缘由(尽管 KFP 也在作 Tekton 的 backend)。

可是在权限控制方面,Argo 作的就不如 Tekton,我我的认为,Tekton 的结构定义更为清晰。两者各有优劣,能够根据本身的需求进行选择。

参考文档