如何分析Argo Workflows-Kubernetes的工作流引擎,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
專業(yè)的建站公司網(wǎng)站可以采用ASP、PHP、.NET編程語言及配備的SQL SERVER、MYSQL、ACCESSS數(shù)據(jù)庫存儲來整體開發(fā)及設計各類型大中型網(wǎng)站(包括:公司、行業(yè)門戶、醫(yī)院門戶、商城、政府門戶、音樂、視頻、交友、分類信息網(wǎng)站等各種類型網(wǎng)站),我們可以提供從網(wǎng)站開發(fā)、網(wǎng)站設計、網(wǎng)站安全維護及網(wǎng)站托管運營和網(wǎng)絡推廣一條龍服務。打造高端企業(yè)網(wǎng)站設計公司,網(wǎng)站開發(fā)周期短,質量有保證,設計精美,價格合理。
Argo Workflows是一個開源項目,為Kubernetes提供container-native工作流程,其主要通過Kubernetes CRD實現(xiàn)的。
特點如下:
工作流的每一步都是一個容器
將多步驟工作流建模為一系列任務,或者使用有向無環(huán)圖(DAG)描述任務之間的依賴關系
可以在短時間內輕松運行用于機器學習或數(shù)據(jù)處理的計算密集型作業(yè)
在Kubernetes上運行CI/CD Pipeline,無需復雜的軟件配置
安裝控制器端
Argo Wordflows的安裝非常簡單,直接使用以下命令安裝即可。
kubectl create ns argo kubectl apply -n argo -f https://raw.githubusercontent.com/argoproj/argo-workflows/stable/manifests/quick-start-postgres.yaml
安裝完成后,會生成以下4個pod。
# kubectl get po -n argo NAME READY STATUS RESTARTS AGE argo-server-574ddc66b-62rjc 1/1 Running 4 4h35m minio 1/1 Running 0 4h35m postgres-56fd897cf4-k8fwd 1/1 Running 0 4h35m workflow-controller-77658c77cc-p25ll 1/1 Running 4 4h35m
其中:
argo-server是argo服務端
mino是進行制品倉庫
postgres是數(shù)據(jù)庫
workflow-controller是流程控制器
然后配置一個server端的ingress,即可訪問UI,配置清單如下(我這里使用的是traefik):
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: argo-ui namespace: argo spec: entryPoints: - web routes: - match: Host(`argowork-test.coolops.cn`) kind: Rule services: - name: argo-server port: 2746
UI界面如下:
再配置一個minio的ingress,配置清單如下:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: minio namespace: argo spec: entryPoints: - web routes: - match: Host(`minio-test.coolops.cn`) kind: Rule services: - name: minio port: 9000
UI界面如下(默認用戶名密碼是:admin:password):
Argo Workflows提供Argo CLI,其安裝方式也非常簡單,如下:Linux系統(tǒng):
# Download the binary curl -sLO https://github.com/argoproj/argo/releases/download/v3.0.0-rc4/argo-linux-amd64.gz # Unzip gunzip argo-linux-amd64.gz # Make binary executable chmod +x argo-linux-amd64 # Move binary to path mv ./argo-linux-amd64 /usr/local/bin/argo
安裝完成后,使用以下命令校驗是否安裝成功。
# argo version argo: v3.0.0-rc4 BuildDate: 2021-03-02T21:42:55Z GitCommit: ae5587e97dad0e4806f7a230672b998fe140a767 GitTreeState: clean GitTag: v3.0.0-rc4 GoVersion: go1.13 Compiler: gc Platform: linux/amd64
其主要的命令有:
list 列出工作流 logs 查看工作流的日志 submit 創(chuàng)建工作流 watch 實時監(jiān)聽工作流 get 現(xiàn)實詳細信息 delete 刪除工作流 stop 停止工作流
更多命令可以使用argo --help進行查看。
然后可以使用一個簡單的hello world的WorkFlow,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: hello-world- labels: workflows.argoproj.io/archive-strategy: "false" spec: entrypoint: whalesay templates: - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: ["hello world"]
使用如下命令創(chuàng)建并觀察workflow。
$ argo submit -n argo helloworld.yaml --watch
然后可以看到以下輸出。
Name: hello-world-9pw7v Namespace: argo ServiceAccount: default Status: Succeeded Conditions: Completed True Created: Mon Mar 08 14:51:35 +0800 (10 seconds ago) Started: Mon Mar 08 14:51:35 +0800 (10 seconds ago) Finished: Mon Mar 08 14:51:45 +0800 (now) Duration: 10 seconds Progress: 1/1 ResourcesDuration: 4s*(1 cpu),4s*(100Mi memory) STEP TEMPLATE PODNAME DURATION MESSAGE ? hello-world-9pw7v whalesay hello-world-9pw7v 5s
還可以通過argo list來查看狀態(tài),如下:
# argo list -n argo NAME STATUS AGE DURATION PRIORITY hello-world-9pw7v Succeeded 1m 10s 0
使用argo logs來查看具體的日志,如下:
# argo logs -n argo hello-world-9pw7v hello-world-9pw7v: _____________ hello-world-9pw7v: < hello world > hello-world-9pw7v: ------------- hello-world-9pw7v: \ hello-world-9pw7v: \ hello-world-9pw7v: \ hello-world-9pw7v: ## . hello-world-9pw7v: ## ## ## == hello-world-9pw7v: ## ## ## ## === hello-world-9pw7v: /""""""""""""""""___/ === hello-world-9pw7v: ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ hello-world-9pw7v: \______ o __/ hello-world-9pw7v: \ \ __/ hello-world-9pw7v: \____\______/
Workflow
Workflow是Argo中最重要的資源,其主要有兩個重要功能:
它定義要執(zhí)行的工作流
它存儲工作流程的狀態(tài)
要執(zhí)行的工作流定義在Workflow.spec字段中,其主要包括templates和entrypoint,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: hello-world- # Workflow的配置名稱 spec: entrypoint: whalesay # 解析whalesay templates templates: - name: whalesay # 定義whalesay templates,和entrypoint保持一致 container: # 定義一個容器,輸出"helloworld" image: docker/whalesay command: [cowsay] args: ["hello world"]
Templates
templates是列表結構,主要分為兩類:
定義具體的工作流
調用其他模板提供并行控制
定義具體的工作流有4種類別,如下:
Container
Script
Resource
Suspend
Container
container是最常用的模板類型,它將調度一個container,其模板規(guī)范和K8S的容器規(guī)范相同,如下:
- name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world"]
Script
Script是Container的另一種包裝實現(xiàn),其定義方式和Container相同,只是增加了source字段用于自定義腳本,如下:
- name: gen-random-int script: image: python:alpine3.6 command: [python] source: | import random i = random.randint(1, 100) print(i)
腳本的輸出結果會根據(jù)調用方式自動導出到{{tasks.
Resource
Resource主要用于直接在K8S集群上執(zhí)行集群資源操作,可以 get, create, apply, delete, replace, patch集群資源。如下在集群中創(chuàng)建一個ConfigMap類型資源:
- name: k8s-owner-reference resource: action: create manifest: | apiVersion: v1 kind: ConfigMap metadata: generateName: owned-eg- data: some: value
Suspend
Suspend主要用于暫停,可以暫停一段時間,也可以手動恢復,命令使用argo resume進行恢復。定義格式如下:
- name: delay suspend: duration: "20s"
調用其他模板也有兩種類別:
Steps
Dag
Steps
Steps主要是通過定義一系列步驟來定義任務,其結構是"list of lists",外部列表將順序執(zhí)行,內部列表將并行執(zhí)行。如下:
- name: hello-hello-hello steps: - - name: step1 template: prepare-data - - name: step2a template: run-data-first-half - name: step2b template: run-data-second-half
其中step1和step2a是順序執(zhí)行,而step2a和step2b是并行執(zhí)行。
還可以通過When來進行條件判斷。如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: coinflip- spec: entrypoint: coinflip templates: - name: coinflip steps: - - name: flip-coin template: flip-coin - - name: heads template: heads when: "{{steps.flip-coin.outputs.result}} == heads" - name: tails template: tails when: "{{steps.flip-coin.outputs.result}} == tails" - name: flip-coin script: image: python:alpine3.6 command: [python] source: | import random result = "heads" if random.randint(0,1) == 0 else "tails" print(result) - name: heads container: image: alpine:3.6 command: [sh, -c] args: ["echo \"it was heads\""] - name: tails container: image: alpine:3.6 command: [sh, -c] args: ["echo \"it was tails\""]
提交這個Workflow,執(zhí)行效果如下:
除了使用When進行條件判斷,還可以進行循環(huán)操作,示例代碼如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: loops- spec: entrypoint: loop-example templates: - name: loop-example steps: - - name: print-message template: whalesay arguments: parameters: - name: message value: "{{item}}" withItems: - hello world - goodbye world - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay:latest command: [cowsay] args: ["{{inputs.parameters.message}}"]
提交Workflow,輸出結果如下:
Dag
Dag主要用于定義任務的依賴關系,可以設置開始特定任務之前必須完成其他任務,沒有任何依賴關系的任務將立即執(zhí)行。如下:
- 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會立即執(zhí)行,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
image.png
在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的輸入?yún)?shù),然后在使用"{{}}"形式引用變量。
變量還可以進行一些函數(shù)運算,主要有:
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的時候,已經(jīng)安裝了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中可以看到生成的制品,制品經(jīng)過了壓縮,如下:
WorkflowTemplate
WorkflowTemplate是Workflow的模板,可以從WorkflowTemplate內部或者集群上其他Workflow和WorkflowTemplate引用它們。
WorkflowTemplate和template的區(qū)別:
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}}"]
創(chuàng)建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: # 參數(shù) parameters: - name: message value: "hello world"
ClusterWorkflowTemplate
ClusterWorkflowTemplate創(chuàng)建的是一個集群范圍內的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: # 參數(shù) parameters: - name: message value: "hello world"
上面大概敘述了一下argo的基本理論知識,更多的理論知識可以到官網(wǎng)去學習。
下面將使用一個簡單的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來創(chuàng)建鏡像,不用掛載docker.sock,但是push鏡像的時候需要config.json,所以首先需要創(chuàng)建一個secret,如下:
kubectl create secret generic docker-config --from-file=.docker/config.json -n argo
2、準備好storageClass,當然也可以不需要,直接使用empty,不過可以將緩存文件這些持久化,可以加速構建(我上面沒有做)。
3、創(chuàng)建WorkflowTemplate,命令如下:
argo template create -n argo devops-java.yaml
4、創(chuàng)建Workflow,可以手動創(chuàng)建,如下:
apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: workflow-template-devops-java- spec: workflowTemplateRef: name: devops-java
也可以直接在UI界面點擊創(chuàng)建,我這里直接在UI界面點擊創(chuàng)建。選擇剛創(chuàng)建的WorkflowTemplate,點擊創(chuàng)建,如下:
然后就會生成一條Workflow,如下:
點進去,可以看到每個具體的步驟,如下
點擊每個具體的步驟,可以看日志,如下:
也可以在命令行界面看到Workflow的執(zhí)行結果,如下:
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。