Dag
Dag主要用于定义任务的依赖关系,可以设置开始特定任务之前必须完成其他任务,没有任何依赖关系的任务将立即执行。如下:
- 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
其中A会立即执行,B和C会依赖A,D依赖B和C。
然后运行一个示例看看效果,示例如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: dag-diamond- spec: entrypoint: diamond templates: - name: diamond dag: tasks: - name: A template: echo arguments: parameters: [{name: message, value: A}] - name: B dependencies: [A] template: echo arguments: parameters: [{name: message, value: B}] - name: C dependencies: [A] template: echo arguments: parameters: [{name: message, value: C}] - name: D dependencies: [B, C] template: echo arguments: parameters: [{name: message, value: D}] - name: echo inputs: parameters: - name: message container: image: alpine:3.7 command: [echo, "{{inputs.parameters.message}}"]
提交workflow。
argo submit -n argo dag.yam --watch
Variables
在argo的Workflow中允许使用变量的,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: hello-world-parameters- spec: entrypoint: whalesay arguments: parameters: - name: message value: hello world templates: - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay command: [ cowsay ] args: [ "{{inputs.parameters.message}}" ]
首先在spec字段定义arguments
,定义变量message
,其值是hello world
,然后在templates
字段中需要先定义一个inputs
字段,用于templates
的输入参数,然后在使用"{{}}"
形式引用变量。
变量还可以进行一些函数运算,主要有:
- filter:过滤
- asInt:转换为Int
- asFloat:转换为Float
- string:转换为String
- toJson:转换为Json
例子:
filter([1, 2], { # > 1}) asInt(inputs.parameters["my-int-param"]) asFloat(inputs.parameters["my-float-param"]) string(1) toJson([1, 2])
更多语法可以访问https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md进行学习。
制品库
在安装argo的时候,已经安装了mino作为制品库,那么到底该如何使用呢?
先看一个官方的例子,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: artifact-passing- spec: entrypoint: artifact-example templates: - name: artifact-example steps: - - name: generate-artifact template: whalesay - - name: consume-artifact template: print-message arguments: artifacts: - name: message from: "{{steps.generate-artifact.outputs.artifacts.hello-art}}" - name: whalesay container: image: docker/whalesay:latest command: [sh, -c] args: ["sleep 1; cowsay hello world | tee /tmp/hello_world.txt"] outputs: artifacts: - name: hello-art path: /tmp/hello_world.txt - name: print-message inputs: artifacts: - name: message path: /tmp/message container: image: alpine:latest command: [sh, -c] args: ["cat /tmp/message"]
其分为两步:
- 首先生成制品
- 然后获取制品
提交Workflow,运行结果如下:
然后在minio中可以看到生成的制品,制品经过了压缩,如下:
WorkflowTemplate
WorkflowTemplate是Workflow的模板,可以从WorkflowTemplate内部或者集群上其他Workflow和WorkflowTemplate引用它们。
WorkflowTemplate和template的区别:
- template只是Workflow中templates下的一个任务,当我们定义一个Workflow时,至少需要定义一个template
- WorkflowTemplate是驻留在集群中的Workflow的定义,它是Workflow的定义,因为它包含模板,可以从WorkflowTemplate内部或者集群上其他Workflow和WorkflowTemplate引用它们。
在2.7版本后,WorkflowTemplate的定义和Workflow的定义一样,我们可以简单的将kind:Workflow
改成kind:WorkflowTemplate
。比如:
apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: name: workflow-template-1 spec: entrypoint: whalesay-template arguments: parameters: - name: message value: hello world templates: - name: whalesay-template inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"]
创建WorkflowTemplate,如下
argo template create workflowtemplate.yaml
然后在Workflow中引用,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: workflow-template-hello-world- spec: entrypoint: whalesay templates: - name: whalesay steps: # 引用模板必须在steps/dag/template下 - - name: call-whalesay-template templateRef: # 应用模板字段 name: workflow-template-1 # WorkflowTemplate名 template: whalesay-template # 具体的template名 arguments: # 参数 parameters: - name: message value: "hello world"
ClusterWorkflowTemplate
ClusterWorkflowTemplate创建的是一个集群范围内的WorkflowTemplate,其他workflow可以引用它。
如下定义一个ClusterWorkflow。
apiVersion: argoproj.io/v1alpha1 kind: ClusterWorkflowTemplate metadata: name: cluster-workflow-template-whalesay-template spec: templates: - name: whalesay-template inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"]
然后在workflow中使用templateRef
去引用它,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: workflow-template-hello-world- spec: entrypoint: whalesay templates: - name: whalesay steps: - - name: call-whalesay-template templateRef: #引用模板 name: cluster-workflow-template-whalesay-template # ClusterWorkflow名 template: whalesay-template # 具体的模板名 clusterScope: true # 表示是ClusterWorkflow arguments: # 参数 parameters: - name: message value: "hello world"
实践
上面大概叙述了一下argo的基本理论知识,更多的理论知识可以到官网去学习。
下面将使用一个简单的CI/CD实践,来了解一下用argo workflow应该如何做。
CI/CD的整个流程很简单,即:拉代码->编译->构建镜像->上传镜像->部署。
定义一个WorkflowTemplate,如下:
apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: annotations: workflows.argoproj.io/description: | Checkout out from Git, build and deploy application. workflows.argoproj.io/maintainer: '@joker' workflows.argoproj.io/tags: java, git workflows.argoproj.io/version: '>= 2.9.0' name: devops-java spec: entrypoint: main arguments: parameters: - name: repo value: gitlab-test.coolops.cn/root/springboot-helloworld.git - name: branch value: master - name: image value: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp:202103101613 - name: cache-image value: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp - name: dockerfile value: Dockerfile - name: devops-cd-repo value: gitlab-test.coolops.cn/root/devops-cd.git - name: gitlabUsername value: devops - name: gitlabPassword value: devops123456 templates: - name: main steps: - - name: Checkout template: Checkout - - name: Build template: Build - - name: BuildImage template: BuildImage - - name: Deploy template: Deploy # 拉取代码 - name: Checkout script: image: registry.cn-hangzhou.aliyuncs.com/rookieops/maven:3.5.0-alpine workingDir: /work command: - sh source: | git clone --branch {{workflow.parameters.branch}} http://{{workflow.parameters.gitlabUsername}}:{{workflow.parameters.gitlabPassword}}@{{workflow.parameters.repo}} . volumeMounts: - mountPath: /work name: work # 编译打包 - name: Build script: image: registry.cn-hangzhou.aliyuncs.com/rookieops/maven:3.5.0-alpine workingDir: /work command: - sh source: mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip volumeMounts: - mountPath: /work name: work # 构建镜像 - name: BuildImage volumes: - name: docker-config secret: secretName: docker-config container: image: registry.cn-hangzhou.aliyuncs.com/rookieops/kaniko-executor:v1.5.0 workingDir: /work args: - --context=. - --dockerfile={{workflow.parameters.dockerfile}} - --destination={{workflow.parameters.image}} - --skip-tls-verify - --reproducible - --cache=true - --cache-repo={{workflow.parameters.cache-image}} volumeMounts: - mountPath: /work name: work - name: docker-config mountPath: /kaniko/.docker/ # 部署 - name: Deploy script: image: registry.cn-hangzhou.aliyuncs.com/rookieops/kustomize:v3.8.1 workingDir: /work command: - sh source: | git remote set-url origin http://{{workflow.parameters.gitlabUsername}}:{{workflow.parameters.gitlabPassword}}@{{workflow.parameters.devops-cd-repo}} git config --global user.name "Administrator" git config --global user.email "coolops@163.com" git clone http://{{workflow.parameters.gitlabUsername}}:{{workflow.parameters.gitlabPassword}}@{{workflow.parameters.devops-cd-repo}} /work/devops-cd cd /work/devops-cd git pull cd /work/devops-cd/devops-simple-java kustomize edit set image {{workflow.parameters.image}} git commit -am 'image update' git push origin master volumeMounts: - mountPath: /work name: work volumeClaimTemplates: - name: work metadata: name: work spec: storageClassName: nfs-client-storageclass accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
说明:
1、使用kaniko来创建镜像,不用挂载docker.sock,但是push镜像的时候需要config.json,所以首先需要创建一个secret,如下:
kubectl create secret generic docker-config --from-file=.docker/config.json -n argo
2、准备好storageClass,当然也可以不需要,直接使用empty,不过可以将缓存文件这些持久化,可以加速构建(我上面没有做)。
3、创建WorkflowTemplate,命令如下:
argo template create -n argo devops-java.yaml
创建完成后,可以在UI界面看到刚创建的WorkflowTemplate,如下:
4、创建Workflow,可以手动创建,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: workflow-template-devops-java- spec: workflowTemplateRef: name: devops-java
也可以直接在UI界面点击创建,我这里直接在UI界面点击创建。选择刚创建的
WorkflowTemplate,点击创建,如下:
然后就会生成一条Workflow,如下:
点进去,可以看到每个具体的步骤,如下
点击每个具体的步骤,可以看日志,如下:
也可以在命令行界面看到Workflow的执行结果,如下:
初次使用到这里就结束了,后期会逐步去优化。