kubevela.github.io/i18n/zh/docusaurus-plugin-content-docs/current/tutorials/k8s-object.mdx

302 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Kubernetes 原生资源
description: 对 Kubernetes 有一定了解的用户,参考本文档学习利用 KubeVela 的能力将已经定义好的 Kubernetes 资源便捷交付到多个集群。
---
本文介绍了如何使用 KubeVela 将你定义的 Kubernetes 资源交付到多个目标环境和集群。
KubeVela 支持面向应用组织多个 Kubernetes 资源进行交付,常见的用例是 Deployment+Service。我们支持将其通过自定义工作流有序的在多个集群进行交付因此在本例中你将学习到以下能力
1. 交付 Kubernetes 原生资源。
2. 初步了解工作流使用方法和场景。
3. 初步了解多环境/多集群的应用发布。
4. 应用发布过程控制:回退、终止和继续。
不仅如此,你还可以使用 KubeVela 引用已有的 Kubernetes 对象并将它们分发到其他位置来完成以下场景:
- 将管控集群中的密钥复制到子集群中。
- 将验证集群中的工作负载部署到生产集群中。
- 使用 Kubernetes 原生的 apiserver 作为控制面,将所有的 Kubernetes 对象存储在外部数据库中。然后通过引用这些资源,将它们下发到真正运行负载的子集群中。
## 开始之前
- 准备一个 Deployment+Service 资源的 Yaml 定义文件,请注意,涉及多个资源时请将 Deployment、Statefulset、Job 等工作负载类资源置于第一个。如果多个工作负载类资源,请拆分为多个应用。
<!-- - 准备两个或更多的运行时集群, 参考: [管理运行时集群](./manage-cluster) TODO v1.2-->
## 规划并创建交付目标
[交付目标(Target)](../getting-started/core-concept#交付目标target) 定义了应用交付的运行时集群和命名空间,创建交付目标的同时完成运行时集群的命名空间创建。
点击 `New Target` 按钮进入创建流程,填写必要的信息,选择集群、命名空间即可完成创建。我们使用 2 个集群来创建交付目标,当然如果你暂无多个集群,也可以使用一个集群的多个命名空间来创建多个交付目标。我们最少准备 3 个交付目标1 个用于测试环境2 个或更多用于生产环境。
## 创建 Kubernetes 应用
完成交付目标创建后,我们开始创建应用。与 [交付第一个应用](../quick-start) 一样,首先我们需要填写应用的基础信息,这里有三个不同点:
1选择部署类型 k8s-objects; 该类型用于部署多个 Kubernetes 原生资源,请注意,同一个应用请尽量保持只有一个 Workload 资源,即不要出现多个 Deployment 或者 Statefulset。
2环境规划时我们分配两个环境测试环境和生产环境其中开发环境选择 1 个准备的开发用交付目标, 生产环境选择多个交付目标。
![](../resources/create-k8s-app.jpg)
3设置部署参数直接上传准备好的 Yaml 文件即可。需要注意的是,资源的名称如果在配置中指定,即使用配置的名称,你需要确定其与已存在的资源不冲突,如果不指定,则使用 KubeVela 资源命名规则自动命名。编辑器会自动将输入的内容进行格式化。
![](../resources/config-k8s-app.jpg)
设置完成后点击 `Create` 即可完成应用创建。
## 部署测试环境
![](../resources/app-dashboard.jpg)
进入应用管理页面,你会发现改应用自动生成了 2 个环境2 个工作流。Vela 会自动为每一个环境生成默认的工作流,工作流由`deploy2env`类型的步骤组成,每一个交付目标对于一个步骤,表示将应用交付到该交付目标。
我们首先切换到测试环境 Tab 页面下,点击页面中的 Deploy 按钮进行该环境的部署。由于测试环境我们只分配了一个交付目标,默认情况下工作流步骤只有一步。观察页面右上方的工作流执行状态,其变更为绿色后即已执行完成。如果其为红色,即工作流执行遇到故障,我们将鼠标移动到步骤上方即可查询失败原因,处理异常后工作量会继续重拾,如果故障解决其可完成部署。
部署完成后,刷新实例列表即可查看到 Pod 列表,如果 Pod 运行异常可以点击行查看 Pod 详情信息。
![](../resources/pod-list.jpg)
对于测试环境,它当然应该持续进行迭代,当我们变更了部署参数(镜像版本,实例数等),只需要重新执行测试环境的 Workflow 即可升级部署,鼠标移动到页面右上方,选择测试环境的 流水线 执行即可。若点击旁边的 Deploy 按钮,其含义是执行默认的流水线。
![](../resources/select-workflow.jpg)
## 部署生产环境
当我们在测试环境多次部署完成业务的测试工作以后,我们要开始将应用发布到生产环境,我们切换到生产环境 Tab 下会发现当前环境处于未部署状态。是的同一个应用的不同环境是完全隔离管理的它的背后是生成独立的应用部署实例Application CR
由于我们生产环境有多个交付目标,它默认情况下是根据先后顺序依次部署,这时如果假设大家希望在部署完第一个交付目标后,希望人工审核/校验一下部署状态后再执行后续部署。带着这个需求,我们需要进入到应用基准配置的工作流管理页面。
![](../resources/app-workflow.jpg)
我们可以看到已经自动生成的两条流水线配置,这时我们点击生产环境流水线的 `Edit` 进入编辑模式,从左侧的工作流步骤的选项中选择 `suspend`, 将其拖入右侧画板中。便捷弹窗将自动出现,该类型没有更多的配置参数,你可以设置别名或直接保存即可。
添加完成后我们需要编排它的顺序,首先断开已有步骤之间的连线(通过点击连线+delete 键),然后将 suspend 步骤连线在中间即可。编辑完成后需要点击右上方的 Save 按钮即可保存并生效。
![](../resources/workflow-edit.jpg)
工作流编辑完成后回到生产环境页面下,点击 Deploy 按钮,即可开始生产环境的部署。
![](../resources/workflow-suspend.jpg)
观察右上方的工作流执行状态,当第一个交付目标完成部署后,即会停止在第二个步骤等待用户进行审核操作,我们从下方的实例列表也可以查看到第一个交付目标的实例已经生成并处于运行状态。
暂停步骤有三个操作可以进行:
- Rollback: 版本回退,即将采用历史最新的完成部署的版本进行重新部署,当前版本部署工作流终止。
- Terminate: 终止,即停止当前版本的部署,但不会改变已经部署的交付目标。
- Continue: 继续执行,进入下一个步骤的执行。
当你选择继续执行后,第二个或更多的交付目标即可完成部署。从实例列表中你可以查看到多个交付目标的实例,可以通过选择交付目标进行实例筛选查询。
![](../resources/multiple-target-pods.jpg)
## 通过 CLI 交付
通过 CLI 部署的应用没有环境的概念,你可以通过部署多个应用来实现与控制台中类似的环境隔离。
这是一个部署 Kubernetes 原生资源的示例应用,我们知道大多数 Kubernetes 应用都由 Deployment 和 Service 组成。该应用配置中包括了 2 个部署策略和 3 个工作流步骤,这些配置的表达的含义是部署应用到两个命名空间且在第一个完成部署后需要人工审核。
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-with-k8s-objects
namespace: default
spec:
components:
- name: k8s-demo-service
properties:
objects:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
type: Recreate
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
- apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
labels:
app: nginx
name: nginx
namespace: default
spec:
externalTrafficPolicy: Local
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
type: k8s-objects
policies:
- name: topology-default
type: topology
properties:
clusters: ['local']
namespace: default
- name: topology-production
type: topology
properties:
clusters: ['local']
namespace: production
workflow:
steps:
- name: deploy2default
properties:
policies: ['topology-default']
type: deploy
- name: suspend
type: suspend
- name: deploy2production
properties:
policies: ['topology-production']
type: deploy
```
- 关于 Topology 策略参考: [Topology](../end-user/policies/references#override)
- 关于 Deploy 步骤参考: [Deploy](../end-user/workflow/built-in-workflow-defs#deploy)
通过下述命令来部署该应用:
- 在部署之前创建所需的命名空间 `production`
```shell
$ vela up -f https://kubevela.io/example/applications/create-namespace.yaml
```
- 部署该应用
```shell
$ vela up -f https://kubevela.io/example/applications/app-with-k8s-objects.yaml
```
- 查询应用状态进入暂停状态后执行审核命令:
```shell
$ vela workflow resume app-with-k8s-objects
```
## 分发引用的外部 Kubernetes 对象
> 开始这部分之前需要你先了解使用 CLI 如何进行多集群应用的部署。你可以参考 [多集群应用交付](../case-studies/multi-cluster) 章节.
## 在组件中引用已有的 Kubernetes 对象
为了在组件中使用已有的 Kubernetes 对象,你需要使用 `ref-objects` 类型的组件,并在参数中声明你想要引用的资源。例如,在下面的例子中,命名空间 `examples` 中的密钥 `image-credential-to-copy` 会被作为组件的源数据,然后你可以使用 Topology 策略来将它复制分发到杭州集群中。
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: ref-objects-example
namespace: examples
spec:
components:
- name: image-pull-secrets
type: ref-objects
properties:
objects:
- resource: secret
name: image-credential-to-copy
policies:
- name: topology-hangzhou-clusters
type: topology
properties:
clusterLabelSelector:
region: hangzhou
```
## *ref-objects* 类型组件的细节
声明需要引用资源最直接的方法是使用 `resource: secret` 或 `resource: deployment` 这样的方式来确定引用资源的类型。如果 `name` 和 `labelSelector` 都没有被设置,那么应用将会在它的命名空间下尝试寻找与和组件名称一致的资源。你也可以显式地指定 `name` 和 `namespace` 来确定需要引用的资源。
除了 `name` 和 `namespace`,你还可以使用 `cluster` 字段让应用组件去引用子集群中的资源。你也可以使用 `labelSelector` 来筛选资源,而不是直接用 `name` 去确定目标资源。
在下面的样例中,应用会选择在 *hangzhou-1* 集群的 *examples* 命名空间中,所有符合声明标签要求的 Deployment。然后应用会将这些 Deployments 复制到 *hangzhou-2* 集群中。
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: ref-objects-duplicate-deployments
namespace: examples
spec:
components:
- name: duplicate-deployment
type: ref-objects
properties:
objects:
- resource: deployment
cluster: hangzhou-1
# select all deployment in the `examples` namespace in cluster `hangzhou-1` that matches the labelSelector
labelSelector:
need-duplicate: "true"
policies:
- name: topology-hangzhou-2
type: topology
properties:
clusters: ["hangzhou-2"]
```
> 在一些场景下,你可能想要限制应用能够引用资源的范围,你可以通过在 KubeVela 控制器中设置 `--ref-objects-available-scope` 为 `namespace` 或者 `cluster` 来限制只在同命名空间或者同一集群内引用资源。
## 在 ref-objects 类型组件内使用运维特征
*ref-objects* 类型的组件同样也可以使用运维特征。其主体工作负载会被隐式地设置为引用资源列表中的第一个资源。所有作用在工作负载上的运维特征都会指向该资源。 如下所示的例子展示了如何为引用的 Deployment 设置副本数,并下发到 hangzhou 集群中。
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: ref-objects-multiple-resources
namespace: examples
spec:
components:
- name: nginx-ref-multiple-resources
type: ref-objects
properties:
objects:
- resource: deployment
- resource: service
traits:
- type: scaler
properties:
replicas: 3
policies:
- name: topology-hangzhou-clusters
type: topology
properties:
clusterLabelSelector:
region: hangzhou
```
到此你已经完成了交付 Kubernetes 原生资源的学习!
## 下一步
- [交付云厂商服务](./consume-cloud-services)
- [分发已存在的 Kubernetes 对象](../end-user/components/ref-objects)