版本:v1.3

Kubernetes 原生资源

本文介绍了如何使用 KubeVela 将你定义的 Kubernetes 资源交付到多个目标环境和集群。

KubeVela 支持面向应用组织多个 Kubernetes 资源进行交付,常见的用例是 Deployment+Service。我们支持将其通过自定义工作流有序的在多个集群进行交付,因此在本例中你将学习到以下能力:

  1. 交付 Kubernetes 原生资源。
  2. 初步了解工作流使用方法和场景。
  3. 初步了解多环境/多集群的应用发布。
  4. 应用发布过程控制:回退、终止和继续。

不仅如此,你还可以使用 KubeVela 引用已有的 Kubernetes 对象并将它们分发到其他位置来完成以下场景:

  • 将管控集群中的密钥复制到子集群中。
  • 将验证集群中的工作负载部署到生产集群中。
  • 使用 Kubernetes 原生的 apiserver 作为控制面,将所有的 Kubernetes 对象存储在外部数据库中。然后通过引用这些资源,将它们下发到真正运行负载的子集群中。

  • 准备一个 Deployment+Service 资源的 Yaml 定义文件,请注意,涉及多个资源时请将 Deployment、Statefulset、Job 等工作负载类资源置于第一个。如果多个工作负载类资源,请拆分为多个应用。

交付目标(Target) 定义了应用交付的运行时集群和命名空间,创建交付目标的同时完成运行时集群的命名空间创建。

点击 New Target 按钮进入创建流程,填写必要的信息,选择集群、命名空间即可完成创建。我们使用 2 个集群来创建交付目标,当然如果你暂无多个集群,也可以使用一个集群的多个命名空间来创建多个交付目标。我们最少准备 3 个交付目标,1 个用于测试环境,2 个或更多用于生产环境。

完成交付目标创建后,我们开始创建应用。与 交付第一个应用 一样,首先我们需要填写应用的基础信息,这里有三个不同点:

(1)选择部署类型 k8s-objects; 该类型用于部署多个 Kubernetes 原生资源,请注意,同一个应用请尽量保持只有一个 Workload 资源,即不要出现多个 Deployment 或者 Statefulset。

(2)环境规划时我们分配两个环境,测试环境和生产环境,其中开发环境选择 1 个准备的开发用交付目标, 生产环境选择多个交付目标。

Kubernetes 原生资源 - 图1

(3)设置部署参数,直接上传准备好的 Yaml 文件即可。需要注意的是,资源的名称如果在配置中指定,即使用配置的名称,你需要确定其与已存在的资源不冲突,如果不指定,则使用 KubeVela 资源命名规则自动命名。编辑器会自动将输入的内容进行格式化。

Kubernetes 原生资源 - 图2

设置完成后点击 Create 即可完成应用创建。

Kubernetes 原生资源 - 图3

进入应用管理页面,你会发现改应用自动生成了 2 个环境,2 个工作流。Vela 会自动为每一个环境生成默认的工作流,工作流由deploy2env类型的步骤组成,每一个交付目标对于一个步骤,表示将应用交付到该交付目标。

我们首先切换到测试环境 Tab 页面下,点击页面中的 Deploy 按钮进行该环境的部署。由于测试环境我们只分配了一个交付目标,默认情况下工作流步骤只有一步。观察页面右上方的工作流执行状态,其变更为绿色后即已执行完成。如果其为红色,即工作流执行遇到故障,我们将鼠标移动到步骤上方即可查询失败原因,处理异常后工作量会继续重拾,如果故障解决其可完成部署。

部署完成后,刷新实例列表即可查看到 Pod 列表,如果 Pod 运行异常可以点击行查看 Pod 详情信息。

Kubernetes 原生资源 - 图4

对于测试环境,它当然应该持续进行迭代,当我们变更了部署参数(镜像版本,实例数等),只需要重新执行测试环境的 Workflow 即可升级部署,鼠标移动到页面右上方,选择测试环境的 流水线 执行即可。若点击旁边的 Deploy 按钮,其含义是执行默认的流水线。

Kubernetes 原生资源 - 图5

当我们在测试环境多次部署完成业务的测试工作以后,我们要开始将应用发布到生产环境,我们切换到生产环境 Tab 下,会发现当前环境处于未部署状态。是的,同一个应用的不同环境是完全隔离管理的,它的背后是生成独立的应用部署实例(Application CR)。

由于我们生产环境有多个交付目标,它默认情况下是根据先后顺序依次部署,这时如果假设大家希望在部署完第一个交付目标后,希望人工审核/校验一下部署状态后再执行后续部署。带着这个需求,我们需要进入到应用基准配置的工作流管理页面。

Kubernetes 原生资源 - 图6

我们可以看到已经自动生成的两条流水线配置,这时我们点击生产环境流水线的 Edit 进入编辑模式,从左侧的工作流步骤的选项中选择 suspend, 将其拖入右侧画板中。便捷弹窗将自动出现,该类型没有更多的配置参数,你可以设置别名或直接保存即可。

添加完成后我们需要编排它的顺序,首先断开已有步骤之间的连线(通过点击连线+delete 键),然后将 suspend 步骤连线在中间即可。编辑完成后需要点击右上方的 Save 按钮即可保存并生效。

Kubernetes 原生资源 - 图7

工作流编辑完成后回到生产环境页面下,点击 Deploy 按钮,即可开始生产环境的部署。

Kubernetes 原生资源 - 图8

观察右上方的工作流执行状态,当第一个交付目标完成部署后,即会停止在第二个步骤等待用户进行审核操作,我们从下方的实例列表也可以查看到第一个交付目标的实例已经生成并处于运行状态。

暂停步骤有三个操作可以进行:

  • Rollback: 版本回退,即将采用历史最新的完成部署的版本进行重新部署,当前版本部署工作流终止。
  • Terminate: 终止,即停止当前版本的部署,但不会改变已经部署的交付目标。
  • Continue: 继续执行,进入下一个步骤的执行。

当你选择继续执行后,第二个或更多的交付目标即可完成部署。从实例列表中你可以查看到多个交付目标的实例,可以通过选择交付目标进行实例筛选查询。

Kubernetes 原生资源 - 图9

通过 CLI 部署的应用没有环境的概念,你可以通过部署多个应用来实现与控制台中类似的环境隔离。

这是一个部署 Kubernetes 原生资源的示例应用,我们知道大多数 Kubernetes 应用都由 Deployment 和 Service 组成。该应用配置中包括了 2 个部署策略和 3 个工作流步骤,这些配置的表达的含义是部署应用到两个命名空间且在第一个完成部署后需要人工审核。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: app-with-k8s-objects
  5. namespace: default
  6. spec:
  7. components:
  8. - name: k8s-demo-service
  9. properties:
  10. objects:
  11. - apiVersion: apps/v1
  12. kind: Deployment
  13. metadata:
  14. name: nginx
  15. spec:
  16. replicas: 2
  17. selector:
  18. matchLabels:
  19. app: nginx
  20. strategy:
  21. type: Recreate
  22. template:
  23. metadata:
  24. labels:
  25. app: nginx
  26. spec:
  27. containers:
  28. - image: nginx
  29. name: nginx
  30. ports:
  31. - containerPort: 80
  32. - apiVersion: v1
  33. kind: Service
  34. metadata:
  35. annotations:
  36. service.beta.kubernetes.io/aws-load-balancer-type: nlb
  37. labels:
  38. app: nginx
  39. name: nginx
  40. namespace: default
  41. spec:
  42. externalTrafficPolicy: Local
  43. ports:
  44. - name: http
  45. port: 80
  46. protocol: TCP
  47. targetPort: 80
  48. selector:
  49. app: nginx
  50. type: LoadBalancer
  51. type: k8s-objects
  52. policies:
  53. - name: topology-default
  54. type: topology
  55. properties:
  56. clusters: ['local']
  57. namespace: default
  58. - name: topology-production
  59. type: topology
  60. properties:
  61. clusters: ['local']
  62. namespace: production
  63. workflow:
  64. steps:
  65. - name: deploy2default
  66. properties:
  67. policies: ['topology-default']
  68. type: deploy
  69. - name: suspend
  70. type: suspend
  71. - name: deploy2production
  72. properties:
  73. policies: ['topology-production']
  74. type: deploy
  • 关于 Topology 策略参考: Topology
  • 关于 Deploy 步骤参考: Deploy

通过下述命令来部署该应用:

  • 在部署之前创建所需的命名空间 production
  1. $ vela up -f https://kubevela.io/example/applications/create-namespace.yaml
  • 部署该应用
  1. $ vela up -f https://kubevela.io/example/applications/app-with-k8s-objects.yaml
  • 查询应用状态进入暂停状态后执行审核命令:
  1. $ vela workflow resume app-with-k8s-objects

开始这部分之前需要你先了解使用 CLI 如何进行多集群应用的部署。你可以参考 多集群应用交付 章节.

为了在组件中使用已有的 Kubernetes 对象,你需要使用 ref-objects 类型的组件,并在参数中声明你想要引用的资源。例如,在下面的例子中,命名空间 examples 中的密钥 image-credential-to-copy 会被作为组件的源数据,然后你可以使用 Topology 策略来将它复制分发到杭州集群中。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: ref-objects-example
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: image-pull-secrets
  9. type: ref-objects
  10. properties:
  11. objects:
  12. - resource: secret
  13. name: image-credential-to-copy
  14. policies:
  15. - name: topology-hangzhou-clusters
  16. type: topology
  17. properties:
  18. clusterLabelSelector:
  19. region: hangzhou

声明需要引用资源最直接的方法是使用 resource: secretresource: deployment 这样的方式来确定引用资源的类型。如果 namelabelSelector 都没有被设置,那么应用将会在它的命名空间下尝试寻找与和组件名称一致的资源。你也可以显式地指定 namenamespace 来确定需要引用的资源。

除了 namenamespace,你还可以使用 cluster 字段让应用组件去引用子集群中的资源。你也可以使用 labelSelector 来筛选资源,而不是直接用 name 去确定目标资源。

在下面的样例中,应用会选择在 hangzhou-1 集群的 examples 命名空间中,所有符合声明标签要求的 Deployment。然后应用会将这些 Deployments 复制到 hangzhou-2 集群中。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: ref-objects-duplicate-deployments
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: duplicate-deployment
  9. type: ref-objects
  10. properties:
  11. objects:
  12. - resource: deployment
  13. cluster: hangzhou-1
  14. # select all deployment in the `examples` namespace in cluster `hangzhou-1` that matches the labelSelector
  15. labelSelector:
  16. need-duplicate: "true"
  17. policies:
  18. - name: topology-hangzhou-2
  19. type: topology
  20. properties:
  21. clusters: ["hangzhou-2"]

在一些场景下,你可能想要限制应用能够引用资源的范围,你可以通过在 KubeVela 控制器中设置 --ref-objects-available-scopenamespace 或者 cluster 来限制只在同命名空间或者同一集群内引用资源。

ref-objects 类型的组件同样也可以使用运维特征。其主体工作负载会被隐式地设置为引用资源列表中的第一个资源。所有作用在工作负载上的运维特征都会指向该资源。 如下所示的例子展示了如何为引用的 Deployment 设置副本数,并下发到 hangzhou 集群中。

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: ref-objects-multiple-resources
  5. namespace: examples
  6. spec:
  7. components:
  8. - name: nginx-ref-multiple-resources
  9. type: ref-objects
  10. properties:
  11. objects:
  12. - resource: deployment
  13. - resource: service
  14. traits:
  15. - type: scaler
  16. properties:
  17. replicas: 3
  18. policies:
  19. - name: topology-hangzhou-clusters
  20. type: topology
  21. properties:
  22. clusterLabelSelector:
  23. region: hangzhou

到此你已经完成了交付 Kubernetes 原生资源的学习!

Last updated on 2022年11月1日 by Tianxin Dong