初识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界面如下:

posted @ 2022-05-31 09:02  _安阳  阅读(403)  评论(0编辑  收藏  举报