Version: v1.1

自定义环境初始化

本案例将介绍环境的概念以及如何初始化一个环境。

什么是环境?

一个应用开发团队通常需要初始化一些共享环境供用户部署他们的应用部署计划(Application)。环境是一个逻辑概念,他表示一组应用部署计划依赖的公共资源。 例如,一个团队想要初始化2个环境: 一个开发环境用于开发和测试,一个生产环境用于实际应用部署并提供对外服务。 管理员可以针对环境所代表的实际含义配置相关的初始化方式,创建不同的资源。

环境初始化背后也是用 OAM 模型的方式来执行的,所以环境初始化控制器的功能非常灵活,几乎可以满足任何初始化的需求,同时也是可插拔的。通常而言,可以初始化的资源类型包括但不限于下列类型:

  1. 一个或多个 Kubernetes 集群,不同的环境可能需要不同规模和不同版本的 Kubernetes 集群。同时环境初始化还可以将多个 Kubernetes 集群注册到一个中央集群进行统一的多集群管控。

  2. 任意类型的 Kubernetes 自定义资源(CRD)和系统插件,一个环境会拥有很多种不同的自定义资源来提供系统能力,比如不同的工作负载、不同的运维管理功能等等。初始化环境可以包含环境所依赖的一系列功能的初始化安装,比如各类中间件工作负载、流量管理、日志监控等各类运维系统。

  3. 各类共享资源和服务,一个微服务在不同环境中测试验证时,除了自身所开发的组件以外,往往还会包含一系列其他团队维护的组件和一些公共资源。环境初始化功能可以将其他组件和公共资源统一部署,在无需使用时销毁。这些共享资源可以是一个微服务组件、云数据库、缓存、负载均衡、API网关等等。

  4. 各类管理策略和流程,一个环境可能会配备不同的全局策略和流程,举例来说,环境策略可能会包括混沌测试、安全扫描、错误配置检测、SLO指标等等;而流程则可以是初始化一个数据库表、注册一个自动发现配置等。

环境初始化

KubeVela 允许你自定义组合不同的资源来初始化环境。

你可以利用应用部署计划中的 “应用的执行策略(Policy)” 和 “部署工作流(Workflow)” 来流程化、配置化地创建环境。需要注意的是,多个环境初始化 之间可能会存在依赖关系,一个环境初始化会依赖其他环境初始化提供的能力。我们通过工作流中的 depends-on-app 来完成依赖关系的确定。

不同环境初始化存在依赖关系,可以将不同环境初始化的公共资源分离出一个单独的环境初始化作为依赖,这样可以形成可以被复用的初始化模块。 例如,测试环境和开发环境都依赖了一些相同的控制器,可以将这些控制器提取出来作为单独的环境初始化,在开发环境和测试环境中都指定依赖该环境初始化。

如何使用

直接使用应用部署计划完成环境初始化

如果我们希望在环境中使用 kruise 的能力,那么,我们可以使用 Helm 组件初始化 kruise。

我们可以直接使用应用部署计划来初始化 kruise 的环境,该应用会帮你在集群中部署一个 kruise 的控制器,给集群提供 kruise 的各种能力:

  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

部署如上文件后,可以查看集群中应用的状态:

  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 已经成功运行!之后,你可以在环境中使用 kruise 的能力。如果需要配置新的环境,也只需要部署如上应用文件。

自定义初始化依赖关系

在应用的工作流中,depends-on-app 表示环境初始化 kruise 依赖环境初始化 fluxcd 提供的能力。

depends-on-app 会根据 properties 中的 namenamespace,去查询集群中是否存在对应的应用。

如果应用存在,则当该应用的状态可用时,才会进行下一个步骤; 若该应用不存在,则会去查询同名的 configMap,从中读取出应用的配置并部署到集群中。

若应用不存在,则需要形如下的 configMap:

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

在应用部署中加入初始化的工作流

在环境中,一些通用的 ConfigMap / PVC 等资源是十分常用的。 如果你希望在部署应用前内置一些通用资源,可以在应用部署中加入初始化的工作流来完成。

KubeVela 提供了一个内置的工作流步骤 apply-object,可以直接在组件的 properties 字段中填写创建到环境中的原生 Kubernetes 资源。 这种在 Application 中直接填写 Kubernetes 原生资源的方式,可以避免编写多余的组件定义(ComponentDefinition)。

部署如下应用,初始化一个带有 ConfigMap / PVC 的环境。同时,部署两个组件,第一个组件会不断向 PVC 中写入数据,第二个组件会读取 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

查看集群中的 PVC 以及 ConfigMap:

  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

查看集群中应用的状态:

  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

检查第二个组件的日志输出:

  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

可以看到,应用中的两个组件均已正常运行。同时,这两个组件共享同一个 PVC,并使用相同的 ConfigMap 进行配置。