All Products
Search
Document Center

Container Service for Kubernetes:Use Argo Workflows to create CI pipelines

Last Updated:Dec 27, 2024

Argo Workflows provides easy-to-use interfaces and tools. You can use YAML files to define workflows and quickly configure a Continuous Integration (CI) pipeline. Argo Workflows allows you to simultaneously run jobs in the cluster and dynamically scale the required computing resources. This improves the efficiency of the CI pipeline.

Feature introduction

To create CI pipelines by using Argo Workflows, use BuildKit to build and push container images and then use BuildKit Cache to accelerate image building. Using File Storage NAS (NAS) to store the Go mod cache can accelerate the Go Test and Go Build steps. This greatly reduces the required time to create CI pipelines.

image

Introduction to a predefined ClusterWorkflowTemplate

You can directly use the predefined template or create a custom template based on the predefined template. In this example, a ClusterWorkflowTemplate named ci-go-v1 is created. The template uses BuildKit Cache and NAS to store the Go mod cache to greatly accelerates CI pipeline creation.

View the processes of the ClusterWorkflowTemplate

  1. Git Clone and Checkout

    • Clone the Git repository and check out the Git repository to the destination branch.

    • Obtain the commit ID, which is appended as a suffix to the image tag during image building.

  2. Run Go Test

    • Run all test cases (Go projects) in the Git repository by default.

    • You can set the pipeline parameter enable_test to specify whether to perform this step.

    • The Go mod cache is stored in the /pkg/mod directory of the NAS file system to accelerate Go Test and Go Build.

  3. Build & Push Image

    • Use BuildKit to build and push container images, and use caches of the registry type in BuildKit Cache to accelerate image building.

    • By default, the image tag is in the {container_tag}-{commit_id} format. You can specify whether to append the commit ID to the image tag when you submit the pipeline.

    • During image pushing, the latest version of the image is pushed to overwrite the current version.

View the content of the ClusterWorkflowTemplate

apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
  name: ci-go-v1
spec:
  entrypoint: main
  volumes:
  - name: run-test
    emptyDir: {}
  - name: workdir
    persistentVolumeClaim:
      claimName: pvc-nas
  - name: docker-config
    secret:
      secretName: docker-config
  arguments:
    parameters:
    - name: repo_url
      value: ""
    - name: repo_name
      value: ""
    - name: target_branch
      value: "main"
    - name: container_image
      value: ""
    - name: container_tag
      value: "v1.0.0"
    - name: dockerfile
      value: "./Dockerfile"
    - name: enable_suffix_commitid
      value: "true"
    - name: enable_test
      value: "true"
  templates:
    - name: main
      dag:
        tasks:
          - name: git-checkout-pr
            inline:
              container:
                image: mirrors-ssl.aliyuncs.com/alpine:latest
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    
                    apk --update add git
          
                    cd /workdir
                    echo "Start to Clone "{{workflow.parameters.repo_url}}
                    git -C "{{workflow.parameters.repo_name}}" pull || git clone {{workflow.parameters.repo_url}} 
                    cd {{workflow.parameters.repo_name}}
          
                    echo "Start to Checkout target branch" {{workflow.parameters.target_branch}}
                    git checkout --track origin/{{workflow.parameters.target_branch}} || git checkout {{workflow.parameters.target_branch}}
                    git pull
                    
                    echo "Get commit id" 
                    git rev-parse --short origin/{{workflow.parameters.target_branch}} > /workdir/{{workflow.parameters.repo_name}}-commitid.txt
                    commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                    echo "Commit id is got: "$commitId
                                        
                    echo "Git Clone and Checkout Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                resources:
                  requests:
                    memory: 1Gi
                    cpu: 1
                activeDeadlineSeconds: 1200
          - name: run-test
            when: "{{workflow.parameters.enable_test}} == true"
            inline: 
              container:
                image: mirrors-ssl.aliyuncs.com/golang:alpine3.21
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    
                    if [ !  -d "/workdir/pkg/mod" ]; then
                      mkdir -p /workdir/pkg/mod
                      echo "GOMODCACHE Directory /pkg/mod is created"
                    fi
                    
                    export GOMODCACHE=/workdir/pkg/mod
                    
                    cp -R /workdir/{{workflow.parameters.repo_name}} /test/{{workflow.parameters.repo_name}} 
                    echo "Start Go Test..."
                    
                    cd /test/{{workflow.parameters.repo_name}}
                    go test -v ./...
                    
                    echo "Go Test Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                - name: run-test
                  mountPath: /test
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: git-checkout-pr    
          - name: build-push-image
            inline: 
              container:
                image: mirrors-ssl.aliyuncs.com/moby/buildkit:v0.13.0-rootless
                command:
                  - sh
                  - -c
                  - |         
                    set -eu
                     
                    tag={{workflow.parameters.container_tag}}
                    if [ {{workflow.parameters.enable_suffix_commitid}} == "true" ]
                    then
                      commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                      tag={{workflow.parameters.container_tag}}-$commitId
                    fi
                    
                    echo "Image Tag is: "$tag
                    echo "Start to Build And Push Container Image"
                    
                    cd /workdir/{{workflow.parameters.repo_name}}
                    
                    buildctl-daemonless.sh build \
                    --frontend \
                    dockerfile.v0 \
                    --local \
                    context=. \
                    --local \
                    dockerfile=. \
                    --opt filename={{workflow.parameters.dockerfile}} \
                    build-arg:GOPROXY=http://goproxy.cn,direct \
                    --output \
                    type=image,\"name={{workflow.parameters.container_image}}:${tag},{{workflow.parameters.container_image}}:latest\",push=true,registry.insecure=true \
                    --export-cache mode=max,type=registry,ref={{workflow.parameters.container_image}}:buildcache \
                    --import-cache type=registry,ref={{workflow.parameters.container_image}}:buildcache
                    
                    echo "Build And Push Container Image {{workflow.parameters.container_image}}:${tag} and {{workflow.parameters.container_image}}:latest Complete."
                env:
                  - name: BUILDKITD_FLAGS
                    value: --oci-worker-no-process-sandbox
                  - name: DOCKER_CONFIG
                    value: /.docker
                volumeMounts:
                  - name: workdir
                    mountPath: /workdir
                  - name: docker-config
                    mountPath: /.docker
                securityContext:
                  seccompProfile:
                    type: Unconfined
                  runAsUser: 1000
                  runAsGroup: 1000
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: run-test

You can run the kubectl apply -f cluster-workflow-template.yaml command to deploy the template to the cluster.

View the parameter description of the template

Parameter

Description

Example

entrypoint

Specify the entry template.

main

repo_url

The URL of the Git repository.

https://github.com/ivan-cai/echo-server.git

repo_name

The name of the repository.

echo-server

target_branch

The destination branch of the repository. Default value: main.

main

container_image

The image that you want to build. Format: <ACR EE Domain>/<ACR EE Namespace>/<Repository Name>.

test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server

container_tag

The image tag. Default: v1.0.0.

v1.0.0

dockerfile

The directory and name of the Dockerfile.

Specify the relative path in the root directory. Default: ./Dockerfile.

./Dockerfile

enable_suffix_commitid

Specify whether to append the commit ID to the image tag. Valid values:

  • true: appends the commit ID to the image tags. This is the default value.

  • false: does not append the commit ID to the image tags.

true

enable_test

Specify whether to run the Go Test step. Valid values:

  • true: runs the Go Test step. This is the default value.

  • false: does not run the Go Test step.

true

Procedure

A public Git repository is used as an example to demonstrate how to create a CI pipeline. If you use a private Git repository, you need to first clone the private repository in the CI pipeline. For more information, see Clone a private Git repository in a CI pipeline.

Important

The Secret that stores the credentials for accessing the container image and the NAS volume must belong to the namespace of the pipeline to be submitted.

Step 1: Create credentials to access the Container Registry Enterprise Edition instance

The credentials are used to pull images from BuildKit.

  1. Configure access credentials for the Container Registry Enterprise Edition instance. For more information, see Configure access credentials for a Container Registry Enterprise Edition instance.

  2. Run the following command to create a Secret in the cluster to store the credentials. The credentials are used by BuildKit.

    Note

    $repositoryDomain: the domain name of the Container Registry image repository.

    $username: the username of the Container Registry image repository.

    $password: the password of the Container Registry image repository.

    kubectl create secret -n argo generic docker-config --from-literal="config.json={\"auths\": {\"$repositoryDomain\": {\"auth\": \"$(echo -n $username:$password|base64)\"}}}"

Step 2: Mount a NAS volume

After you mount a NAS volume, data such as the code repository information for Clone can be shared between various jobs of the workflow. NAS volumes can also be used to store Go mod cache and accelerate the go test and go build steps in CI pipeline.

For more information about how to mount NAS volumes, see Use volumes.

Step 3: Launch a pipeline based on the template

Use the console

  1. Log on to the Argo console. In the left-side navigation pane, click Cluster Workflow Templates and click the predefined ClusterWorkflowTemplate named ci-go-v1.

    image

  2. On the template details page, click + SUBMIT in the upper-right corner. In the panel that appears, configure the parameters and click + SUBMIT.

    Refer to Template parameters and configure the parameters based on your business requirements.

    image

    After you complete the configuration, you can view the status of the pipeline on the Workflows details page.

    image

Use the Argo CLI

  1. Create a file named workflow.yaml and copy the following content to the file. Refer to Template parameters and configure the parameters.

    apiVersion: argoproj.io/v1alpha1
    kind: Workflow
    metadata:
      generateName: ci-go-v1-
      labels:
        workflows.argoproj.io/workflow-template: ackone-ci
      namespace: argo  
    spec:
      arguments:
        parameters:
        - name: repo_url
          value: https://github.com/ivan-cai/echo-server.git
        - name: repo_name
          value: echo-server
        - name: target_branch
          value: main
        - name: container_image
          value: "test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server"
        - name: container_tag
          value: "v1.0.0"
        - name: dockerfile
          value: ./Dockerfile
        - name: enable_suffix_commitid
          value: "true"
        - name: enable_test
          value: "true"
      workflowTemplateRef:
        name: ci-go-v1
        clusterScope: true
  2. Run the following command to submit a pipeline:

    argo submit workflow.yaml

Contact us

If you have suggestions or questions about this product, join the DingTalk group 35688562 to contact us.