kubernetes ArgoCD回调到管道

pn9klfpd  于 2023-10-17  发布在  Kubernetes
关注(0)|答案(1)|浏览(107)

我想让ArgoCD在部署成功时批准CircleCI中批准步骤中的作业。
然而,这是一个多星期的旅程,没有结果。我首先看了这个:
https://argo-cd.readthedocs.io/en/stable/user-guide/resource_hooks/
我花了时间建立了一个完整的argo工作流程和工作。然后设置一个管道来捕获等待的作业id(在更新yaml文件之前),并使用该id运行工作流,该工作流将生成一个PostSync,该PostSync可以使用该id来批准等待的circleci作业,只有在成功部署之后,然后销毁它自己。我也有一个同步失败。当我意识到这是通用的时候,我的希望破灭了。我看不到一种方法,只运行此作业的一个特定的应用程序在argocd,它似乎运行在任何同步事件。(什么??)
现在我在看这个:https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/
然而,我又一次看到打嗝已经在我的事件开始之前。似乎没有可能的方式来运行自定义代码,因此我无法运行API来批准我的作业。有没有人得到了一个特定的应用程序工作回调系统?我可以尝试通过回调管道来运行API,但这似乎很愚蠢。一定有更好的办法...

ua4mk5z4

ua4mk5z41#

经过近一个月的搜索、构建和挖掘代码,我有了一些工作。这并不是我想要的,但我认为从长远来看,这可能是更好的。
我使用了一个callback来代替回调机制,不过我将在下面给予一些实现回调批准机制的方法。

背景

我正在使用以下服务:

argocd
    argocd-notifications
    argocd-workflows

默认情况下,argocd-notificationsargocd捆绑在一起,而argocd-workflows没有捆绑,需要单独安装。(所有这些都是通过社区Helm图表完成的)。

ArgoCD-ROM设置

argocd-notifications-cm(密码Map必须命名为这个,argocd将自动拾取这个密码Map名称)argocd-notifications-secret(出于同样的原因,密码必须命名为这个)

argocd-notifications-cm

请注意,如果你只是使用它,你将覆盖默认情况下生成的。如果需要的话,您可以将其附加到现有的Map中,但请确保在应用您自己的Map之前捕获该信息。

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  template.run-github-pipeline: |
    webhook:
      trigger-workflow:
        method: POST
        path: /submit
        body: |
          {
            "resourceKind": "WorkflowTemplate",
            "namespace": "argo-workflows",
            "resourceName": "scripts-trigger-pipelines",
            "submitOptions": {
                "entryPoint": "github",
                "generateName": "{{ `{{.app.metadata.name}}` }}-github-pipeline-",
                "parameters": [
                    "app_name={{ `{{.app.metadata.name}}` }}",
                    "trigger_with_data={{ `{{.recipient}}` }}"
                ],
                "labels": "workflows.argoproj.io/workflow-template=scripts-trigger-pipelines",
                "generateName": "{{ `{{.app.metadata.name}}` }}-trigger-github-pipeline-"
          }}
  trigger.on-deployment-success-circleci: |
    - when: app.status.sync.status in ['Synced'] and app.status.operationState != nil and app.status.operationState.phase in ['Succeeded'] and app.status.health.status in ['Healthy']
      oncePer: app.status.operationState.syncResult.revision
      send: [run-circleci-pipeline]
  service.webhook.trigger-workflow: |
    url: "https://{{ .Values.workflows.endpoint }}/api/v1/workflows/argo-workflows"
    headers:
    - name: "Authorization"
      value: "Bearer $ARGO_WORKFLOWS_API_TOKEN"
    - name: "Content-Type"
      value: "application/json"
    insecureSkipVerify: false

argocd-notifications-secret

这个秘密也必须存在,以便它知道$ARGO_WORKFLOWS_API_TOKEN是什么:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: argocd-notifications-secret
  namespace: argocd
spec:
  secretStoreRef:
    kind: ClusterSecretStore
    name: aws-secrets-manager
  refreshInterval: 1m
  target:
    creationPolicy: Owner
    deletionPolicy: Delete
  # map secret key/value pairs to envvars
  data:
    - secretKey: ARGO_WORKFLOWS_API_TOKEN
      remoteRef:
        key: my-secret-name
        property: argo_workflows_api_token

在上面的例子中,我使用了一个外部的Secret,这样我就可以在其他地方维护这个Secret,并将它同步到kuberentes,但是如果你愿意的话,你也可以使用一个普通的Secret。订阅
现在这个问题让我纠结了一段时间,但是你只能将这些注解添加到kubernetes资源kind: Application中。这一点只有阿格哈德才能理解。你可以这样添加:

notifications.argoproj.io/subscribe.on-deployment-success-github.trigger-workflow: 'repo:my_test_repo|eventtype:my-repository-dispatch-event|payload:{app_name:sample}'

这就利用了上面的{{.recipient}}Map中定义的{{.recipient}}。在触发事件之前,它会将以下内容添加到该Map的{{.recipient}}条目中:

repo:my_test_repo|eventtype:my-repository-dispatch-event|payload:{app_name:sample}

现在argo-notifications端已经完成。我们需要设置argo-workflowsside.

Argo-Workflows设置

您需要设置一些方法来与argo-workflows通信。这意味着你需要设置一个webhook(抱歉,这里不会详细介绍如何做到这一点,只是知道你需要它)。获取API令牌
接下来,我们需要设置一个服务帐户rolebindingrole,我们将使用它们来访问argo-workflows的API。为了获得我们在上面的通知中使用的API令牌,我们需要生成一个secret:

apiVersion: v1
kind: Secret
metadata:
  name: argo-workflows-pipelines.service-account-token
  annotations:
    kubernetes.io/service-account.name: argo-workflows-pipelines
  type: kubernetes.io/service-account-token

这样做将允许我们运行以下命令来获取API令牌,并将其直接放置到外部密钥或argocd-notifications-secret中:

kg secret argo-workflows-pipelines.service-account-token -o=jsonpath='{.data.token}' -n argo-workflows | base64 --decode

设置任务清单

现在我们有了token,我们可以设置一个作业清单,它将由通知触发,通知将负责回调到我们想要的任何管道(circleci,github,bitbucket等)-在这个例子中,我使用github

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: scripts-trigger-pipelines
spec:
  ttlStrategy:
    secondsAfterCompletion: 320    # Auto delete workflow in 5 minutes after it completes
  entrypoint: github
  arguments:
    parameters:
      - name: trigger_with_data
        value: "{}"
      - name: app_name
        value: ""
  templates:
    - name: github
      serviceAccountName: <my-sa-name>
      inputs:
        parameters:
          - name: trigger_with_data
          - name: app_name
      metadata:
        annotations:
          kubectl.kubernetes.io/default-container: main
      resource:
        action: create
        setOwnerReference: true
        manifest: |
          apiVersion: batch/v1
          kind: Job
          metadata:
            generateName: "{{ `{{inputs.parameters.app_name}}` }}-trigger-github-pipeline-"
          spec:
            template:
              spec:
                serviceAccountName: argo-workflows-pipelines
                volumes:
                - name: secret-volume
                  secret:
                    secretName: <my-secret-volume>
                containers:
                - name: trigger-github-pipeline
                  image: {{ .Values.awsAccountID }}.dkr.ecr.us-east-1.amazonaws.com/{{ .Values.pipelineCallbacks.docker.image }}:{{ .Values.pipelineCallbacks.docker.tag }}
                  command: ["/bin/bash", "-c"]
                  args:
                    - |-
                      echo "Input App: {{ `{{inputs.parameters.app_name}}` }}"
                      INPUT_DATA='{{ `{{inputs.parameters.trigger_with_data}}` }}'
                      ...

                      # Trigger target github repository dispatch event with the generated token and parsed data
                      echo "Issuing curl to url:https://api.github.com/repos/<owner>/$REPO/dispatches -- with data: {\"event_type\":\"$EVENT_TYPE\",\"client_payload\":{\"dispatch_payload\":$PAYLOAD}}"
                      curl \
                        -X POST \
                        -H "Accept: application/vnd.github+json" \
                        -H "Authorization: Bearer $GITHUB_TOKEN"\
                        -H "X-GitHub-Api-Version: 2022-11-28" \
                        https://api.github.com/repos/<owner>/$REPO/dispatches \
                        -d "{\
                          \"event_type\":\"$EVENT_TYPE\",\
                          \"client_payload\":$PAYLOAD
                        }"

                  volumeMounts:
                  - name: secret-volume
                    readOnly: true
                    mountPath: "/secrets"
                restartPolicy: Never
            backoffLimit: 2

注意:我不会在这里为您详细说明所有内容,因为您需要将GITHUB_TOKEN纳入工作流程。我只会使用我提供的例子通过卷挂载的“秘密”。我也会使用github应用程序来动态生成令牌,更安全。
注2:

ttlStrategy:
    secondsAfterCompletion: 320

在第一次建造的时候,我可能会把它移走,直到你准备好了。Github设置
现在我们已经设置了argo-notificationsargo-workflows,我们可以在github管道中设置一个存储库分派事件(或其他管道的等效事件)。

name: "Argo Callback"
on:
  repository_dispatch:
    types: [my-repository-dispatch-event]
    inputs:
      app_name:
        description: 'The name of the app you want to update in your own triggering repo.'
        required: true
        type: string

jobs:
  argo-callback:
    name: "Init Callback"
    runs-on: ubuntu-latest
    steps:
      - name: Output payload
        id: verify
        run: |
          echo "RECEIVED CALLBACK FOR APP: ${{ github.event.client_payload.app_name }}"
          echo "${{ github.event.client_payload }}"

只要我没有错别字的东西,你填写的一切,它应该是工作。
但是,如果不是呢?让我们谈谈调试。调试

Argo-Argo

kubectl get pods -n argocd | grep argocd-notifications

应该吐出通知控制器。然后你可以看看它的日志:

kubectl logs <pod_name> -n argocd --tail=100 -f

如果你想沿着实时跟踪日志,我添加了-f。
Argo-Workflows

kubectl get pods -n argo-workflows

有一个服务器和一个控制器,就像argo-notifications。用同样的方法查看这些日志。这应该会给你给予成功所需的所有信息!祝你好运!
阿尔戈-阿维尼翁的文件简直是地狱。这里也有一些有用的信息,对未记录的东西,如应用程序。状态等。
https://github.com/argoproj/gitops-engine/blob/187312fe86ed627b1cf4147c13dccf9ff331424b/pkg/sync/sync_task.go
https://github.com/argoproj/gitops-engine/blob/master/pkg/sync/common/types.go#L54

回调审批

现在,有了以上所有内容,如果您使用数据库(如dynamo db)来存储触发部署的哈希,则可以实现回调批准。然后使用undocument app.status.operationState.syncResult.revision(它基本上是提交的短散列)参数将其发送到argo-workflows。然后,argo-workflows将使用该哈希在数据库中查找该信息,以了解它应该响应谁。
我知道这将是一个超级宝贵的资源,任何人与工作流程或通知工作。

相关问题