前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Argo Workflows 中文快速指南·

Argo Workflows 中文快速指南·

作者头像
LinuxSuRen
发布2023-02-27 09:05:28
2.9K0
发布2023-02-27 09:05:28
举报
文章被收录于专栏:JenkinsJenkins

Argo Workflows 是一个云原生的通用的工作流引擎。本教程主要介绍如何用其完成持续集成(Continous Integration, CI)任务。

本文全部内容来自:https://github.com/LinuxSuRen/argo-workflows-guide

如果您感觉本文对您或其他人有帮助,欢迎点赞、转发、分享。更加丰富、详细的内容也会在上面的 GitHub 仓库中更新,大家可以在上面的 issue 中交流。

基本概念

对任何工具的基本概念有一致的认识和理解,是我们学习以及与他人交流的基础。

以下是本文涉及到的概念:

  • WorkflowTemplate,工作流模板
  • Workflow,工作流

为方便读者理解,下面就几个同类工具做对比:

Argo Workflow

Jenkins

WorkflowTemplate

Pipeline

Workflow

Build

安装

首先,你需要有一套 Kubernetes 环境。下面的工具可以帮助你快速按照好一套 Kubernetes 环境:

推荐使用 hd 安装下面的工具 安装 hd 的命令为:curl https://linuxsuren.github.io/tools/install.sh|bash

工具

工具安装

使用

k3d

hd i k3d

k3d cluster create

kubekey

hd i kk

kk create cluster

minikube

hd i minikube

minikube start

当 Kubernetes 环境就绪后,就可以通过下面的命令会在命名空间(argo)下安装最新版本的 Argo Workflow

代码语言:javascript
复制
kubectl create namespace argo
kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/latest/download/install.yaml

如果你的环境访问 GitHub 时有网络问题,可以使用下面的命令来安装:

代码语言:javascript
复制
docker run -it --rm -v /root/.kube/:/root/.kube --network host ghcr.io/linuxsuren/argo-workflows-guide:master

推荐使用的工具:

k9s

K9s is a terminal based UI to interact with your Kubernetes clusters.

设置访问方式

我们可以用下面的方式或者其他方式来设置 Argo Workflows 的访问端口:

代码语言:javascript
复制
kubectl -n argo port-forward deploy/argo-server --address 0.0.0.0 2746:2746

需要注意的是,这里默认的配置下,服务器设置了自签名的证书提供 HTTPS 服务,因此,确保你使用 https:// 协议进行访问。

例如,地址为:https://10.121.218.242:2746/

Argo Workflows UI 提供了多种认证登录方式,对于学习、体验等场景,我们可以通过下面的命令直接设置绕过登录:

代码语言:javascript
复制
kubectl patch deployment \
  argo-server \
  --namespace argo \
  --type='json' \
  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/args", "value": [
  "server",
  "--auth-mode=server"
]}]'

简单示例

下面是一个非常简单的示例:

代码语言:javascript
复制
cat <<EOF | kubectl apply -n default -f -
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: hello-world
spec:
  entrypoint: hd # 执行入口,类似于 Go、Java 语言的的 main 函数
  templates:
  - container:
      args:
      - search
      - kubectl
      command:
      - hd
      image: ghcr.io/linuxsuren/hd:v0.0.70 # 任务镜像
      name: main
    name: hd
EOF

执行成功后,就可以在下面的地址访问到刚刚创建的工作流模板:

https://10.121.218.242:2746/workflow-templates/default

选择其中一个模板,点击 SUBMIT 按钮,并设置对应的参数后即可触发工作流的执行。

在 Workflows 的详情页面中,我们做如下的操作:

  • RESUBMIT,使用相同的模板以及参数触发一次新的执行

小结

通过前面的步骤,我们可以观察到 Argo Workflow 有如下特点:

  • 需要具备基本的容器知识
  • 需要熟悉 Kubernetes 的基本资源,例如:PodTemplate、ConfigMap、Secret、Volume 等
  • 实现特定任务,基本上是需要寻找官方提供的镜像,或自行构建镜像

完整示例

代码语言:javascript
复制
cat <<EOF | kubectl apply -n default -f -
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: gogit
spec:
  entrypoint: main                  # 执行入口
  arguments:
    # 工作流全局参数
    parameters:
      - name: repo
        value: https://github.com/linuxsuren/gogit
      - name: branch
        value: master

  # Volume 模板申明,用于工作流中多个 Pod 之间共享存储
  # 例如:克隆代码、构建代码的 Pod 之间共享目录
  # 动态创建 Volume,与当前工作流的生命流程保持一致
  volumeClaimTemplates:
    - metadata:
        name: work
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 64Mi

  templates:
  - name: main
    dag:
      tasks:
        - name: clone
          template: clone   # 引用下面的模板,并传入参数
          arguments:
            parameters:
              - name: repo
                value: "{{workflow.parameters.repo}}"
              - name: branch
                value: "{{workflow.parameters.branch}}"
        - name: build
          template: build
          depends: checkout # 通过 depends 设置执行任务之间的顺序关系
  
  - name: clone
    inputs:
      parameters:
        - name: repo
        - name: branch
    container:
      volumeMounts:
        - mountPath: /work              # 共享该目录
          name: work
      image: alpine/git:v2.26.2
      workingDir: /work                 # 代码会克隆到这个目录中
      args:
        - clone
        - --depth
        - "1"
        - --branch
        - "{{inputs.parameters.branch}}"
        - --single-branch
        - "{{inputs.parameters.repo}}"
        - .
  - name: build
    container:
      image: golang:1.19
      volumeMounts:
        - name: work
          mountPath: /work
      workingDir: /work
      env:
        - name: GOPROXY     # 根据需要来设置相应的环境变量,例如这里的 Golang 代理
          value: https://goproxy.io,direct
      command:
        - make
      args:
        - build             # 执行 Makefile 中的 build 指令来构建 Golang 代码
EOF

小结

通过上面的例子,我们可以看到 Argo Workflows 的如下特点:

  • 一个工作流中的多个任务之间默认是并行执行的,如果希望顺序执行则可以通过 depends 设置
  • 工作流中可以申明多个任务模板,只有被 entrypoint 引用到的模板才会被执行
  • 每执行一个任务都会对应启动一个 Pod
  • 一个工作流之间的多个任务需要共享目录的话,需要挂载 Volume

Webhook

所有主流 Git 仓库都是支持 webhook 的,借助 webhook 可以当代码发生变化后实时地触发工作流的执行。

Argo Workflows 利用 WorkflowEventBinding 将收到的 webhook 请求与 WorkflowTemplate 做关联。请参考下面的例子:

代码语言:javascript
复制
cat <<EOF kubectl apply -n default -f -
apiVersion: argoproj.io/v1alpha1
kind: WorkflowEventBinding
metadata:
  name: pull-request-binding
spec:
  event:
    # 通过 webhook 的 payload 对请求进行过滤,并联动触发对应的工作流模板
    selector: payload.project.name == "gogit" && payload.object_attributes.state == "opened"
  submit:
    workflowTemplateRef:
      name: gogit       # 关联工作流模板
    arguments:
      parameters:
      - name: branch
        valueFrom:
          # 从 webhook 的 payload 中提取值作为参数
          event: payload.object_attributes.source_branch
EOF

然后,在代码仓库中添加如下的 webhook 地址(其中,defaultWorkflowEventBinding 所在的命名空间):

代码语言:javascript
复制
https://argo-workflow-ip:port/api/v1/events/default/

小结

从上面的例子中,我们可以看到:

  • Argo Workflows 以申明式的资源将 webhook 与工作流模板做关联,非常地灵活
  • webhook 绑定并不局限在 Git 代码仓库上,还可以与其他类型的 webhook 做关联
  • 通过从 webhook 的 payload 中提取值,可以非常方便地为工作流模板参数传递值

关联代码仓库

对于不少的团队而言,会出于各种考虑而选择私有部署 Git 服务,例如:Gitlab、Gitee 等。而将工作流的执行结果与代码仓库的 Pull Request 相关联几乎是一个标配。以下是关联后的几点好处:

  • 工作流执行失败后阻止 Pull Request 的合并
  • 在 Pull Request 页面中可以直接看到工作流执行状态

下面会基于 https://github.com/LinuxSuRen/gogit/ 给出一个关联方案:

代码语言:javascript
复制
cat <<EOF | kubectl apply -n default -f -
apiVersion: v1
data:
  token: eW91ci10b2tlbg==
kind: Secret
metadata:
  name: git-secret
type: Opaque
---
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: hook
spec:
  entrypoint: main
  arguments:
    parameters:
      - name: pr
        value: 1
      - name: argoServer
        value: https://localhost:8080

  hooks:
    exit:                   # 只有 exit 这个 hook 名称是固定的
      template: hook
    all:                    # 这里可以是任意字符串,重点在于 expression 这里的表达式
      template: hook
      expression: "true"    # 可以通过表达式 expression 对事件进行过滤

  templates:
  - container:
      args:
      - search
      - kubectl
      command:
      - hd
      image: ghcr.io/linuxsuren/hd:v0.0.70 # 任务镜像
      name: main
    name: hd
  - name: hook
    volumes:
      - name: git-secret
        secret:
          defaultMode: 0400
          secretName: git-secret    # 包含 token 字段的 Secret
    container:
      image: ghcr.io/linuxsuren/gogit:master@sha256:4855f4ffbc1644eb7246f94cc9ee12c793ed4c26ba18e1d4d9afa57b72f1e846
      args:
        - --provider=github         # 支持 GitHub、Gitlab 等,私有部署的话需要参数 --server 指定地址
        - --owner=LinuxSuRen        # 根据需要修改 owner、repo、username
        - --repo=gogit
        - --username=LinuxSuRen
        - --token=file:///root/.ssh/token
        - --pr={{workflow.parameters.pr}}
        - --target={{workflow.parameters.argoServer}}/workflows/{{workflow.namespace}}/{{workflow.name}}
        - --status={{workflow.status}}
      volumeMounts:
        - mountPath: /root/.ssh/
          name: git-secret
EOF

触发上面的工作流后,就会在指定的仓库 Pull Request 上出现构建状态。

参考链接

  • 官方文档

小结

从这个示例中,我们可以看到:

  • hook 机制依然是非常的灵活,但 expression 表达式可能会是一个具有挑战的部分
  • hook 机制有点像是 Golang 的 __init 函数,作为特殊的入口,可以调用其他的模板

日志持久化

Argo Workflows 默认不会持久化工作流日志,而是从每个任务对应的 Pod 中获取日志。而对于 Kubernetes 来说,Pod 是一个没有保障的最小执行单元,可能会由于人为或者某种策略被删除。当 Pod 被删除后,日志就无法查看了。因此,对于生产环境而言,必须要持久化日志。

Argo Workflows 执行多种存储协议,以下是兼容 S3 的 MinIO 存储:

首先,下载、安装以及配置 minio。本文仅作学习、演示使用,生产环境中,请按照官方文档进行安装、配置。

代码语言:javascript
复制
hd i minio
minio server /tmp/minio --console-address ":9001"

然后,访问 minio 管理界面 http://localhost:9001,创建名为 argo-workflowbucket。创建 Access Key,并写入下面的 Secret 中。

安装如下配置修改 ConfigMap

代码语言:javascript
复制
kubectl create secret generic minio-workflow \
  --from-literal=accessKey=supersecret \
  --from-literal=secretKey=topsecret
cat <<EOF | kubectl apply -n default -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: workflow-controller-configmap
  namespace: argo
data:
  artifactRepository: |
    archiveLogs: true          # 全局设置使得所有工作流日志做持久化
    s3:
      bucket: argo-workflow    # 在 minio 中创建的 bucket
      endpoint: minio.minio.svc
      insecure: true                  # 当 minio 没有启用 TLS
      accessKeySecret:
        name: minio-workflow
        key: accessKey
      secretKeySecret:
        name: minio-workflow
        key: secretKey
EOF

完成上面的配置后,再次执行任意工作流,并将执行完成的 Pod 删除后,我们依然可以在 UI 上查看任务日志。并且,可以在 minio 中看到了新增的文件。每个 Pod 的日志在 minio 中分别以一个文件的形式存储。

我们可以通过 minio 的命令行客户端 mc 看到类似如下的文件:

代码语言:javascript
复制
mc alias set myminio http://localhost:9001 minioadmin minioadmin
# mc ls myminio/argo-workflow -r
[2022-12-09 10:53:31 CST]    20B STANDARD hello-world-5mjgp/hello-world-5mjgp-clone-3848310779/main.log
[2022-12-09 10:55:39 CST]  16KiB STANDARD hello-world-5mjgp/hello-world-5mjgp-image-2614052838/main.log
[2022-12-09 10:54:35 CST] 5.9KiB STANDARD hello-world-5mjgp/hello-world-5mjgp-scan-4101005739/main.log
[2022-12-09 10:53:51 CST]   435B STANDARD hello-world-5mjgp/hello-world-5mjgp-test-1532501286/main.log

参考链接

  • 支持的外部存储类型
  • 官方文档

小结

通过上面的例子,我们可以看到:

  • Argo Workflows 能以非侵入式的配置,使得工作流日志输出到对象存储等外部存储中
  • Argo Workflows 的任务有输入、输出(input、output)的概念,日志的持久化是将日志作为输出写入到预先配置好的外部存储
  • 日志的持久化,可以分别在全局 ConfigMap、Workflow Spec、WorkflowTemplate 中配置

References

  • DevOps Practice Guide https://github.com/LinuxSuRen/devops-practice-guide
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Jenkins 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本概念
  • 安装
  • 设置访问方式
  • 简单示例
    • 小结
    • 完整示例
      • 小结
      • Webhook
        • 小结
        • 关联代码仓库
          • 参考链接
            • 小结
            • 日志持久化
              • 参考链接
                • 小结
                • References
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档