初识Argo(二)
四、Argo Event
4.1 Argo Event简介
Event事件大家都很熟悉,可以说Kubernetes就是完全由事件驱动的,不同的controller manager本质就是实现了不同的事件处理函数,比如所有ReplicaSet对象是由ReplicaSetController控制器管理,该控制器通过Informer监听ReplicaSet以及其关联的Pod的事件变化,从而维持运行状态和我们声明spec保持一致。
当然Kubernetes无论是什么Controller,其监听和处理的都是内部事件,而在应用层上我们也有很多外部事件,比如CICD事件、Webhook事件、日志事件等等,如何处理这些事件呢,目前Kubernetes原生是无法实现的。
当然你可以自己实现一个event handler运行在Kubernetes平台,不过实现难度也不小。而Argo Event组件完美解决了这个问题。
如图是Argo Event官方提供的的流程图:
首先事件源EventSource可以是Webhook、S3、Github、SQS等等,中间会经过一个叫Gateway(新版本叫EventBus)的组件,更准确地说老版本原来gateway的配置功能已经合并到EventSource了,EventBus是新引入的组件,后端默认基于高性能分布式消息中间件NATS[1]实现,当然其他中间件比如Kafka也是可以的。
这个EventBus可以看做是事件的一个消息队列,消息生产者连接EvenSource,EventSource又连接到Sensor。更详细地说EvenSource把事件发送给EvenBus,Sensor会订阅EvenBus的消息队列,EvenBus负责把事件转发到已订阅该事件的Sensor组件,EventSorce在上图中没有体现,具体设计文档可以参考Argo-events Enhancement Proposals[2]。
有些人可能会说为什么EventBus不直接到Trigger,中间引入一个Sensor,这主要是两个原因,一是为了使事件转发和处理松耦合,二是为了实现Trigger事件的参数化,通过Sensor不仅可以实现事件的过滤,还可以实现事件的参数化,比如后面的Trigger是创建一个Kubernetes Pod,那这个Pod的metadata、env等,都可以根据事件内容进行填充。
Sensor组件注册关联了一个或者多个触发器,这些触发器可以触发AWS Lambda事件、Argo Workflow事件、Kubernetes Objects等,通俗简单地说,可以执行Lambda函数,可以动态地创建Kubernetes的对象或者创建前面的介绍的Workflow。
还记得前面介绍的Argo Rollout吗,我们演示了手动promote实现应用发布或者回滚,通过Argo Event就可以很完美地和测试平台或者CI/CD事件结合起来,实现自动应用自动发布或者回滚。
4.2 一个简单的Webhook例子
关于Argo Event的部署非常简单,直接通过kubecl apply或者helm均可,可以参考文档Installation[3],这里不再赘述。
Argo Event部署完成后注意还需要部署EventBus,官方推荐使用NATS中间件,文档中有部署NATS stateful的文档。
接下来我们以一个最简单的Webhook事件为例,从而了解Argo Event的几个组件功能以及用法。
首先按照前面的介绍,我们需要先定义EventSource:
apiVersion: argoproj.io/v1alpha1
kind: EventSource
metadata:
name: webhook
spec:
service:
ports:
- port: 12000
targetPort: 12000
webhook:
webhook_example:
port: "12000"
endpoint: /webhook
method: POST
这个EventSource定义了一个webhook webhook_example,端口为12000,路径为/webhook,一般Webhook为POST方法,因此该Webhhok处理器我们配置只接收POST方法。
为了把这个Webhook EventSource暴露,我们还创建了一个Service,端口也是12000。
此时我们可以手动curl该Service:
# kubectl get svc -l eventsource-name=webhook
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webhook-eventsource-svc ClusterIP 10.96.93.24 <none> 12000/TCP 5m49s
# curl -X POST -d '{}' 10.96.93.24:12000/webhook
success
当然此时由于没有注册任何的Sensor,因此什么都不会发生。
接下来我们定义Sensor:
首先在dependencies中定义了订阅的EventSource以及具体的Webhook,由于一个EventSource可以定义多个Webhook,因此必须同时指定EventSource和Webhook两个参数。
在Trigger中我们定义了对应Action为create一个workflow,这个workflow的spec定义在resource中配置。
最后的parameters部分定义了workflow的参数,这些参数值从event中获取,这里我们会把整个event都当作workflow的input。当然你可以通过dataKey只汲取body部分:dataKey: body.message。
此时我们再次curl这个webhook事件:
curl -X POST -d '{"message": "HelloWorld!"}' 10.96.93.24:12000/webhook
此时我们获取argo workflow列表发现新创建了一个实例:
# argo list
NAME STATUS AGE DURATION PRIORITY
webhook-8xt4s Succeeded 1m 18s 0
查看workflow输出如下:
由于我们是把整个event作为workflow input发过去的,因此data内容部分是base64编码,我们可以查看解码后的内容如下:
{
"header": {
"Accept": [
"*/*"
],
"Content-Length": [
"26"
],
"Content-Type": [
"application/x-www-form-urlencoded"
],
"User-Agent": [
"curl/7.58.0"
]
},
"body": {
"message": "HelloWorld!"
}
}
从这里我们也可以看出Event包含两个部分,一个是context,一个是data,data中又包含header部分以及body部分,在parameters中可以通过Key获取任意部分内容。
如上的webhook触发是通过手动curl的,你可以很容易地在github或者bitbucket上配置到webhook中,这样一旦代码有更新就能触发这个事件了。
4.3 Kubernetes触发AWS Lambda函数
前面的例子中的EventSource使用了Webhook,除了Webhook,Argo Event还支持很多的EventSource,比如:
amqp
aws-sns
aws-sqs
github/gitlab
hdfs
kafka
redis
Kubernetes resource
...
Trigger也同样支持很多,比如:
aws lambda
amqp
kafka
...
如上官方都提供了非常丰富的例子,可以参考argo events examples[4]。
这里以Kubernetes resource事件源为例,这个事件监听Kubernetes的资源状态,比如Pod创建、删除等,这里以创建Pod为例:
apiVersion: argoproj.io/v1alpha1
kind: EventSource
metadata:
name: k8s-resource-demo
spec:
template:
serviceAccountName: argo-events-sa
resource:
pod_demo:
namespace: argo-events
version: v1
resource: pods
eventTypes:
- ADD
filter:
afterStart: true
labels:
- key: app
operation: "=="
value: my-pod
如上例子监听Pods的ADD事件,即创建Pod,filter中过滤只有包含app=my-pod标签的Pod,特别需要注意的是使用的serviceaccount argo-events-sa必须具有Pod的list、watch权限。
接下来我们使用AWS Lambda触发器,Lambda函数已经在AWS提前创建好:
这个Lambda函数很简单,直接返回event本身。
创建Sensor如下:
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: aws-lambda-trigger-demo
spec:
template:
serviceAccountName: argo-events-sa
dependencies:
- name: test-dep
eventSourceName: k8s-resource-demo
eventName: pod_demo
triggers:
- template:
name: lambda-trigger
awsLambda:
functionName: hello
accessKey:
name: aws-secret
key: accesskey
secretKey:
name: aws-secret
key: secretkey
namespace: argo-events
region: cn-northwest-1
payload:
- src:
dependencyName: test-dep
dataKey: body.name
dest: name
如上AWS access key和access secret需要提前放到aws-secret中。
此时我们创建一个新的Pod my-pod:
apiVersion: v1
kind: Pod
metadata:
labels:
app: my-pod
name: my-pod
spec:
containers:
- image: nginx
name: my-pod
dnsPolicy: ClusterFirst
restartPolicy: Always
当Pod启动后,我们发现AWS Lambda函数被触发执行:
4.4 event filter
前面的例子中webhook中所有的事件都会被sensor触发,我们有时不需要处理所有的事件,Argo Event支持基于data以及context过滤,比如我们只处理message为hello或者为hey的事件,其他消息忽略,只需要在原来的dependencies中test-dep增加filter即可:
dependencies:
- name: test-dep
eventSourceName: webhook
eventName: webhook_example
filters:
- name: data-filter
data:
- path: body.message
type: string
value:
- "hello"
- "hey"
filter指定了基于data过滤,过滤的字段为body.message,匹配的内容为hello、hey。
4.5 trigger policy
trigger policy主要用来判断最后触发器执行的结果是成功还是失败,如果是创建Kubernetes资源比如Workflow,可以根据Workflow最终状态决定这个Trigger的执行结果,而如果是触发一个HTTP或者AWS Lambda,则需要自定义policy status。
awsLambda:
functionName: hello
accessKey:
name: aws-secret
key: accesskey
secretKey:
name: aws-secret
key: secretkey
namespace: argo-events
region: us-east-1
payload:
- src:
dependencyName: test-dep
dataKey: body.message
dest: message
policy:
status:
allow:
- 200
- 201
如上表示当AWS Lambda返回200或者201时表示Trigger成功。
4.6 总结
前面介绍的例子都是单事件源单触发器,Argo Event可以支持多种事件源以及触发器,支持各种组合,从而实现把内部以及外部事件结合起来,通过事件驱动把应用以及外围系统连接起来,目前我们已经通过监听代码仓库Push或者PR Merge更新自动触发Workflow收集C7N policy到自动化平台系统中。
五、Argo CD
5.1 关于GitOps
最近各种Ops盛行,比如DevOps、DevSecOps、AIOps、GOps、ChatOps、GitOps等等,这些都可以认为是持续交付的一种方式,而本章主要关注其中的GitOps。
GitOps的概念最初来源于Weaveworks的联合创始Alexis在2017年8月发表的一篇博客GitOps - Operations by Pull Request[5],由命名就可以看出GitOps将Git作为交付流水线的核心。
通俗地讲,就是通过代码(code)定义基础设施(infrastructure)以及应用(application),这些代码可以是Terraform的声明文件或者Kubernetes或者Ansible的yaml声明文件,总之都是代码。
这些代码均可以通过git代码仓库(如github、gitlab、bitbuket)进行版本管理。这样就相当于把基础设施和应用通过git仓库管理起来了,如果需要做应用变更,只需要提交一个Pull Request,merge后持续交付工具自动根据变更的声明文件进行变更,收敛到最终期望的状态。应用回滚则只需要通过git revert即可。
通过git log可以方便地查看应用的版本信息,通过git的多分支可以指定交付的不同环境,比如开发测试环境、预发环境、生产环境等。
GitOps特别适合云原生应用,yaml定义一切,因此GitOps在Weaveworks的推广下流行起来,目前Jenkins X、Argo CD、Weave Flux、Spinnaker等均是基于GitOps模型的持续交付工具。
本章主要介绍其中的Argo CD工具。
5.2 Argo CD
Argo CD也是Argoproj项目中开源的一个持续集成工具,功能类似Spinnaker。
其部署也非常简单,可以参考官方文档Getting Started[6]。
ArgoCD内置了WebUI以及CLI工具,CLI工具功能比较全,比如只能通过CLI添加cluster,在WebUI上无法完成。
ArgoCD主要包含如下实体:
- Repository: 代码仓库,支持HTTPS或者SSH协议纳管代码仓库,代码仓库中包含Kubernetes yaml文件或者Helm Chart等。
- Cluster:Kubernetes集群,通常需要托管多个Kubernetes,比如生产环境、测试环境、预发环境、版本环境等。
- Project:其实就是Repository和Cluster建立关系,即把Repository中的声明的应用部署到指定的Cluster中。
- APP:Project的运行态。
5.3 Argo CD简单演示
Argo CD由于已经提供了WebUI,只需要按照UI界面提示一步步操作即可,没有什么难度。这里快速演示下如何使用Argo CD。
首先在github上创建了一个my-app的仓库,仓库的app目录下创建了一个my-app.yaml文件:
my-app.yaml文件内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-app
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- image: jocatalin/kubernetes-bootcamp:v1
name: my-app
在Argo CD中创建一个Repository:
接着在Argo CD中创建一个Project,指定Repository以及Cluster:
最后创建App即可:
此时应用自动进行同步和部署:
同步完成后,所有创建的资源都是可视化的:
现在我们把版本升级到v2:
git checkout -b v2
sed -i 's#jocatalin/kubernetes-bootcamp:v1#jocatalin/kubernetes-bootcamp:v2#g' app/my-app.yaml
git add .
git commit -m "Upgrade my app to v2"
git push --set-upstream origin v2
如上我们也可以直接push代码到master分支,不过为了按照GitOps的标准流程,我们创建了一个新的分支v2,通过Pull Request合并到master分支中。
在github上创建Pull Request并Merge后,应用自动进行了更新:
5.4 总结
Argo CD是基于GitOps模型的持续集成工具,搭配CI工具完成应用的自动构建并推送镜像到仓库中,配合CD完成应用的持续交付。
六、安装argo
- 条件:需要k8s环境
6.1 安装
# 创建命名空间argo
kubectl create ns argo
# 以命名空间为argo创建argo.yaml文件
kubectl apply -n argo -f argo.yaml
# 安装后会生成两个pod
[root@k8s-master1 ~]# kubectl get po -n argo
NAME READY STATUS RESTARTS AGE
argo-server-7d46945f95-qnxgv 1/1 Running 2 2d21h
workflow-controller-58fc87dfd7-hxd7r 1/1 Running 34 2d1h
# 第一个pod为argo服务端
# 第二个pod为工作流程控制器
- 文件argo.yaml:
# 将该yaml文件保存为arog.yaml
# This is an auto-generated file. DO NOT EDIT
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: clusterworkflowtemplates.argoproj.io
spec:
group: argoproj.io
names:
kind: ClusterWorkflowTemplate
listKind: ClusterWorkflowTemplateList
plural: clusterworkflowtemplates
shortNames:
- clusterwftmpl
- cwft
singular: clusterworkflowtemplate
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: cronworkflows.argoproj.io
spec:
group: argoproj.io
names:
kind: CronWorkflow
listKind: CronWorkflowList
plural: cronworkflows
shortNames:
- cwf
- cronwf
singular: cronworkflow
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
status:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: workfloweventbindings.argoproj.io
spec:
group: argoproj.io
names:
kind: WorkflowEventBinding
listKind: WorkflowEventBindingList
plural: workfloweventbindings
shortNames:
- wfeb
singular: workfloweventbinding
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: workflows.argoproj.io
spec:
group: argoproj.io
names:
kind: Workflow
listKind: WorkflowList
plural: workflows
shortNames:
- wf
singular: workflow
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Status of the workflow
jsonPath: .status.phase
name: Status
type: string
- description: When the workflow was started
format: date-time
jsonPath: .status.startedAt
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
status:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
subresources: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: workflowtaskresults.argoproj.io
spec:
group: argoproj.io
names:
kind: WorkflowTaskResult
listKind: WorkflowTaskResultList
plural: workflowtaskresults
singular: workflowtaskresult
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
message:
type: string
metadata:
type: object
outputs:
properties:
artifacts:
items:
properties:
archive:
properties:
none:
type: object
tar:
properties:
compressionLevel:
format: int32
type: integer
type: object
zip:
type: object
type: object
archiveLogs:
type: boolean
artifactory:
properties:
passwordSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
url:
type: string
usernameSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
required:
- url
type: object
from:
type: string
fromExpression:
type: string
gcs:
properties:
bucket:
type: string
key:
type: string
serviceAccountKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
required:
- key
type: object
git:
properties:
depth:
format: int64
type: integer
disableSubmodules:
type: boolean
fetch:
items:
type: string
type: array
insecureIgnoreHostKey:
type: boolean
passwordSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
repo:
type: string
revision:
type: string
sshPrivateKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
usernameSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
required:
- repo
type: object
globalName:
type: string
hdfs:
properties:
addresses:
items:
type: string
type: array
force:
type: boolean
hdfsUser:
type: string
krbCCacheSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
krbConfigConfigMap:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
krbKeytabSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
krbRealm:
type: string
krbServicePrincipalName:
type: string
krbUsername:
type: string
path:
type: string
required:
- path
type: object
http:
properties:
headers:
items:
properties:
name:
type: string
value:
type: string
required:
- name
- value
type: object
type: array
url:
type: string
required:
- url
type: object
mode:
format: int32
type: integer
name:
type: string
optional:
type: boolean
oss:
properties:
accessKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
bucket:
type: string
createBucketIfNotPresent:
type: boolean
endpoint:
type: string
key:
type: string
lifecycleRule:
properties:
markDeletionAfterDays:
format: int32
type: integer
markInfrequentAccessAfterDays:
format: int32
type: integer
type: object
secretKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
securityToken:
type: string
required:
- key
type: object
path:
type: string
raw:
properties:
data:
type: string
required:
- data
type: object
recurseMode:
type: boolean
s3:
properties:
accessKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
bucket:
type: string
createBucketIfNotPresent:
properties:
objectLocking:
type: boolean
type: object
encryptionOptions:
properties:
enableEncryption:
type: boolean
kmsEncryptionContext:
type: string
kmsKeyId:
type: string
serverSideCustomerKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
type: object
endpoint:
type: string
insecure:
type: boolean
key:
type: string
region:
type: string
roleARN:
type: string
secretKeySecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
useSDKCreds:
type: boolean
type: object
subPath:
type: string
required:
- name
type: object
type: array
exitCode:
type: string
parameters:
items:
properties:
default:
type: string
description:
type: string
enum:
items:
type: string
type: array
globalName:
type: string
name:
type: string
value:
type: string
valueFrom:
properties:
configMapKeyRef:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
default:
type: string
event:
type: string
expression:
type: string
jqFilter:
type: string
jsonPath:
type: string
parameter:
type: string
path:
type: string
supplied:
type: object
type: object
required:
- name
type: object
type: array
result:
type: string
type: object
phase:
type: string
progress:
type: string
required:
- metadata
type: object
served: true
storage: true
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: workflowtasksets.argoproj.io
spec:
group: argoproj.io
names:
kind: WorkflowTaskSet
listKind: WorkflowTaskSetList
plural: workflowtasksets
shortNames:
- wfts
singular: workflowtaskset
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
status:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
subresources:
status: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: workflowtemplates.argoproj.io
spec:
group: argoproj.io
names:
kind: WorkflowTemplate
listKind: WorkflowTemplateList
plural: workflowtemplates
shortNames:
- wftmpl
singular: workflowtemplate
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
type: object
x-kubernetes-map-type: atomic
x-kubernetes-preserve-unknown-fields: true
required:
- metadata
- spec
type: object
served: true
storage: true
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-server
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: argo-role
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- get
- update
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: argo-aggregate-to-admin
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
- workfloweventbindings
- workfloweventbindings/finalizers
- workflowtemplates
- workflowtemplates/finalizers
- cronworkflows
- cronworkflows/finalizers
- clusterworkflowtemplates
- clusterworkflowtemplates/finalizers
- workflowtasksets
- workflowtasksets/finalizers
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-edit: "true"
name: argo-aggregate-to-edit
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
- workfloweventbindings
- workfloweventbindings/finalizers
- workflowtemplates
- workflowtemplates/finalizers
- cronworkflows
- cronworkflows/finalizers
- clusterworkflowtemplates
- clusterworkflowtemplates/finalizers
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: argo-aggregate-to-view
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
- workfloweventbindings
- workfloweventbindings/finalizers
- workflowtemplates
- workflowtemplates/finalizers
- cronworkflows
- cronworkflows/finalizers
- clusterworkflowtemplates
- clusterworkflowtemplates/finalizers
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argo-cluster-role
rules:
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- watch
- list
- apiGroups:
- ""
resources:
- persistentvolumeclaims
- persistentvolumeclaims/finalizers
verbs:
- create
- update
- delete
- get
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
- workflowtasksets
- workflowtasksets/finalizers
verbs:
- get
- list
- watch
- update
- patch
- delete
- create
- apiGroups:
- argoproj.io
resources:
- workflowtemplates
- workflowtemplates/finalizers
- clusterworkflowtemplates
- clusterworkflowtemplates/finalizers
verbs:
- get
- list
- watch
- apiGroups:
- argoproj.io
resources:
- workflowtaskresults
verbs:
- list
- watch
- deletecollection
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- list
- apiGroups:
- argoproj.io
resources:
- cronworkflows
- cronworkflows/finalizers
verbs:
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- get
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argo-server-cluster-role
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- watch
- list
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create
- list
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
- pods/log
verbs:
- get
- list
- watch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- watch
- create
- patch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- list
- watch
- apiGroups:
- argoproj.io
resources:
- eventsources
- sensors
- workflows
- workfloweventbindings
- workflowtemplates
- cronworkflows
- clusterworkflowtemplates
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: argo-role
subjects:
- kind: ServiceAccount
name: argo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argo-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-cluster-role
subjects:
- kind: ServiceAccount
name: argo
namespace: argo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argo-server-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-server-cluster-role
subjects:
- kind: ServiceAccount
name: argo-server
namespace: argo
---
apiVersion: v1
kind: ConfigMap
metadata:
name: workflow-controller-configmap
---
apiVersion: v1
kind: Service
metadata:
name: argo-server
spec:
ports:
- name: web
port: 2746
targetPort: 2746
selector:
app: argo-server
---
apiVersion: v1
kind: Service
metadata:
labels:
app: workflow-controller
name: workflow-controller-metrics
spec:
ports:
- name: metrics
port: 9090
protocol: TCP
targetPort: 9090
selector:
app: workflow-controller
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: workflow-controller
value: 1000000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: argo-server
spec:
selector:
matchLabels:
app: argo-server
template:
metadata:
labels:
app: argo-server
spec:
containers:
- args:
- server
env: []
image: quay.io/argoproj/argocli:v3.3.0
name: argo-server
ports:
- containerPort: 2746
name: web
readinessProbe:
httpGet:
path: /
port: 2746
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 20
securityContext:
capabilities:
drop:
- ALL
volumeMounts:
- mountPath: /tmp
name: tmp
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
serviceAccountName: argo-server
volumes:
- emptyDir: {}
name: tmp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: workflow-controller
spec:
selector:
matchLabels:
app: workflow-controller
template:
metadata:
labels:
app: workflow-controller
spec:
containers:
- args:
- --configmap
- workflow-controller-configmap
- --executor-image
- quay.io/argoproj/argoexec:v3.3.0
command:
- workflow-controller
env:
- name: LEADER_ELECTION_IDENTITY
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: quay.io/argoproj/workflow-controller:v3.3.0
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 6060
initialDelaySeconds: 90
periodSeconds: 60
timeoutSeconds: 30
name: workflow-controller
ports:
- containerPort: 9090
name: metrics
- containerPort: 6060
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
nodeSelector:
kubernetes.io/os: linux
priorityClassName: workflow-controller
securityContext:
runAsNonRoot: true
serviceAccountName: argo
6.2 argoctl工具命令的安装:
# Download the binary
curl -sLO https://github.com/argoproj/argo-workflows/releases/download/v3.3.0/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
# Test installation
argo version
Controller and Server
kubectl create namespace argo
kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.3.0/install.yaml
v2.9之后登录需要认证
#将token复制到客户端验证登录
Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImszOTFxaW9FWWp3QzRDSEhpSC1GU01ScS1IZm9VSk01T1k4ZDVRU1NvTjQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJhcmdvIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFyZ28tc2VydmVyLXRva2VuLTQyczdzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFyZ28tc2VydmVyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDg3ZTYyOTAtODMwYS00YzM2LTk2ZWEtNWZjODkyNWE3OTU4Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmFyZ286YXJnby1zZXJ2ZXIifQ.HVmbOQdouJCXEnw2Fu6pE4OyJ1Z3EkKfgloZtifQ2A4lfxyt1PNvEWqCeFckDUAujESRX7iyNtThA2VOouNEJTZHH9_L6qvlIHpQZhDBVWZkiXu-TzOYnZYAEIVXh8bPrDsmMR-N8iR0V_Chl0GANilHxfH2nQzz92dO1SkVa75n6kgq0Uv1Z1Se5AYY27u7kfC_hLSIetHjO1BY9Hk4lm1k9H-gazabvK52TjpJhtPXAXs8cIRoZc8-75L0MfqHDjTFXGiOu1C7RgwMBmLjF1TrqWitJhUTNJz2ZwgwlMsi1ElWCK8UMp5yfd2loeFG8_pCzRoTApjTUH2ptI4g_w
UI界面如下: