Unified Declarative CI/CD

From code to application, one of the indispensable step is to build image. This section will introduce how to orchestrate image build, image push and application delivery in KubeVela.

KubeVela introduced standalone workflow in version v1.6 that can be used independently, which can be used to orchestrate the process between CI steps and application delivery. Different from the workflow in the KubeVela application, it is one-time and does not manage resources. Even if the workflow is deleted, the created resources will not be deleted.

Unified Declarative CI/CD - 图1tip

Please make sure that you have enabled workflow addon with vela addon enable vela-workflow.

Apply the following workflow:

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: build-push-image
  5. namespace: default
  6. spec:
  7. context:
  8. image: my-registry/test-image:v2
  9. workflowSpec:
  10. steps:
  11. # or use kubectl create secret generic git-token --from-literal='GIT_TOKEN=<your-token>'
  12. - name: create-git-secret
  13. type: export2secret
  14. properties:
  15. secretName: git-secret
  16. data:
  17. token: <git token>
  18. # or use kubectl create secret docker-registry docker-regcred \
  19. # --docker-server=https://index.docker.io/v1/ \
  20. # --docker-username=<your-username> \
  21. # --docker-password=<your-password>
  22. - name: create-image-secret
  23. type: export2secret
  24. properties:
  25. secretName: image-secret
  26. kind: docker-registry
  27. dockerRegistry:
  28. username: <username>
  29. password: <password>
  30. - name: build-push
  31. type: build-push-image
  32. inputs:
  33. - from: context.image
  34. parameterKey: image
  35. properties:
  36. # use your kaniko executor image like below, if not set, it will use default image oamdev/kaniko-executor:v1.9.1
  37. # kanikoExecutor: gcr.io/kaniko-project/executor:latest
  38. # you can use context with git and branch or directly specify the context, please refer to https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts
  39. context:
  40. git: github.com/FogDong/simple-web-demo
  41. branch: main
  42. # Note that this field will be replaced by the image in inputs
  43. image: my-registry/test-image:v1
  44. # specify your dockerfile, if not set, it will use default dockerfile ./Dockerfile
  45. # dockerfile: ./Dockerfile
  46. credentials:
  47. image:
  48. name: image-secret
  49. # buildArgs:
  50. # - key="value"
  51. # platform: linux/arm
  52. - name: apply-app
  53. type: apply-app
  54. inputs:
  55. - from: context.image
  56. parameterKey: data.spec.components[0].properties.image
  57. properties:
  58. data:
  59. apiVersion: core.oam.dev/v1beta1
  60. kind: Application
  61. metadata:
  62. name: my-app
  63. spec:
  64. components:
  65. - name: my-web
  66. type: webservice
  67. properties:
  68. # Note that this field will be replaced by the image in inputs
  69. image: my-registry/test-image:v1
  70. imagePullSecrets:
  71. - image-secret
  72. ports:
  73. - port: 80
  74. expose: true

The workflow has four steps in total:

  1. Create a secret with Git token, which is used to pull the code from the private repository to build the image. If your repository is public, you can skip this step. You can also skip this step and use the kubectl create secret generic git-token --from-literal='GIT_TOKEN=<your-token>' command to create the secret.
  2. Create a secret with the image registry token to push the image to your image registry. You can also skip this step and use kubectl create secret docker-registry docker-regcred --docker-server=https://index.docker.io/v1/ --docker-username=<your-username> -- docker-password=<your-password> command to create the secret.
  3. Use the build-push-image step type to build and push the image. This step will use the specified Git url and the code in its branch to build the image. You can also directly specify in the context field. The bottom layer of this step will use Kaniko for image building. During the building, you can use vela workflow logs build-push-image --step build-push to view the log of the step. Note that this step has an input from context.image, which will override the image field in properties. As you can see, we currently declare image: my-registry/test-image:v2 in the context. When we need to reuse this workflow to build a new image version, we only need to update the data in the context to update the entire process.
  4. In the last step, the image version in context.image will be used to publish the application. When the application starts, you can use vela port-forward my-app 8080:80 to check the result.

If you configure the process in VelaUX’s Pipeline, you can directly see the status and sequence of all steps on the page, including step logs, input and output, etc.

Unified Declarative CI/CD - 图2

You can also directly build the image in the application, and use the newly built image in the component. Apply the following application:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: build-push-image
  5. namespace: default
  6. spec:
  7. components:
  8. - name: my-web
  9. type: webservice
  10. properties:
  11. image: my-registry/test-image:v1
  12. ports:
  13. - port: 80
  14. expose: true
  15. workflow:
  16. steps:
  17. - name: build-push
  18. type: build-push-image
  19. properties:
  20. # use your kaniko executor image like below, if not set, it will use default image oamdev/kaniko-executor:v1.9.1
  21. # kanikoExecutor: gcr.io/kaniko-project/executor:latest
  22. # you can use context with git and branch or directly specify the context, please refer to https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts
  23. context:
  24. git: github.com/FogDong/simple-web-demo
  25. branch: main
  26. # you must align the image value with image field of the component properties
  27. image: my-registry/test-image:v1
  28. # specify your dockerfile, if not set, it will use default dockerfile ./Dockerfile
  29. # dockerfile: ./Dockerfile
  30. credentials:
  31. image:
  32. name: image-secret
  33. # buildArgs:
  34. # - key="value"
  35. # platform: linux/arm
  36. - name: apply-comp
  37. type: apply-component
  38. properties:
  39. component: my-web

In the application above, the first step in the workflow will use the build-push-image step to build the image, and the second step will deploy the component with the newly built image.

Last updated on Aug 4, 2023 by Daniel Higuero