Version: v1.1

Initialize custom environment

This case will introduce what is environment and how to initialize an environment.

What is environment

An Application development team usually needs to initialize some shared environment for users. An environment is a logical concept that represents a set of common resources for Applications.

For example, a team usually wants two environments: one for development, and one for production.

In general, the resource types that can be initialized include the following types:

  1. One or more Kubernetes clusters. Different environments may need different sizes and versions of Kubernetes clusters. Environment initialization can also manage multiple clusters .

  2. Any type of Kubernetes custom resources (CRDS) and system plug-ins can be set up in environment initialization.

  3. All kinds of shared resources and services. For example. shared resources in microservices. These shared resources can be a microservice component, cloud database, cache, load balancer, API gateway, and so on.

  4. Various management policies and processes. An environment may have different global policies. The policy can be initializing a database table, registering an automatic discovery configuration, and so on.

Initialize the environment

KubeVela allows you to use different resources to initialize the environment.

You can use the Policy and Workflow in your Application. Note that there may be dependencies between initializations, we can use depends-on-app in workflow to do it.

The initialization of different environments has dependencies. Common resources can be separated as dependencies. In this way, reusable initialization modules can be formed.

For example, if both the test and develop environments rely on the same controllers, these controllers can be pulled out and initialized as separate environments, specifying dependency initialization in both the development and test environments.

How to use

Directly use Application for initialization

If we want to use kruise in cluster, we can use Helm to initialize kruise.

We can directly use Application to initialize a kruise environment. The application below will deploy a kruise controller in cluster:

  1. vela addon enable fluxcd
  1. cat <<EOF | kubectl apply -f -
  2. apiVersion: core.oam.dev/v1beta1
  3. kind: Application
  4. metadata:
  5. name: kruise
  6. namespace: vela-system
  7. spec:
  8. components:
  9. - name: kruise
  10. type: helm
  11. properties:
  12. branch: master
  13. chart: ./charts/kruise/v0.9.0
  14. version: "*"
  15. repoType: git
  16. url: https://github.com/openkruise/kruise
  17. workflow:
  18. steps:
  19. - name: check-flux
  20. type: depends-on-app
  21. properties:
  22. name: fluxcd
  23. namespace: vela-system
  24. - name: apply-kruise
  25. type: apply-component
  26. properties:
  27. component: kruise
  28. EOF

After applying the files, we can check the application in cluster:

  1. $ vela ls -n vela-system
  2. APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
  3. kruise ... raw running healthy 2021-09-24 20:59:06 +0800 CST
  4. fluxcd ... raw running healthy 2021-09-24 20:59:06 +0800 CST

Kruise is running successfully! Then you can use kruise in your cluster. If you need to set up a new environment, the only thing you need to do is to apply the files above.

Customize initialization dependencies

In the example above, depends-on-app means this initialization depends on the ability of fluxcd.

depends-on-app will check if the cluster has the application with name and namespace defines in properties.

If the application exists, the next step will be executed after the application is running. If the application do not exists, KubeVela will check the configMap with the same name, and read the config of the Application and apply to cluster.

If the application do not exists, we need configMap like below:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: fluxcd
  5. namespace: vela-system
  6. data:
  7. fluxcd: ...

Add initialize workflow in application

Some Kubernetes native resources like ConfigMap/PVC are commonly used in the environment.

If you want to apply those resources before deploying your application, you can add an initialization workflow to your application.

KubeVela provides a built-in workflow step apply-object to fill in native Kubernetes resources. In this way, by filling in Kubernetes native resources, we can avoid writing redundant component definitions.

Apply the following application, it will initialize an environment with ConfigMap/PVC. There is two components in this application, the first one will write data to PVC, the second on will read the data from PVC:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: server-with-pvc-and-cm
  5. namespace: default
  6. spec:
  7. components:
  8. - name: log-gen-worker
  9. type: worker
  10. properties:
  11. image: busybox
  12. cmd:
  13. - /bin/sh
  14. - -c
  15. - >
  16. i=0;
  17. while true;
  18. do
  19. echo "$i: $(date)" >> /test-pvc/date.log;
  20. i=$((i+1));
  21. sleep 1;
  22. done
  23. volumes:
  24. - name: "my-pvc"
  25. type: "pvc"
  26. mountPath: "/test-pvc"
  27. claimName: "my-claim"
  28. - name: "my-configmap"
  29. type: "configMap"
  30. mountPath: "/test-cm"
  31. cmName: "my-cm"
  32. items:
  33. - key: test-key
  34. path: test-key
  35. - name: log-read-worker
  36. type: worker
  37. properties:
  38. name: count-log
  39. image: busybox
  40. cmd:
  41. - /bin/sh
  42. - -c
  43. - 'tail -n+1 -f /test-pvc/date.log'
  44. volumes:
  45. - name: "my-pvc"
  46. type: "pvc"
  47. mountPath: "/test-pvc"
  48. claimName: "my-claim"
  49. - name: "my-configmap"
  50. type: "configMap"
  51. mountPath: "/test-cm"
  52. cmName: "my-cm"
  53. items:
  54. - key: test-key
  55. path: test-key
  56. workflow:
  57. steps:
  58. - name: apply-pvc
  59. type: apply-object
  60. properties:
  61. apiVersion: v1
  62. kind: PersistentVolumeClaim
  63. metadata:
  64. name: my-claim
  65. namespace: default
  66. spec:
  67. accessModes:
  68. - ReadWriteOnce
  69. resources:
  70. requests:
  71. storage: 8Gi
  72. storageClassName: standard
  73. - name: apply-cm
  74. type: apply-object
  75. properties:
  76. apiVersion: v1
  77. kind: ConfigMap
  78. metadata:
  79. name: my-cm
  80. namespace: default
  81. data:
  82. test-key: test-value
  83. - name: apply-remaining
  84. type: apply-remaining

Check the PVC and ConfigMap in cluster:

  1. $ kubectl get pvc
  2. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  3. my-claim Bound pvc-2621d7d7-453c-41df-87fb-58e6b3a8e136 8Gi RWO standard 2m53s
  4. $ kubectl get cm
  5. NAME DATA AGE
  6. my-cm 1 3m8s

Check the application in cluster:

  1. $ vela ls
  2. APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
  3. server-with-pvc-and-cm log-gen-worker worker running healthy 2021-10-11 20:42:38 +0800 CST
  4. └─ log-read-worker worker running 2021-10-11 20:42:38 +0800 CST

Check the logs of the second component:

  1. $ kubectl logs -f log-read-worker-774b58f565-ch8ch
  2. 0: Mon Oct 11 12:43:01 UTC 2021
  3. 1: Mon Oct 11 12:43:02 UTC 2021
  4. 2: Mon Oct 11 12:43:03 UTC 2021
  5. 3: Mon Oct 11 12:43:04 UTC 2021
  6. 4: Mon Oct 11 12:43:05 UTC 2021
  7. 5: Mon Oct 11 12:43:06 UTC 2021
  8. 6: Mon Oct 11 12:43:07 UTC 2021
  9. 7: Mon Oct 11 12:43:08 UTC 2021

We can see that both components is running. The two components share the same PVC and use the same ConfigMap.