组件分裂

在 KubeVela 中,我们可以使用 deploy 工作流步骤和 overridetopology 策略。但是例如OpenYurt 的项目中,有对集群具有更细粒度划分,例如”节点池”。需要将一些类似的资源下发到同一集群。这些资源称为replication。回到 OpenYurt 的例子,它可以集成 KubeVela,并将分裂出的多个相似 K8s 资源下发到不同的节点池。

为了将一个组件分裂为多个,我们添加了一个内置策略 replication。它只能与 deploy 工作流步骤一起使用。如果在 deploy 工作流步骤中使用 replication 策略,则在渲染组件时将向上下文添加一个新字段 context.replicaKey 。可以向下发一些资源到集群中,他们带有不同的 replicaKey

组件分裂 - 图1备注

replication 策略仅在 KubeVela 1.6.0+ 版本中支持。

组件分裂 - 图2提示

context.replicaKey 经常在组件定义或运维特征定义中下发资源的 metadata.name 字段中使用,以避免名称冲突。我们将在后面的示例中看到它。

下面的组件定义是一个使用策略的示例 replication。它用 context.replicaKey 给的名称加上后缀。

  1. import (
  2. "strconv"
  3. )
  4. "replica-webservice": {
  5. alias: ""
  6. annotations: {}
  7. attributes: {
  8. status: {}
  9. workload: {
  10. definition: {
  11. apiVersion: "apps/v1"
  12. kind: "Deployment"
  13. }
  14. type: "deployments.apps"
  15. }
  16. }
  17. description: "Webservice, but can be replicated"
  18. labels: {}
  19. type: "component"
  20. }
  21. template: {
  22. output: {
  23. apiVersion: "apps/v1"
  24. kind: "Deployment"
  25. metadata: {
  26. if context.replicaKey != _|_ {
  27. name: context.name + "-" + context.replicaKey
  28. }
  29. if context.replicaKey == _|_ {
  30. name: context.name
  31. }
  32. }
  33. spec: {
  34. selector: matchLabels: {
  35. "app.oam.dev/component": context.name
  36. if context.replicaKey != _|_ {
  37. "app.oam.dev/replicaKey": context.replicaKey
  38. }
  39. }
  40. template: {
  41. metadata: {
  42. labels: {
  43. if parameter.labels != _|_ {
  44. parameter.labels
  45. }
  46. "app.oam.dev/name": context.appName
  47. "app.oam.dev/component": context.name
  48. if context.replicaKey != _|_ {
  49. "app.oam.dev/replicaKey": context.replicaKey
  50. }
  51. }
  52. }
  53. spec: {
  54. containers: [{
  55. name: context.name
  56. image: parameter.image
  57. if parameter["ports"] != _|_ {
  58. ports: [ for v in parameter.ports {
  59. {
  60. containerPort: v.port
  61. name: "port-" + strconv.FormatInt(v.port, 10)
  62. }}]
  63. }
  64. }]
  65. }
  66. }
  67. }
  68. }
  69. exposePorts: [
  70. for v in parameter.ports {
  71. port: v.port
  72. targetPort: v.port
  73. name: "port-" + strconv.FormatInt(v.port, 10)
  74. },
  75. ]
  76. outputs: {
  77. if len(exposePorts) != 0 {
  78. webserviceExpose: {
  79. apiVersion: "v1"
  80. kind: "Service"
  81. metadata: {
  82. if context.replicaKey != _|_ {
  83. name: context.name + "-" + context.replicaKey
  84. }
  85. if context.replicaKey == _|_ {
  86. name: context.name
  87. }
  88. }
  89. spec: {
  90. selector: {
  91. "app.oam.dev/component": context.name
  92. if context.replicaKey != _|_ {
  93. "app.oam.dev/replicaKey": context.replicaKey
  94. }
  95. }
  96. ports: exposePorts
  97. }
  98. }
  99. }
  100. }
  101. parameter: {
  102. // +usage=Which image would you like to use for your service
  103. // +short=i
  104. image: string
  105. // +usage=Which ports do you want customer traffic sent to, defaults to 80
  106. ports?: [...{
  107. // +usage=Number of port to expose on the pod's IP address
  108. port: int
  109. }]
  110. }
  111. }

将定义复制到文件 replica-webservice.cue 并应用定义:

  1. vela def apply replica-webservice.cue

然后,用户可以创建下面的应用程序。replication 策略是在其中的 application.spec.policies 字段声明。并在 deploy 步骤中使用它来影响其结果。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: app-replication-policy
  5. spec:
  6. components:
  7. - name: hello-rep
  8. type: replica-webservice
  9. properties:
  10. image: crccheck/hello-world
  11. ports:
  12. - port: 80
  13. expose: true
  14. policies:
  15. - name: replication-default
  16. type: replication
  17. properties:
  18. keys: [ "beijing","hangzhou" ]
  19. selector: [ "hello-rep" ]
  20. workflow:
  21. steps:
  22. - name: deploy-with-rep
  23. type: deploy
  24. properties:
  25. policies: [ "replication-default" ]

然后,应用程序将下发两个 Deployment 和两个 Service:

  1. vela status app-replication-policy --detail --tree
  1. CLUSTER NAMESPACE RESOURCE STATUS APPLY_TIME DETAIL
  2. local ─── default─┬─ Service/hello-rep-beijing updated 2022-11-03 11:26:03 Type: ClusterIP Cluster-IP: 10.43.26.211 External-IP: <none>
  3. Port(s): 80/TCP Age: 3h10m
  4. ├─ Service/hello-rep-hangzhou updated 2022-11-03 11:26:03 Type: ClusterIP Cluster-IP: 10.43.36.44 External-IP: <none>
  5. Port(s): 80/TCP Age: 3h10m
  6. ├─ Deployment/hello-rep-beijing updated 2022-11-03 11:26:03 Ready: 1/1 Up-to-date: 1 Available: 1 Age: 3h10m
  7. └─ Deployment/hello-rep-hangzhou updated 2022-11-03 11:26:03 Ready: 1/1 Up-to-date: 1 Available: 1 Age: 3h10m

在步骤中可以使用三种策略 deploytopologyoverridereplication。它们可以一起用于分裂组件和将组件下发到不同的集群。下面是它们一起使用时的规则:

  1. 策略的应用顺序为 topology -> override -> replication 。更多详细信息,可以参阅多集群应用
    • topology 选择要下发集群。如果不使用,则默认情况下应用程序将资源部署到 Local 群集。
    • override 修改组件 Properties。如果不使用,则不会更改任何属性。
    • replication 将一个组件分裂为多个组分裂

组件分裂 - 图3备注

默认情况下,KubeVela 所在的控制集群被注册为本地集群。你可以像使用管控集群一样使用它,但是你无法 detach 或 modify 这个集群。

  1. override 并且 replication 可以一起使用。但 override 会影响所有分裂的组件。override 的主要用意是修改不同群集中的同一个组件的属性。

Last updated on 2023年8月4日 by Daniel Higuero