组件部署
ComponentPlan 会安装一个组件到集群,类似执行一次 helm install/upgrade 操作,只不过将 helm install/upgrade 命令中的参数固化到 ComponentPlan 的 spec
字段中,将涉及到的 docker 镜像以及安装后集群对象和现有对象的 diff 显示在 status 字段中,并且可以设置失败后自动重试的次数。
使用
下面是一个 ComponentPlan 示例:
apiVersion: core.kubebb.k8s.com.cn/v1alpha1
kind: ComponentPlan
metadata:
# labels:
# core.kubebb.k8s.com.cn/componentplan-release: nginx
name: nginx-15.0.2
namespace: kubebb-system
spec:
approved: true
component:
name: repository-bitnami-sample.nginx
namespace: kubebb-system
name: my-nginx
override:
images:
- name: docker.io/bitnami/nginx
newTag: latest # the default image is docker.io/bitnami/nginx:1.25.1-debian-11-r0, will be replaced by docker.io/bitnami/nginx:latest
version: 15.0.2
#status:
# conditions:
# - lastTransitionTime: "2023-06-21T03:44:31Z"
# reason: ""
# status: "True"
# type: Approved
# - lastTransitionTime: "2023-06-21T03:44:37Z"
# reason: ""
# status: "True"
# type: Installed
# - lastTransitionTime: "2023-06-21T03:44:37Z"
# reason: ""
# status: "True"
# type: Succeeded
# images:
# - docker.io/bitnami/nginx:latest
# installedRevision: 3
# latest: true
# observedGeneration: 5
# resources:
# - NewCreated: true
# apiVersion: v1
# kind: Service
# name: my-nginx
# - NewCreated: true
# apiVersion: apps/v1
# kind: Deployment
# name: my-nginx
上述 ComponentPlan 定义了安装的组件是 kubebb-system 命名空间的 repository-bitnami-sample.nginx。
安装名为 my-nginx,安装版本为 15.0.2。
同时在安装时,将镜像 docker.io/bitnami/nginx 的 tag 替换为 latest。
通过 status 字段可以看到,当前组件涉及的镜像以及资源。其中资源会标明是新创建还是更新现有资源,一个更新现有资源的例子为:
- apiVersion: v1
kind: Service
name: my-wordpress
specDiffwithExist: no spec diff, but some field like resourceVersion will update
- apiVersion: apps/v1
kind: Deployment
name: my-wordpress
specDiffwithExist: |
metadata:
annotations: map[deployment.kubernetes.io/revision:2] -> <empty> (REMOVED)
spec:
replicas: 3 -> 1
template:
spec:
containers:
'[#0]':
image: docker.io/bitnami/wordpress:6.2.2-debian-11-r9 -> docker.io/bitnami/wordpress:6.2.2-debian-11-r11
resources:
requests:
cpu: 400m -> 300m
memory: 1Gi -> 512Mi
CRD 定义说明
CRD 的代码定义位于 componentplan_types.go。接下来会详细介绍每个字段的含义及其作用。
说明:对于下面的 yaml,我们想要访问 bar 字段,书写格式为 spec.foo.bar
spec:
foo:
bar: xx
配置说明
ComponentPlan 的可选配置匹配了 helm install / upgrade / uninstall 的可选参数,有一些参数 ComponentPlan 并不支持:
--create-namespace参数不支持,helm release 会创建在 ComponentPlan 的同名 namespace 中。--dry-run参数不支持,不需要模拟,模拟运行的结果会出现在 ComponentPlan 的 status 字段中。--replace参数不支持,helm 标记该参数不应该用于生产环境。--render-subchart-notes参数不支持,我们不展示 notes 信息。--devel参数不支持,如果需要使用devel版本,spec.version字段指定>0.0.0-0即可。--nameTemplate和--generateName参数不支持,因为这两个字段在多次运行过程中可能会生成不确定的结果,我们使用spec.name来生成固定的名称。--reset-values和--reuse-values参数不支持,我们使用spec.override.values和spec.override.valuesFrom来重写配置。- 其他认证参数比如
--username,需要在 Repository 中指定。
其他配置为:
spec.componet该字段用来指明要监控的组件实例,一般使用
namespace和name来唯一确定spec.version需要安装的组件版本。
spec.approved是否同意安装。
bool类型,true或false,当为true时,自动触发安装流程。为false时,只会解析这个组件的manifest,并填充status字段,方便用户判断这次安装会对集群中现有资源带来的影响。spec.name组件安装到集群中的名称。类似
helm release的名称spec.force可选字段布尔值,更新时通过替换策略强制更新资源, 类似
helm upgrade --force参数,默认为falsespec.timeoutSeconds可选字段整数值,创建/更新/删除时的超时时间,单位为秒,默认为
300,即 5 分钟。类似helm install/upgrade --timeout参数spec.wait可选字段布尔值,如果设置为
true,将等待所有的 Pod、PVC、Service 和 Deployment、StatefulSet 或 ReplicaSet 的最小数量的 Pod 处于就绪状态才认为安装/更新成功。等待的时间即为spec.timeoutSeconds的值,默认为false,类似helm install/upgrade --wait参数。spec.waitForJobs可选字段布尔值,如果设置为
true,将等待所有的 Job 完成才认为安装/更新成功。等待的时间即为spec.timeoutSeconds的值,默认为false,类似helm install/upgrade --wait-for-jobs参数。spec.description可选字段给安装/更新添加一个自定义描述。默认为空,类似
helm install/upgrade --description参数。spec.dependencyUpdate可选字段布尔值,在安装/更新组件前,是否更新缺少的依赖项。类似
helm install/upgrade --dependency-update参数,默认为falsespec.disableHooks可选字段布尔值,如果设置为
true,则阻止 Hook 在安装过程中运行,并禁用升级前/后 Hook,类似helm install/upgrade --no-hooks参数,默认为falsespec.disableOpenAPIValidation可选字段布尔值,如果设置为
true,安装过程将不会根据 Kubernetes OpenAPI Schema 验证渲染的模板。类似helm install/upgrade --disable-openapi-validation参数,默认为falsespec.atomic可选字段布尔值,如果设置为
true,安装/更新过程会在安装/更新失败时删除安装。如果spec.atomic设置为true,将自动设置spec.wait为true。类似helm install/upgrade --atomic参数,默认为falsespec.skipCRDs可选字段布尔值,如果设置为
true,则跳过 CRD 的安装。默认情况下,如果尚未安装 CRD,会自动安装。类似helm install/upgrade --skip-crds参数,默认为falsespec.enableDNS可选字段布尔值,在渲染模板时是否启用 DNS 查询,类似
helm install/upgrade --enable-dns参数 默认为falsespec.historyMax可选字段整数值,限制每个 release 保存的最大 revisions 数目。使用
0表示无限制,默认为10spec.maxRetry可选字段整数值,创建/更新最大重试次数,默认为
5spec.cleanupOnFail可选字段布尔值,当升级失败时,允许删除在此升级中创建的新资源,类似
helm upgrade --cleanup-on-fail参数,默认为false。spec.keepHistory可选字段布尔值,卸载时,删除所有相关资源,并将发布标记为已删除,但保留发布历史。类似
helm uninstall --keep-history参数,默认为false。spec.override可选字段用于覆盖原组件配置的字段。
spec.override.valuesJSON格式的values,用于覆盖默认值spec.override.valuesFrom字段为数组。当要设定的字段偏多时,我们一般希望把
values.yaml单独拿出来,放在ConfigMap或者Secret中,而且我们可能会有很多values.yaml文件。具体格式为:spec.override.valuesFrom[].kind可选项为
Secret或ConfigMapspec.override.valuesFrom[].nameSecret或ConfigMap的名称,不需要namespace字段,因为只会查找和当前 ComponentPlan 同namespace的资源。spec.override.valuesFrom[].valuesKeySecret或ConfigMap的data中的key,默认为values.yaml会尝试先后查询ConfigMap中的Data和BinaryData字段,Secret中的StringData和Data字段。
spec.override.set数组,类似
helm template --set的参数spec.override.set-string数组,类似
helm template --set-string的参数spec.override.images数组。类似
kustomize的镜像自定义参数spec.override.images[].name原始镜像名称,
tag可选,如果包含tag,则匹配精确到tag一致才替换,比如,如果该项为docker.io/bitnami/nginx:v1,那么只匹配 tag 为v1的 nginx 镜像,如果有docker.io/bitnami/nginx:v2不会被替换。spec.override.images[].newName替代原始镜像名称的名称
spec.override.images[].newTag替代原始
tag的新tag名称spec.override.images[].digest替代原始
tag的新digest,如果digest有值,会忽略newTag的值。
状态描述
一个典型的 ComponentPlan 状态示例如下:
status:
conditions:
- lastTransitionTime: "2023-07-25T12:22:12Z"
reason: ""
status: "True"
type: Approved
- lastTransitionTime: "2023-07-25T12:25:00Z"
message: timed out waiting for the condition
reason: UpgradeFailed
status: "False"
type: Actioned
- lastTransitionTime: "2023-07-25T12:25:00Z"
reason: ""
status: "False"
type: Succeeded
images:
- docker.io/bitnami/nginx:xxxxx
installedRevision: 4
latest: true
observedGeneration: 1
resources:
- NewCreated: true
apiVersion: v1
kind: Service
name: my-nginx
- NewCreated: true
apiVersion: apps/v1
kind: Deployment
name: my-nginx
status.conditions数组,ComponentPlan 的状态
status.conditions[].lastTransitionTime上次从一种状态转换到另一种状态时的时间戳
status.conditions[].reason机器可读的、驼峰编码(UpperCamelCase)的文字,表述上次状况变化的原因
status.conditions[].message人类可读的消息,给出上次状态转换的详细信息
status.conditions[].status表明该状况是否适用,可能的取值有
True"、False或Unknownstatus.conditions[].type状况的名称
可能包含以下状态:
Approved用户已经同意该组件安装计划(ComponentPlan)的安装
Actioned某个操作已经完成
Succeeded用户期待的操作已经全部完成
status.images该 ComponentPlan 会引入的镜像列表
status.installedRevision该 ComponentPlan 安装的 helm release revision 版本。
status.latesthelm release 的最新版本是否是该 ComponentPlan 安装的。支持多个 ComponentPlan 按部署时间安装/升级同一个 helm release。
status.observedGeneration用于程序内部处理。表示该 ComponentPlan 基于的
.metadata.generation的过期次数。 例如,如果.metadata.generation当前为 12,但.status.observedGeneration为 9, 则相对于实例的当前状态已过期。status.resources数组,ComponentPlan 涉及的资源
status.resources[].specDiffwithExist展示该资源的 manifest 在该 ComponentPlan 应用前后的对比
status.resources[].NewCreated布尔值,该资源是否是新创建的
status.resources[].kind该资源的类型
status.resources[].name该资源的名称
status.resources[].apiVersion该资源的 apiVersion 信息
工作原理
组件安装以 Kubernetes Operator 方式实现, 底层通过调用 Helm Go SDK 实现组件安装、升级和卸载。
在运行时,通过监测集群中是否有同名 helm release 来智能使用 helm install 或者 helm upgrade 相关函数进行安装或升级。
安装或升级时,会将 ComponentPlan 中的配置传递给相关函数,功能和 helm install 或者 helm upgrade 基本一致。
当删除 ComponentPlan 时,判断当前集群中的同名的 helm release 的最新版本是否由待删除的 ComponentPlan 安装,如果是,则同时调用 helm uninstall 相关函数删除该 helm release。
一些细节:
- 创建 ComponentPlan 后,operator 会尝试自动解析该 ComponentPlan 中引入的 helm release 会对集群中现有资源的影响,结果会展示在 ComponentPlan 的 status
字段中,类似于先进行
helm install/upgrade --dry-run后,将生成的 manifest 再进行kubectl diff操作, - 只有 ComponentPlan 中的
spec.approved为true,对应的helm release才会真正安装。 - 单个 ComponentPlan 的镜像替换 (即
spec.override.images字段)的规则遵循 kustomize:ImageTagTransformer 规范,代码实现也是直接调用了 kustomize 的这部分代码,降低了用户学习成本,保证了代码的兼容性和有效性。 - 单个 ComponentPlan 的镜像替换和整个 Repository 的镜像替换,都是通过 Helm:post-rendering 技术实现的。
镜像覆盖策略

ComponentPlan 和 Helm release 的关系
