多集群应用交付

本章节将会介绍如何使用 KubeVela 分发多集群应用。

如今,在越来越多的场景下,开发者和系统运维人员开始将应用部署在多个集群中:

  • 由于 Kubernetes 集群存在着部署规模的局限性(单一集群最多容纳 5k 节点),需要应用多集群技术来部署、管理海量的应用。
  • 考虑到稳定性及高可用性,同一个应用可以部署在多个集群中,以实现容灾、异地多活等需求。
  • 应用可能需要部署在不同的区域来满足不同政府对于数据安全性的政策需求。

多集群应用交付 - 图1

KubeVela 的多集群依赖于 Cluster-Gateway 组件,在 KubeVela 的 Helm Chart 中自动安装。 默认情况下,KubeVela 管理多集群的方式是通过 kubeconfig 直连集群,你也可以使用 Open Cluster Management 组件来使用拉取(PULL)模式。

下文将会介绍如何在 KubeVela 中进行使用管理多集群应用。

在使用多集群应用部署之前,你需要将子集群通过 KubeConfig 加入到 KubeVela 的管控中来。Vela CLI 可以帮你实现这一点。

  1. vela cluster join <your kubeconfig path>

该命令会自动使用 KubeConfig 中的 context.cluster 字段作为集群名称,你也可以使用 --name 参数来指定,如

  1. $ vela cluster join beijing.kubeconfig --name beijing
  2. $ vela cluster join hangzhou-1.kubeconfig --name hangzhou-1
  3. $ vela cluster join hangzhou-2.kubeconfig --name hangzhou-2

在子集群加入 KubeVela 中后,你同样可以使用 CLI 命令来查看当前正在被 KubeVela 管控的所有集群。

  1. $ vela cluster list
  2. CLUSTER TYPE ENDPOINT ACCEPTED LABELS
  3. local Internal - true
  4. cluster-beijing X509Certificate <ENDPOINT_BEIJING> true
  5. cluster-hangzhou-1 X509Certificate <ENDPOINT_HANGZHOU_1> true
  6. cluster-hangzhou-2 X509Certificate <ENDPOINT_HANGZHOU_2> true

默认情况下,KubeVela 控制面所在的管控集群会被作为 local 集群进行注册。你可以通过它将应用资源部署在管控集群中。该 local 集群不能被修改或者删除。

如果你不需要某个子集群了,还可以将子集群从 KubeVela 管控中移除。

  1. $ vela cluster detach beijing

移除一个正在使用的集群是危险行为。不过如果你想要对集群的认证信息做修改,比如轮转证书,你可以强行删除它。

你也可以给你的集群打标签,帮助你选择要部署的集群。

  1. $ vela cluster labels add cluster-hangzhou-1 region=hangzhou
  2. $ vela cluster labels add cluster-hangzhou-2 region=hangzhou
  3. $ vela cluster list
  4. CLUSTER TYPE ENDPOINT ACCEPTED LABELS
  5. local Internal - true
  6. cluster-beijing X509Certificate <ENDPOINT_BEIJING> true
  7. cluster-hangzhou-1 X509Certificate <ENDPOINT_HANGZHOU_1> true region=hangzhou
  8. cluster-hangzhou-2 X509Certificate <ENDPOINT_HANGZHOU_2> true region=hangzhou

你只需要使用 topology 策略来声明要部署的集群,就可以部署多集群应用了。例如,你可以使用下面这个样例将 nginx webservice 部署在两个杭州集群中,

  1. $ cat <<EOF | vela up -f -
  2. apiVersion: core.oam.dev/v1beta1
  3. kind: Application
  4. metadata:
  5. name: basic-topology
  6. namespace: examples
  7. spec:
  8. components:
  9. - name: nginx-basic
  10. type: webservice
  11. properties:
  12. image: nginx
  13. traits:
  14. - type: expose
  15. properties:
  16. port: [80]
  17. policies:
  18. - name: topology-hangzhou-clusters
  19. type: topology
  20. properties:
  21. clusters: ["cluster-hangzhou-1", "cluster-hangzhou-2"]
  22. EOF

你可以通过运行 vela status 来查看部署状态。

  1. $ vela status basic-topology -n examples
  2. About:
  3. Name: basic-topology
  4. Namespace: examples
  5. Created at: 2022-04-08 14:37:54 +0800 CST
  6. Status: workflowFinished
  7. Workflow:
  8. mode: DAG
  9. finished: true
  10. Suspend: false
  11. Terminated: false
  12. Steps
  13. - id:3mvz5i8elj
  14. name:deploy-topology-hangzhou-clusters
  15. type:deploy
  16. phase:succeeded
  17. message:
  18. Services:
  19. - Name: nginx-basic
  20. Cluster: cluster-hangzhou-1 Namespace: examples
  21. Type: webservice
  22. Healthy Ready:1/1
  23. Traits:
  24. expose
  25. - Name: nginx-basic
  26. Cluster: cluster-hangzhou-2 Namespace: examples
  27. Type: webservice
  28. Healthy Ready:1/1
  29. Traits:
  30. expose

你可以运行以下 CLI 命令调试上述的多集群应用。通过这些 CLI 命令,你可以在管控集群上直接操纵子集群中的资源,而不需要切换 KubeConfig 等集群配置。如果你的应用使用了多个集群,CLI 向你询问你希望操纵的集群。

  • vela status 如上文所示,为你展示多集群应用的整体部署情况。
  • vela logs 查询子集群中的 Pod 日志。
  1. $ vela logs basic-topology -n examples
  2. ? You have 2 deployed resources in your app. Please choose one: Cluster: cluster-hangzhou-1 | Namespace: examples | Kind: Deployment | Name: nginx-basic
  3. + nginx-basic-dfb6dcf8d-km5vk nginx-basic
  4. nginx-basic-dfb6dcf8d-km5vk nginx-basic 2022-04-08T06:38:10.540430392Z /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
  5. nginx-basic-dfb6dcf8d-km5vk nginx-basic 2022-04-08T06:38:10.540742240Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
  • vela exec 帮助你在子集群的 Pod 里执行命令。
  1. $ vela exec basic-topology -n examples -it -- ls
  2. ? You have 2 deployed resources in your app. Please choose one: Cluster: cluster-hangzhou-1 | Namespace: examples | Kind: Deployment | Name: nginx-basic
  3. bin docker-entrypoint.d home media proc sbin tmp
  4. boot docker-entrypoint.sh lib mnt root srv usr
  5. dev etc lib64 opt run sys var
  • vela port-forward 将子集群中的 Pod 或者 Service 通过端口映射到本地使其可以在本地被访问。
  1. $ vela port-forward basic-topology -n examples 8080:80
  2. ? You have 4 deployed resources in your app. Please choose one: Cluster: cluster-hangzhou-1 | Namespace: examples | Kind: Deployment | Name: nginx-basic
  3. Forwarding from 127.0.0.1:8080 -> 80
  4. Forwarding from [::1]:8080 -> 80
  5. Forward successfully! Opening browser ...
  6. Handling connection for 8080

下图为多集群应用的整体结构图。如图所示,所有的配置信息(包括应用、策略和工作流)都处于管控集群中。只有资源(如 deployment 或者 service)会被下发到子集群之中。

策略主要负责描述资源的位置以及它们应该如何被差异化配置。资源下发真正的执行者是工作流。在工作流中,deploy 步骤会根据引用的策略对资源进行差异化配置,然后再将它们分发到对应的集群中。

multi-cluster-arch

选择部署目标的最直接的方法就是在 topology 策略中声明你想要部署的集群名称。有的时候,使用标签来筛选要部署的集群会更方便,比如下面这个例子通过标签筛选出所有的杭州集群:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: label-selector-topology
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-label-selector
  9. type: webservice
  10. properties:
  11. image: nginx
  12. policies:
  13. - name: topology-hangzhou-clusters
  14. type: topology
  15. properties:
  16. clusterLabelSelector:
  17. region: hangzhou

如果你想要在管控集群中部署应用,你也可以使用 local 集群。除此之外,你还可以选择希望部署的命名空间,取代应用原有的命名空间。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: local-ns-topology
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-local-ns
  9. type: webservice
  10. properties:
  11. image: nginx
  12. policies:
  13. - name: topology-local
  14. type: topology
  15. properties:
  16. clusters: ["local"]
  17. namespace: examples-alternative

有时,出于安全考虑,你可能希望限制应用使其只能在自己的命名空间中部署资源。你可以通过在 KubeVela 控制器的启动参数中配置 --allow-cross-namespace-resource=false 来禁用跨命名空间部署。

默认情况下,如果你在应用中声明了多个 topology 策略,应用组件将会依次分发到这些目标位置上。

如果你想要控制整个部署流程,比如更改默认的部署顺序,或者是添加人工审核步骤,你可以显式使用 deploy 工作流步骤来实现。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: deploy-workflowstep
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-deploy-workflowstep
  9. type: webservice
  10. properties:
  11. image: nginx
  12. policies:
  13. - name: topology-hangzhou-clusters
  14. type: topology
  15. properties:
  16. clusterLabelSelector:
  17. region: hangzhou
  18. - name: topology-local
  19. type: topology
  20. properties:
  21. clusters: ["local"]
  22. namespace: examples-alternative
  23. workflow:
  24. steps:
  25. - type: deploy
  26. name: deploy-local
  27. properties:
  28. policies: ["topology-local"]
  29. - type: deploy
  30. name: deploy-hangzhou
  31. properties:
  32. # require manual approval before running this step
  33. auto: false
  34. policies: ["topology-hangzhou-clusters"]

如果你希望并行地部署所有集群,你可以在一个 deploy 工作流步骤中使用所有的 topology 策略。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: deploy-concurrently
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-deploy-concurrently
  9. type: webservice
  10. properties:
  11. image: nginx
  12. policies:
  13. - name: topology-hangzhou-clusters
  14. type: topology
  15. properties:
  16. clusterLabelSelector:
  17. region: hangzhou
  18. - name: topology-local
  19. type: topology
  20. properties:
  21. clusters: ["local"]
  22. namespace: examples-alternative
  23. workflow:
  24. steps:
  25. - type: deploy
  26. name: deploy-all
  27. properties:
  28. policies: ["topology-local", "topology-hangzhou-clusters"]

在一些情况下,你可能希望应用在不同的集群中有不一样的配置,而不是全都使用完全相同的默认配置。比如使用不同的镜像或者配置不同的副本数量。

override 策略可以帮助你实现差异化配置。你可以在 deploy 工作流步骤中,配合 topology 策略来使用它。

在下面的样例中,应用会在 local 集群中部署一个默认的 nginx webservcie,然后在杭州集群中部署含有 3 副本的高可用 nginx webservice,并且使用 nginx:1.20 镜像。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: deploy-with-override
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-with-override
  9. type: webservice
  10. properties:
  11. image: nginx
  12. policies:
  13. - name: topology-hangzhou-clusters
  14. type: topology
  15. properties:
  16. clusterLabelSelector:
  17. region: hangzhou
  18. - name: topology-local
  19. type: topology
  20. properties:
  21. clusters: ["local"]
  22. namespace: examples-alternative
  23. - name: override-nginx-legacy-image
  24. type: override
  25. properties:
  26. components:
  27. - name: nginx-with-override
  28. properties:
  29. image: nginx:1.20
  30. - name: override-high-availability
  31. type: override
  32. properties:
  33. components:
  34. - type: webservice
  35. traits:
  36. - type: scaler
  37. properties:
  38. replicas: 3
  39. workflow:
  40. steps:
  41. - type: deploy
  42. name: deploy-local
  43. properties:
  44. policies: ["topology-local"]
  45. - type: deploy
  46. name: deploy-hangzhou
  47. properties:
  48. policies: ["topology-hangzhou-clusters", "override-nginx-legacy-image", "override-high-availability"]

注意:override 策略是用来修改基础配置的策略,因此它被设计成必须需要和 topology 策略一同使用。如果你不想要使用 topology 策略,你可以直接将配置写在组件声明中,而不是使用 override 策略。如果你错误的在 deploy 工作流步骤中使用了 override 策略,而没有使用 topology 策略,应用不会发生错误,但是也不会下发任何资源。

差异化配置有一些高级配置能力,比如添加额外的组件,或者选择部分组件。下面的样例中,应用会首先在 local 集群中部署一个镜像为 nginx:1.20 的 webservice,然后再将 nginxnginx:stable 两个 webservice 部署到杭州集群中

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: advance-override
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-advance-override-legacy
  9. type: webservice
  10. properties:
  11. image: nginx:1.20
  12. - name: nginx-advance-override-latest
  13. type: webservice
  14. properties:
  15. image: nginx
  16. policies:
  17. - name: topology-hangzhou-clusters
  18. type: topology
  19. properties:
  20. clusterLabelSelector:
  21. region: hangzhou
  22. - name: topology-local
  23. type: topology
  24. properties:
  25. clusters: ["local"]
  26. namespace: examples-alternative
  27. - name: override-nginx-legacy
  28. type: override
  29. properties:
  30. selector: ["nginx-advance-override-legacy"]
  31. - name: override-nginx-latest
  32. type: override
  33. properties:
  34. selector: ["nginx-advance-override-latest", "nginx-advance-override-stable"]
  35. components:
  36. - name: nginx-advance-override-stable
  37. type: webservice
  38. properties:
  39. image: nginx:stable
  40. workflow:
  41. steps:
  42. - type: deploy
  43. name: deploy-local
  44. properties:
  45. policies: ["topology-local", "override-nginx-legacy"]
  46. - type: deploy
  47. name: deploy-hangzhou
  48. properties:
  49. policies: ["topology-hangzhou-clusters", "override-nginx-latest"]

有时,你可能希望在不同的应用之间使用相同的策略,或者在部署资源的时候复用之前的工作流配置。 为了减少重复的配置,你可以使用外置的策略和工作流,并在应用中引用它们。

注意:你只能在应用中引用相同命名空间下的策略和工作流。

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: Policy
  3. metadata:
  4. name: topology-hangzhou-clusters
  5. namespace: examples
  6. type: topology
  7. properties:
  8. clusterLabelSelector:
  9. region: hangzhou
  10. ---
  11. apiVersion: core.oam.dev/v1alpha1
  12. kind: Policy
  13. metadata:
  14. name: override-high-availability-webservice
  15. namespace: examples
  16. type: override
  17. properties:
  18. components:
  19. - type: webservice
  20. traits:
  21. - type: scaler
  22. properties:
  23. replicas: 3
  24. ---
  25. apiVersion: core.oam.dev/v1alpha1
  26. kind: Workflow
  27. metadata:
  28. name: make-release-in-hangzhou
  29. namespace: examples
  30. steps:
  31. - type: deploy
  32. name: deploy-hangzhou
  33. properties:
  34. auto: false
  35. policies: ["override-high-availability-webservice", "topology-hangzhou-clusters"]
  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: external-policies-and-workflow
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-external-policies-and-workflow
  9. type: webservice
  10. properties:
  11. image: nginx
  12. workflow:
  13. ref: make-release-in-hangzhou

注意:内置的策略会被优先使用。只有当工作流使用的策略不存在于内置策略中时才会使用外置策略。在下面的样例中,你可以复用 topology-hangzhou-clusters 策略以及 make-release-in-hangzhou 工作流,但是通过在应用中声明 override-high-availability-webservice 策略来覆盖同名的外置策略。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: nginx-stable-ultra
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-stable-ultra
  9. type: webservice
  10. properties:
  11. image: nginx:stable
  12. policies:
  13. - name: override-high-availability-webservice
  14. type: override
  15. properties:
  16. components:
  17. - type: webservice
  18. traits:
  19. - type: scaler
  20. properties:
  21. replicas: 5
  22. workflow:
  23. ref: make-release-in-hangzhou

多集群部署的功能可以结合自定义工作流步骤 实现功能多样的多集群调度能力.

如下示例所示,我们会部署一个任务到 local 集群的 default 命名空间,然后通过 read-object 步骤检查部署状态,最后根据状态将任务部署到 prod 命名空间。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: deploy-with-override
  5. spec:
  6. components:
  7. - name: mytask
  8. type: task
  9. properties:
  10. image: bash
  11. count: 1
  12. cmd: ["echo", "hello world"]
  13. policies:
  14. - name: target-default
  15. type: topology
  16. properties:
  17. clusters: ["local"]
  18. namespace: "default"
  19. - name: target-prod
  20. type: topology
  21. properties:
  22. clusters: ["local"]
  23. namespace: "prod"
  24. - name: override-annotations-1
  25. type: override
  26. properties:
  27. components:
  28. - type: task
  29. traits:
  30. - type: annotations
  31. properties:
  32. "description": "01 cron task - 1"
  33. - name: override-annotations-2
  34. type: override
  35. properties:
  36. components:
  37. - type: task
  38. traits:
  39. - type: annotations
  40. properties:
  41. "description": "02 cron task - 2"
  42. workflow:
  43. steps:
  44. - type: deploy
  45. name: deploy-01
  46. properties:
  47. policies: ["target-default", "override-annotations-1"]
  48. - name: read-object
  49. type: read-object
  50. outputs:
  51. - name: ready
  52. valueFrom: output.value.status["ready"]
  53. properties:
  54. apiVersion: batch/v1
  55. kind: Job
  56. name: mytask
  57. namespace: default
  58. cluster: local
  59. - type: deploy
  60. name: deploy-02
  61. inputs:
  62. - from: ready
  63. if: inputs["ready"] == 0
  64. properties:
  65. policies: ["target-prod", "override-annotations-2"]

KubeVela 的 v1.3 应用相较于之前的版本使用了不同的策略和工作流步骤来分发、管理多集群应用。

旧版本中的 env-binding 策略以及 deploy2env 工作流步骤在目前版本中仍保留并兼容,但可能会在未来的版本中逐步废弃。

新的策略和工作流步骤可以完全覆盖旧版本中多集群应用的所有使用场景,而且提供了更强的能力。自动化升级工具将会在废弃旧版本之前提供给用户。

如果你已经在生产环境中使用了旧版本的多集群应用,并且不希望改变他们,KubeVela v1.3 可以完全兼容它们,而不需要对应用进行升级。

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