Kubernetes 新玩法:在 yaml 中编程( 二 )
通过在 yaml 中表达想法 , 编排对 K8s 资源的操作、监控 , 再也不用为性能测试的实现头疼了 :D
为什么要在 yaml 中编程?
性能测试、回归测试等对于服务质量保障有很大帮助 , 需要做 , 但常规的实现方法在初期需要投入较多的时间和精力 , 新增变更后维护成本比较高 。
通常这个过程是以代码的方式实现原子操作 , 如创建 Deployment、检测 Pod 配置等 , 然后再组合原子操作来满足需求 , 如 创建 Deployment -> 等待 Deployment ready -> 检测 Pod 配置等 。
有没有办法在实现的过程中既可以尽量低成本实现 , 又可以复用已有的经验?
可以将原子操作封装为原语 , 如 CreateDeployment、CheckPod , 再通过 yaml 的结构表达流程 , 那么就可以通过 yaml 而非代码的方式描述想法 , 又可以复用他人已经写好的 yaml 文件来解决某类场景的需求 。
即在 yaml 中编程 , 减少重复性代码工作 , 通过声明式 的方式描述逻辑 , 并以 yaml 文件来满足场景级别的复用 。
业界有很多种类型的声明式操作 服务 , 如运维领域中的 Ansible、SaltStack , Kubernetes 中的Argo Workflow、clusterloader2 。 它们的思想整体比较类似 , 将高频使用的操作封装为原语 , 使用者通过原语来表述操作逻辑 。
通过声明式的方法 , 将面向 K8s 的操作抽象成 yaml 中的关键词 , 在 yaml 中提供串行、并行等控制逻辑 , 那么就可以通过 yaml 文件完整描述想要进行的工作 。
这种思想和 Argo Workflow 比较像 , 但粒度比 Argo 更细 , 关注在操作函数上:
本文插图
下面简单描述该服务的设计和实现 。
设计和实现
1. 服务形态
- 使用者在 yaml 中 , 通过声明式 的方式描述操作逻辑;
- 以 all-in-one 的二进制工具或 Operator 的方式交付;
- 服务内置常见原语的实现 , 以关键字的方式在 yaml 中提供;
- 支持配置原生 K8s 资源 。
该方案的核心在于配置管理的设计 , 将操作流程配置化 , 自上而下有如下概念:
- Service:Modules 或 Tasks 的编排;
- Module:一种任务场景 , 是操作单元的集合(其中包含 templates/ 目录 , 表征模板文件的集合 , 可用来配置 K8s 原生资源);
- Task:操作单元 , 使用 plugin 及参数执行操作;
- Plugin:操作指令 , 类似开发语言中的函数 。
- K8s 相关CreateNamespaceDeleteNamespacePrepareSecretPrepareConfigMapPrepareBatchDeploymentsWaitForBatchDeploymentsReadyetc.
- 观测性相关DeploymentCreationEfficiencyPodCreationEfficiencyetc.
- 检测项相关CheckPodAnnotationsCheckPodObjectInfoCheckPodInnerStatesetc.
- 控制语句相关RepeatNTimesetc.
本文插图
示例可参见文章开头的 yaml 文件 , 对应形式二 。
3. 核心实现
CRD 设计:
package v1alpha1 import ( corev1 ''k8s.io/api/core/v1'' metav1 ''k8s.io/apimachinery/pkg/apis/meta/v1'' ) // BeidouType is the type related to Beidou execution. type BeidouType string const ( // BeidouTask represents the Task execution type. BeidouTask BeidouType = ''Task'' ) // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Beidou represents a crd used to describe serices. type Beidou struct { metav1.TypeMeta`json:'',inline''` metav1.ObjectMeta `json:''metadata,omitempty'' protobuf:''bytes,1,opt,name=metadata''` SpecBeidouSpec`json:''spec,omitempty'' protobuf:''bytes,2,opt,name=spec''` Status BeidouStatus `json:''status,omitempty'' protobuf:''bytes,3,opt,name=status''` } // BeidouSpec is the spec of a Beidou. type BeidouSpec struct { Steps[]BeidouStep`json:''steps'' protobuf:''bytes,1,opt,name=steps''` References []BeidouReference `json:''references'' protobuf:''bytes,2,opt,name=references''` } // BeidouStep is the spec of step. type BeidouStep struct { Namestring`json:''name'' protobuf:''bytes,1,opt,name=name''` Operations []BeidouOperation `json:''operations'' protobuf:''bytes,2,opt,name=operations''` } // BeidouOperation is the spec of operation. type BeidouOperation struct { Name string`json:''name'' protobuf:''bytes,1,opt,name=name''` Type BeidouType`json:''type'' protobuf:''bytes,2,opt,name=type''` Opstring`json:''op'' protobuf:''bytes,3,opt,name=op''` Args []BeidouArg `json:''args'' protobuf:''bytes,4,opt,name=args''` } // BeidouArg is the spec of arg. type BeidouArg struct { Namestring`json:''name'' protobuf:''bytes,1,opt,name=name''` Valuestring`json:''value,omitempty'' protobuf:''bytes,2,opt,name=value''` ReferenceBeidouOperationReference `json:''reference,omitempty'' protobuf:''bytes,3,opt,name=reference''` Tolerations []corev1.Toleration`json:''tolerations,omitempty'' protobuf:''bytes,4,opt,name=tolerations''` Checking[]string`json:''checking,omitempty'' protobuf:''bytes,5,opt,name=checking''` } // BeidouOperationReference is the spec of operation reference. type BeidouOperationReference struct { ID string `json:''id'' protobuf:''bytes,1,opt,name=id''` } // BeidouReference is the spec of reference. type BeidouReference struct { IDstring`json:''id'' protobuf:''bytes,1,opt,name=id''` Steps []BeidouStep `json:''steps'' protobuf:''bytes,2,opt,name=steps''` } // BeidouStatus represents the current state of a Beidou. type BeidouStatus struct { Message string `json:''message'' protobuf:''bytes,1,opt,name=message''` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // BeidouList is a collection of Beidou. type BeidouList struct { metav1.TypeMeta `json:'',inline''` metav1.ListMeta `json:''metadata'' protobuf:''bytes,1,opt,name=metadata''` Items []Beidou `json:''items'' protobuf:''bytes,2,opt,name=items''` }核心流程:
推荐阅读
- 木木不哭助手|虎牙《CS?GO》一哥发现另类新玩法,全程尬舞秀出天际
- CSGO|打打杀杀太无聊,CSGO出了新玩法?QUQU中路直接邀人尬舞
- 王者荣耀|王者荣耀:“七命复活流”玩法到底是什么?复活甲被限制复活次数
- 电信诈骗|市民赵女士遭遇电信诈骗新玩法:靠“绑架”讹钱
- 直播超级夜、总裁直播、省长直播......京东直播创新玩法引爆11.11
- 天涯明月刀|天涯明月刀:提升功力不用愁!装备琢磨系统玩法详解
- 闽南网|导能绘卷玩法攻略分享,《原神》导能绘卷获取方法
- 玩加电竞APP|LOL游戏玩法感想:商店中新增超过60个全新或更新的图标
- 九游网|《原神》导能绘卷获取方法 导能绘卷玩法分享
- 追狐狸的人呐|简单的玩法,不简单的表达,最好的反战游戏之一
