argo-workflow介绍
Argo Workflows是一个开源的容器化云原生工作流项目,其主要通过Kubernetes CRD实现的。
特点如下:
- 工作流的每一步都是一个容器
- 将多步骤工作流建模为一系列任务,或者使用有向无环图(DAG)描述任务之间的依赖关系
- 可以在短时间内轻松运行用于机器学习或数据处理的计算密集型作业
- 在Kubernetes上运行CI/CD Pipeline,无需复杂的软件配置
要安装 Argo Workflows,请导航至 Release 页面并找到您希望使用的版本(最好是最新的大版本)。
以下是安装命令的示例,请确保替换 ARGO_WORKFLOWS_VERSIO
变量以安装正确的版本号:
kubectl create namespace argo
kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v<<ARGO_WORKFLOWS_VERSION>>/install.yaml
安装好后我们可以使用 kubectl 命令查看 argo 命名空间下的服务,我们可以看到主要是2个服务,argo-server 用来接收前端请求,workflow-controller 用来执行 crd 控制器逻辑。
补丁 argo-server 认证
argo-server(以及 UI)默认为客户端身份验证,这需要客户端提供其 Kubernetes 承载令牌才能进行身份验证。有关详细信息,请参阅 Argo 服务器身份验证模式文档。我们将身份验证模式切换为 server ,以便我们现在可以绕过 UI 登录:
kubectl patch deployment \
argo-server \
--namespace argo \
--type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/args", "value": [
"server",
"--auth-mode=server"
]}]'
ui界面端口转发
将ui端口转发到本地
kubectl -n argo port-forward deployment/argo-server 2746:2746 & open https://localhost:2746
我们可以看到argo-workflow的界面啦 ,默认会显示 argo 命名空间下的工作流任务列表。
提交一个最简单的工作流
提交工作流
让我们从创建一个非常简单的工作流模板开始,使用来自 Docker Hub 的 docker/whalesay 容器镜像来回应“hello world”
您可以使用简单的 docker 命令直接从 shell 运行它:
$ docker run docker/whalesay cowsay "hello world"
_____________
< hello world >
-------------
\
\
\
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
Hello from Docker!
This message shows that your installation appears to be working correctly.
我们尝试让argo系统帮助我们运行这个容器,点击argo界面 +SUBMIT NEW WORKFLOW
按钮,将下面的yaml文件,提交到argo系统。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-world-
spec:
entrypoint: whalesay
templates:
- name: whalesay
container:
image: docker/whalesay
command: [ cowsay ]
args: [ "hello world" ]
resources:
limits:
memory: 32Mi
cpu: 100m
查看工作流
我们可以看到界面上多了个绿色的任务,点击右下角的Logs按钮,我们能查看容器中的日志,打印出了我们要的鲸鱼。
多步骤工作流
如果我们想执行多个工作流,如何做呢?试试提交下下面的yaml文件吧!
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-
spec:
entrypoint: hello-hello-hello
templates:
- name: hello-hello-hello
steps:
- - name: hello1
template: whalesay
arguments:
parameters:
- name: message
value: "hello1"
- - name: hello2a
template: whalesay
arguments:
parameters:
- name: message
value: "hello2a"
- name: hello2b
template: whalesay
arguments:
parameters:
- name: message
value: "hello2b"
- name: whalesay
inputs:
parameters:
- name: message
container:
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
看图秒懂!我们创建了3个任务,hello2b 和 hello2a 在 hello1 任务之后并发执行。同时这三个任务接受的参数不同,打印的结果也不同哦!
4大模版
argo-workflow 系统重定义的模版有4种类别,如下:
Container
也许是最常见的模板类型,它会调度一个容器。模板的规范与 Kubernetes 容器规范相同,因此您可以像在 Kubernetes 中的其他任何地方一样在这里定义容器。
- name: whalesay
container:
image: docker/whalesay
command: [cowsay]
args: ["hello world"]
Script
执行脚本,添加了 source: 字段,允许您就地定义脚本。该脚本将保存到一个文件中并为您执行。脚本的结果会自动导出到 变量 {{steps.<NAME>.outputs.result}}
中,你可以在下一阶段使用这个结果。
- name: gen-random-int
script:
image: python:alpine3.6
command: [python]
source: |
import random
i = random.randint(1, 100)
print(i)
Resource
直接对集群资源进行操作。它可用于获取、创建、应用、删除、替换或修补集群上的资源。此示例在集群上创建一个 ConfigMap 资源
- name: k8s-owner-reference
resource:
action: create
manifest: |
apiVersion: v1
kind: ConfigMap
metadata:
generateName: owned-eg-
data:
some: value
Suspend
暂停模板将暂停工作流的执行,持续一段时间或直到手动恢复。用户可以使用 cli、API 接口或 UI点击操作来恢复暂停的工作流,让其继续执行。
- name: delay
suspend:
duration: "20s"
2大流程控制
Steps
steps 模板允许您在一系列 steps 中定义您的任务。模板的结构是“列表的列表”。外部列表将按顺序运行,内部列表将并行运行。如果要逐一运行内部列表,请使用同步功能。您可以设置各种选项来控制执行,例如 when: 子句以有条件地执行步骤。
在此示例中, step1 首先运行。完成后, step2a 和 step2b 将并行运行:
- name: hello-hello-hello
steps:
- - name: step1
template: prepare-data
- - name: step2a
template: run-data-first-half
- name: step2b
template: run-data-second-half
Dag
dag 模板允许您将任务定义为依赖关系图。在 DAG 中,您列出所有任务并设置在特定任务开始之前必须完成哪些其他任务。没有任何依赖关系的任务将立即运行。在此示例中, A 首先运行。一旦完成, B 和 C 将并行运行,一旦它们都完成, D 将运行:
- name: diamond
dag:
tasks:
- name: A
template: echo
- name: B
dependencies: [A]
template: echo
- name: C
dependencies: [A]
template: echo
- name: D
dependencies: [B, C]
template: echo
CI 示例
一般将代码构建成镜像,有两种方式 ,一种是dind,一种是使用本地构建工具,比如 kaniko,buildkit等工具。这里我们展示如何使用argo-workflow 来构建镜像。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: k8s-jobs-
spec:
serviceAccountName: default
entrypoint: pi-tmpl
templates:
- name: pi-tmpl
resource:
action: create
successCondition: status.succeeded > 0
failureCondition: status.failed > 3
manifest: |
apiVersion: v1
kind: Pod
metadata:
generateName: kaniko-pod
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
args:
- "--dockerfile=Dockerfile"
- "--context=git://github.com/mouuii/golang-dockerfile.git#refs/heads/main"
- "--destination=上传到镜像仓库地址"
volumeMounts:
- name: kaniko-secret
mountPath: "/kaniko/.docker"
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /secret/kaniko-secret.json
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: dockersecret
items:
- key: .dockerconfigjson
path: config.json
我们使用argo-workflow简单创建一个镜像,传入 dockersecret 和代码仓库地址,执行后,会将我们的代码打包成镜像并上传到我们配置的镜像仓库地址,如果不熟悉,可以去百度下 kaniko。
个人感受
概念太多,使用姿势太多,很多东西看的出都是功能的堆叠,并没有一个很好的兼容,上手成本比较高。