
Kubernetes 工作流引擎:Argo(1)
作者 阳明
来源 | k8s技术圈(ID:kube100)
Argo 是 Applatix 推出的一个开源项目,为 Kubernetes 提供 container-native(工作流中的每个步骤是通过容器实现)工作流程。Argo 可以让用户用一个类似于传统的 YAML 文件定义的 DSL 来运行多个步骤的 Pipeline。该框架提供了复杂的循环、条件判断、依赖管理等功能,这有助于提高部署应用程序的灵活性以及配置和依赖的灵活性。使用 Argo,用户可以定义复杂的依赖关系,以编程方式构建复杂的工作流、制品管理,可以将任何步骤的输出结果作为输入链接到后续的步骤中去,并且可以在可视化 UI 界面中监控调度的作业任务。
Argo 简介
Argo V2 版本通过 Kubernetes CRD(Custom Resource Definition)来进行实现的,所以我们可以通过 kubectl 工具来管理 Argo 工作流,当然就可以和其他 Kubernetes 资源对象直接集成了,比如 Volumes、Secrets、RBAC 等等。新版本的 Argo 更加轻量级,安装也十分简单,但是依然提供了完整的工作流功能,包括参数替换、制品、Fixture、循环和递归工作流等功能。
Argo 中的工作流自动化是通过使用 ADSL(Argo 领域特定语言)设计的 YAML 模板(因为 Kubernetes 主要也使用相同的 DSL 方式,所以非常容易使用)进行驱动的。ADSL 中提供的每条指令都被看作一段代码,并与代码仓库中的源码一起托管。Argo 支持6中不同的 YAML 结构:
- 容器模板:根据需要创建单个容器和参数
- 工作流模板:定义一个作业任务(工作流中的一个步骤可以是一个容器)
- 策略模板:触发或者调用作业/通知的规则
- 部署模板:创建一个长期运行的应用程序模板
- Fixture 模板:整合 Argo 外部的第三方资源
- 项目模板:可以在 Argo 目录中访问的工作流定义
Argo 支持几种不同的方式来定义 Kubernetes 资源清单:Ksonnect、Helm Chart 以及简单的 YAML/JSON 资源清单目录。
安装
安装 Argo 非常简单,首先当然需要一个 Kubernetes 集群(1.9+版本),kubectl 工具以及访问集群的 kubeconfig 文件(默认位于 ~/.kube/config)。
Mac 系统:
Linux 系统:
安装完成后,可以使用下面命令校验是否安装成功:
然后安装控制器和 UI 界面:
安装完成后,为了访问方便,我们将 argo-ui 改成 NodePort 类型的 Service(当然也可以创建 Ingress 对象通过域名进行访问):
然后我们就通过上面的 32686 端口来访问 argo-ui 了:
到这里就证明 Argo 的基础环境就已经安装完成了。
基本的 Argo 工作流模板
下面是一个非常简单的模板,首先定义了一个工作流,创建一个带有两个容器的 Pod,其中一个容器带有 curl 命令,而另外一个容器是一个 nginx sidecar 容器,这里 curl 这个容器是“主”容器,用于轮询 nginx sidecar 容器,直到它准备好为请求提供服务为止。
将上面模板保存为名为 argo-base-template.yaml 的文件,然后可以使用 argo 命令来提交这个工作流:
当然同样的我们可以直接使用 kubectl 来进行安装,但是 Argo CLI 提供了更强大的功能,比如 YAML 校验、参数传递、重试等等功能。
上面就是我们定义的一个工作流,创建一个 Pod 并执行 Workflow 中定义的配置:
同样可以通过 argo logs查看容器日志,也可以通过 argo-ui 在页面上查看相关信息:
带条件的工作流模板
前面我们提到过 Argo 支持工作流执行过程中的条件语句。Argo 提供的 Coinflip 示例就描述了如何在模板中使用 “when”,其执行依赖于从父级接收的输出。
将 Coinflip 保存到本地:
上面的 Worflow 运行一个随机的整数脚本,常量为 0=heads、1=tails,调用特定模板(heads 或者 tails)取决于“flip-coin”任务的输出,如上面 Workflow 图中所示,flip-coin 任务执行 heads 任务只有当 heads 模板被执行的时候。
同样,使用 argo submit来提交 Coinflip 这个 Workflow:
可以看到这里出现了一个权限错误,Argo 官网上给出的解决方案是给 default:default 绑定上 admin 的 clusterrole 权限:
然后删除上面的 Workflow,重新创建:
上面的 Workflow 将会创建两个容器,一个是用于执行 randomint python 脚本,另外一个是用于根据脚本的执行结果执行的 tails 模板,如下所示,tails 模板根据 randomint 脚本的结果(result==tails)被调用执行了:
类似地,递归(递归调用模板)也可以添加到条件规范中,例如,下面的模板输出显示 flip-coin 模板执行 n 次,直到结果为 heads 为止,下载 flip-coin 递归模板示例:
我们可以简单对比下前面的 coinflip,基本上是一致的,唯一的区别就是 tails 模板重新指向了 coinflip,这样就形成了递归:
然后用同样的方法来提交这个 Workflow,可以通过 argoget命令来查看具体的执行步骤:
我们可以看到这里递归执行了4次,最后才出现 flip-coin 的模板输出 heads,这个时候递归才退出,每一次递归调用都会产生一个 Pod,加上最后的 heads 模板,所以一共会产生 5 个 Pod:
同样可以在 argo-ui 中查看这个 Workflow 的调用示意图:
带循环和参数的 Workflow 模板
Argo 可以很方便的迭代 Workflow 中的一组输入,也可以处理用户提供参数(比如:输入参数)。在下面的 Workflow 中,使用两个输入参数 “hello kubernetes”和 “hello argo”来执行 Whalesay 模板。
下载这里我们需要使用的 Workflow 示例:
不过需要注意,我们需要把 loops.yaml 文件里面的 withItems 修改成下面的参数值:
完整的 YAML 文件内容如下所示:
上面的模板包含一个单独的模板,通过使用一个 items 列表并根据提供的参数值数量来运行任务,所以,会创建两个 Pod,一个使用 “hello kubernetes”参数,另外一个使用 “hello argo”参数,同样使用 argo submit命令来创建这个 Workflow:
使用 argoget命令来查看这个 Workflow 的详细信息,可以看到迭代了两个步骤出来,当然就会产生两个 Pod:
我们去查看生成的两个 Pod 的日志信息,里面就包含上面的传入的两个参数 “hello kubernetes”和 “hello argo”的信息:
类似的我们还可以完成更加复杂的循环:循环迭代一组 items,动态生成 items 列表等,具体的实现我们直接查看 Argo GitHub 仓库上面提供的 example 样例:https://github.com/argoproj/argo/blob/master/examples/。
由 DAG(有向无环图)和步骤的依赖定义的多步骤工作流模板
Argo 允许用户使用简单的 Python 对象 DAG 启动多步骤的 Pipeline,还可以在工作流规范中定义多个模板(嵌套工作流)。
下载使用的示例文件:
Workflow 更详细的内容如下所示:
接下来我们来提交这个 Workflow:
然后使用 argoget命令来查看这个 Workflow 的详细信息:
同样在 argo-ui 中也可以查看到这个 Workflow 的依赖关系:
使用 Minio 进行制品管理和 Argo 集成
制品是任何工作流的一部分(比如:CI/CD 中),工作流中的步骤会生成制品,然后其他后续步骤可以使用这个制品。
我们这里使用 Minio 来作为制品仓库,Minio 是兼容 Amazon S3 API 的开源对象存储服务器。
首先先安装 Minio,我们这里使用 Helm 来快速的安装,如果对 Helm 的使用还不熟悉的,可以查看前面我们的文章:Kubernetes Helm 初体验。
我们这里指定了一个名为 my-bucket 的默认 Bucket,使用 NodePort 类型的 Service,另外需要注意的是我这里单纯为了测试,所以将 persistence.enabled 设置为了 false,对于线上环境一定要记得持久化数据:
到这里证明 Minio 就已经安装成功了,然后我们就可以通过 31311 这个 NodePort 端口访问 Minio 的 Dashboard 页面,我们可以使用默认的 accessKey(AKIAIOSFODNN7EXAMPLE) 和 secretKey(wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)登录:
然后我们需要把 Minio 和 Argo 集成在一起,通过编辑 workflow-controller configmap 来引用上面的 Minio Service 和 Secret,上面我们通过 Helm 安装 Minio 的时候会自动将默认的 accessKey 和 secretKey 添加到名为 minio 的 Secret 对象中去:
直接编辑 workflow-controller-configmap,按照如下方式添加上 Minio 相关配置:
编辑完成后我们就完成了 Minio 和 Argo 的集成。不过这里需要注意的是 Secret 对象是 namespace 作用域的,上面 ConfigMap 解析 Secret 对象是和我们使用的 Workflow 的 namespace 中获取 Minio Secret 的,所以如果 Minio 和 Workflow 不在同一个 namespace 下面,需要我们拷贝一份 Secret 到对应的 namespace 下面去,比如我们这里 Workflow 都在 default 这个 namespace 下面,那么我就需要在 default 下面创建相同的 Secret:(minio-secret.yaml)
创建上面的 Secret 对象:
然后下载我们这里使用到的 Workflow 示例文件:
详细的 Workflow 内容如下图所示:
上面 Workflow 包括两个步骤:
- 步骤1生成制品:使用 whalesay 模板生成制品
- 步骤2消费制品:使用步骤1中创建的制品并打印消息。
同样,我们使用 argo submit命令提交这个 Workflow:
我们可以看到上面 Workflow 的两个步骤都已经成功了,然后我们去 minio-ui 上面就可以查看到上面 Workflow 生成的制品了:
上面我们创建的制品被存储在 Minio 的 my-bucket 中,消费制品的任务根据 Workflow 中的定义根据提供的配置拉取制品,Minio 类似于 S3 提供了一个可共享的链接来使用制品:
除了上面提到的这些用法之外,Argo Workflow 还有很多其他用法,我们可以查看 Argo 官方提供的样例了解更多使用方法:https://github.com/argoproj/argo/tree/master/examples。
本文更多的是提到 Argo Workflow 的一些基本使用方法,下一篇文章我们再通过一个完整的示例来演示下 Argo Workflow 的实际用途。
参考链接
https://argoproj.github.io/docs/argo/demo.html
https://itnext.io/argo-workflow-engine-for-kubernetes-7ae81eda1cc5
https://github.com/argoproj/argo/tree/master/examples
