All Products
Search
Document Center

Container Service for Kubernetes:Use an ACK One workflow cluster to build an image CI pipeline

Last Updated:Nov 01, 2024

This topic describes how to use a Distributed Cloud Container Platform for Kubernetes (ACK One) workflow cluster to build an image continuous integration (CI) pipeline.

Prerequisites

Limits

A CI pipeline built by using this method cannot trigger image builds based on code commits.

Benefits of ACK One workflow clusters

Show the benefits of ACK One workflow clusters

Developed based on open source Argo Workflows, workflow clusters comply with the standards of open source workflows. If you have Argo workflows running in existing Container Service for Kubernetes (ACK) clusters or Kubernetes clusters, you can seamlessly upgrade the clusters to workflow clusters without the need to modify the workflows.

By using workflow clusters, you can easily manage workflow orchestration and run each workflow step in containers. This builds a high-efficiency continuous integration/continuous deployment (CI/CD) pipeline that allows you to quickly launch a large number of containers for compute-intensive jobs such as machine learning and data processing jobs.

  • Workflow clusters are developed based on open source Argo Workflows. You can seamlessly upgrade Kubernetes clusters that run Argo workflows to workflow clusters without the need to modify the workflows.

  • Workflow clusters support fully automated O&M and allow you to focus on workflow development.

  • Workflow clusters provide high elasticity and auto scaling capabilities to reduce the costs of compute resources.

  • Workflow clusters support high scheduling reliability and multi-zone load balancing.

  • Workflow clusters use control planes whose performance, efficiency, stability, and observability are optimized.

  • Workflow clusters support enhanced OSS management capabilities, such as large object uploading, artifacts garbage collection (GC), and data streaming.

Build an image CI pipeline

The ACK One workflow cluster uses the BuildKit tool to build and push images. In this example, BuildKit is deployed by using the moby/buildkit:v0.12.1-rootless image, which can be downloaded from Docker Hub (https://hub.docker.com/r/moby/buildkit).

Step 1: Create a Secret in the workflow cluster to store the username and password for logging on to the Container Registry Enterprise Edition instance.

  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 workflow cluster to store the credentials, which can be used by BuildKit to access the Container Registry Enterprise Edition instance.

    Replace ${workflow_kubeconfig} and $username:$password in the following code block with the actual values.

    # repositoryDomain: For example, you can set the value to demo-test-registry.cn-hangzhou.cr.aliyuncs.com.
    kubectl --kubeconfig ${workflow_kubeconfig} create secret generic docker-config --from-literal="config.json={\"auths\": {\"$repositoryDomain\": {\"auth\": \"$(echo -n $username:$password|base64)\"}}}"

Step 2: Create a WorkflowTemplate in the workflow cluster

You can use a WorkflowTemplate to configure code cloning from a Git repository, image building, and image pushing.

  • Code cloning from Git repository: In this example, a public Git repository is used. If you want to use a private Git repository, specify a token for logging on to the private repository. Example: git clone https://[username]:[token]@gitlab.com/demo3624733/echo-server.git.

  • Image building and pushing: In this example, the BuildKit tool is used to build and push images.

The following section describes how to create a WorkflowTemplate that does not use shared storage and a WorkflowTemplate that uses File Storage NAS (NAS).

Create a WorkflowTemplate that does not use shared storage

This method allows you to build a CI pipeline through simple steps. The following WorkflowTemplate configures an init container to clone code to an emptyDir volume and build images in a temporary directory.

  1. Create a file named worktemplate-1.yaml based on the following YAML template.

    Specify a repository, a branch, and an image in the parameters section. Replace the username and token in the following template with the actual ones that are used.

    Show the content of worktemplate-1.yaml

    apiVersion: argoproj.io/v1alpha1
    kind: WorkflowTemplate
    metadata:
      name: build-echo-server-2
    spec:
      arguments:
        parameters:
          - name: repo
            value: https://github.com/ivan-cai/echo-server.git
          - name: branch
            value: main
          - name: path
            value: echo-server
          - name: image
            value: demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v2-argo-08231710
      entrypoint: main
      volumes:
        - name: work
          emptyDir: {}
      templates:
        - name: main
          inputs:
            parameters:
              - name: repo
              - name: branch
              - name: path
              - name: image
          # Mount the configuration so we can push the image.
          # This should create the /.docker/config.json file.
          volumes:
            - name: docker-config
              secret:
                secretName: docker-config
          initContainers:
          - name: git-clone
            image: alpine/git:v2.26.2
            volumeMounts:
              - mountPath: /work
                name: work
            workingDir: /work/
            command:
              - git
            args:
              - clone
              - --depth
              - "1"
              - --branch
              - "{{inputs.parameters.branch}}"
              - --single-branch
              - "{{inputs.parameters.repo}}"
          container:
            readinessProbe:
              exec:
                command: [ sh, -c, "buildctl debug workers" ]
            image: moby/buildkit:v0.12.1-rootless
            volumeMounts:
              - name: work
                mountPath: /work
              - name: docker-config
                mountPath: /.docker
            workingDir: /work/{{inputs.parameters.path}}
            env:
              - name: BUILDKITD_FLAGS
                value: --oci-worker-no-process-sandbox
              - name: DOCKER_CONFIG
                value: /.docker
            command:
              - buildctl-daemonless.sh
            args:
              - build
              - --frontend
              - dockerfile.v0
              - --local
              - context=.
              - --local
              - dockerfile=.
              - --output
              - type=image,name={{inputs.parameters.image}},push=true
              - build-arg:GOPROXY=http://goproxy.cn,direct
  2. Run the following command to create a WorkflowTemplate in the workflow cluster:

    kubectl --kubeconfig ${ackone_argo_kubeconfig} apply -f worktemplate-1.yaml

Create a WorkflowTemplate that uses NAS

This method uses NAS to share data between the pod created to clone code from a Git repository and the pod created to build images. For more information about how to provision NAS volumes in a workflow cluster, see Use volumes.

  1. Create a file named worktemplate-2.yaml based on the following YAML template.

    Specify a repository, a branch, and an image in the parameters section. Replace the username and token in the following template with the actual ones that are used.

    Show the content of worktemplate-2.yaml

    apiVersion: argoproj.io/v1alpha1
    kind: WorkflowTemplate
    metadata:
      name: build-echo-server
    spec:
      arguments:
        parameters:
          - name: repo
            value: https://github.com/ivan-cai/echo-server.git
          - name: branch
            value: main
          - name: path
            value: echo-server
          - name: image
            value: demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v2-argo
      entrypoint: main
      volumes:
        - name: work
          persistentVolumeClaim:
            claimName: pvc-nas
      templates:
        - name: main
          dag:
            tasks:
              - name: clone
                template: clone
                arguments:
                  parameters:
                    - name: repo
                      value: "{{workflow.parameters.repo}}"
                    - name: branch
                      value: "{{workflow.parameters.branch}}"
              - name: image
                template: image
                arguments:
                  parameters:
                    - name: path
                      value: "{{workflow.parameters.path}}"
                    - name: image
                      value: "{{workflow.parameters.image}}"
                depends: "clone"
        - name: clone
          inputs:
            parameters:
              - name: repo
              - name: branch
          container:
            volumeMounts:
              - mountPath: /work
                name: work
            image: alpine/git:v2.26.2
            workingDir: /work/
            # Do a shallow clone, which is the fastest way to clone, by using the
            # --depth, --branch, and --single-branch options
            command:
              - sh
              - -c
              - |
                if [ -d "{{workflow.parameters.path}}" ];then
                  rm -rf {{workflow.parameters.path}}
                fi
                git clone --depth 1 --branch {{inputs.parameters.branch}} --single-branch {{inputs.parameters.repo}}
        - name: image
          inputs:
            parameters:
              - name: path
              - name: image
          # Mount the configuration so we can push the image.
          # This should create the /.docker/config.json file.
          volumes:
            - name: docker-config
              secret:
                secretName: docker-config
          container:
            readinessProbe:
              exec:
                command: [ sh, -c, "buildctl debug workers" ]
            image: moby/buildkit:v0.9.3-rootless
            volumeMounts:
              - name: work
                mountPath: /work
              - name: docker-config
                mountPath: /.docker
            workingDir: /work/{{inputs.parameters.path}}
            env:
              - name: BUILDKITD_FLAGS
                value: --oci-worker-no-process-sandbox
              - name: DOCKER_CONFIG
                value: /.docker
            command:
              - buildctl-daemonless.sh
            args:
              - build
              - --frontend
              - dockerfile.v0
              - --local
              - context=.
              - --local
              - dockerfile=.
              - --output
              - type=image,name={{inputs.parameters.image}},push=true
              - build-arg:GOPROXY=http://goproxy.cn,direct
  2. Run the following command to create a WorkflowTemplate in the workflow cluster:

    kubectl --kubeconfig ${ackone_argo_kubeconfig} apply -f worktemplate-2.yaml

Step 3: Create a workflow

  1. Create a file named workflow.yaml based on the following YAML template:

    apiVersion: argoproj.io/v1alpha1
    kind: Workflow
    metadata:
      annotations:
        workflows.argoproj.io/pod-name-format: v1
      generateName: echo-server-
    spec:
      workflowTemplateRef:
        name: echo-server
  2. Run the following command to create a workflow in the workflow cluster:

    kubectl --kubeconfig ${ackone_argo_kubeconfig} create -f workflow.yaml

Step 4: View the workflow in the ACK One console

After you enable Internet access, you can access the Argo console from the Distributed Cloud Container Platform for Kubernetes (ACK One) console.

  1. Log on to the ACK One console. In the left-side navigation pane, click Workflow Cluster.

  2. On the Basic Information tab, click Workflow Console (Argo) in the Common Operations section.

  3. On the left side of the Workflow console, set NAMESPACE to default to view the workflow you created.