乐趣区

关于kubernetes:Kubernetes-原生-CICD-构建框架-Argo-详解

作者:FogDong(才云)

编辑:Bach(才云)

什么是流水线?

在计算机中, 流水线是把一个反复的过程合成为若干个子过程,使每个子过程与其余子过程并行进行的技术,也叫 Pipeline。因为这种 s 工作形式与工厂中的生产流水线十分相似,因而也被称为流水线技术。从实质上讲,流水线技术是一种工夫并行技术。以“构建镜像”过程为例:

在每一次构建镜像中,咱们都须要拉下代码仓库中的代码,进行代码编译,构建镜像,最初推往镜像仓库。在每一次代码更改过后,这一过程都是不变的。应用流水线工具能够极大的晋升这一过程的效率,只须要进行简略的配置便能够轻松的实现重复性的工作。这样的过程也被称之为 CI。

上图流程中应用的是 Jenkins。Jenkins 作为老牌流水线框架被大家所熟知。在云原生时代,Jenkins 推出了 Jenkins X 作为基于 Kubernetes 的新一代流水线,另外云原生时代还诞生了两大流水线框架—— Argo 和 Tekton。本文就具体介绍了 Argo 的相干内容。

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

Argo

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

Quick Start

Argo 基于 Kubernetes,能够间接应用 kubectl 装置,装置的组件次要包含了一些 CRD 以及对应的 controller 和一个 server。

留神,上述装置只会执行同 namespace 内的 Workflow,cluster install 详见文档。文档地址:https://github.com/argoproj/a…

三级定义

要理解 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/a…。

Workflow

在一个 Workflow 中,其 spec 中有一个名为 templates 的字段,在其中至多须要一个 template 作为其组成的工作。

一个最简略的 hello world 例子如下:

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

上面是一个略微简单的 workflow:

WorkflowTemplate

WorkflowTemplate 相当于 Workflow 的模板库,和 Workflow 一样,也由 template 组成。用户在创立完 WorkflowTemplate 后,能够通过间接提交它们来执行 Workflow。

Workflow Overview

在理解了 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:

Wait

除了 Resource 类型外的 template,Argo 都会注入一个 Wait Container,用于期待 Main Container 的实现并完结所有 Sidecar。这个 Wait Container 的镜像同样为 argoexec,命令是 argoexec wait。(Resource 类型的不须要是因为 Resource 类型的 template 间接应用 argoexec 作为 Main Container 运行)

Inputs and Outputs

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

Artifact

要应用 Argo 的 Artifact,首先必须配置和应用 Artifact 存储仓库。 具体的配置形式能够通过批改存有 Artifact Repository 信息的默认 Config Map 或者在 Workflow 中显示指定,详见 配置文档,在此不做赘述。下表为 Argo 反对的仓库类型。

一个简略的应用了 Artifact 的例子如下:

默认状况下,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

先来看一个简略的例子:

在下面的例子中,有两个类型为 script 的 template,script 容许应用 source 标准脚本主体。这将创立一个蕴含脚本主体的临时文件,而后将临时文件的名称作为最初一个参数传递给 command(执行脚本主体的解释器),这样便能够不便的执行不同类型的脚本(bash、python、js etc)。

Script template 会将脚本的规范输入调配给一个名为 result 的非凡输入参数从而被其余 template 调用。在这里,通过 {{steps.generate.outputs.result}} 即可获取到名为 generate 的 template 的脚本输入。

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

  • 对于变量的格局详见文档,文档地址:https://github.com/argoproj/a…
  • 对于变量替换的逻辑详见源码,源码地址:https://github.com/argoproj/a…

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

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


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

当初就十分明确了,Wait Container 通过挂载 docker.sock 以及 service account,获取到 Main Container 中的输入后果,并保留到 Workflow 中 。当然,因为 Workflow 中保留了大量的信息,当一个 Workflow 的 Step 过多时,整个 Workflow 的构造会过于宏大。

Parameter

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

Volume

这并不是 Argo 解决产物传递的一种规范形式,然而通过共享存储,咱们显然也能达到共通产物的后果。当然,如果应用 Volume,咱们则无需借助 Inputs 和 Outputs。

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

并在其余的 template 中 mount 该 volume:

其余流程管制性能

循环

在编写 Workflow 时,可能循环迭代一组输出通常是十分有用的,如下例所示:

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

条件判断

通过 when 关键字指定:

谬误重尝

递归

Template 能够递归地互相调用 ,这是一个十分实用的性能。例如在机器学习场景中:能够设定准确率必须满足一个值,否则就继续进行训练。在上面这个抛硬币例子中,咱们能够继续抛硬币,直到呈现侧面才完结整个工作流。

以下是两次执行的后果,第一次执行间接抛到侧面,完结流程;第二次反复三次后才抛到侧面,完结流程。

退出解决

退出解决是一个指定在 workflow 完结时执行的 template,无论胜利或失败。

比照 Tekton

相较于 Tekton 而言,Argo 的流程管制性能更加丰盛。领有着循环、递归等性能,这对于一些机器学习的场景都是非常实用的。而 Argo 社区对本人的定位也是 MLOps、AIOps、Data/Batch Processing,这也正是 Kubeflow Pipeline 底层基于 Argo 的起因(只管 KFP 也在做 Tekton 的 backend)。

然而在权限管制方面,Argo 做的就不如 Tekton,我集体认为,Tekton 的构造定义更为清晰。二者各有优劣,能够依据本人的需要进行抉择。

参考文档

  • Argo Roadmap:https://github.com/argoproj/a…
  • Argo Examples:https://argoproj.github.io/ar…
  • Argo Source Code:https://github.com/argoproj/argo
退出移动版