《K8S Operator实践总结.docx》由会员分享,可在线阅读,更多相关《K8S Operator实践总结.docx(7页珍藏版)》请在第一文库网上搜索。
1、K8SOperator实践总结前言前段时间接触了k8sOPeratOr开发,在开发的过程中碰到了很多问题,现将开发过程中碰到的问题及经验进行总结。一、开发流程步骤1 .开发前提 了解k8s中内置资源的使用及CIient-go(C1ien1go不是必须项如果了解更好,笔者也是在开发结束后通过阅读Qubernetes源码剖析第五章补上这一课的) 有GO语言基础 了解k8soperator编程模式 了解kubebui1der(kubebui1der官方链接:https:/book,kubebui1der.ioquick-start.htm1),熟悉如何构建operator项目以及kubebui1de
2、r官方链接中的示例demo2 .开发某个产品的OPerator时,在进行开发前最好先在k8s集群中手动部署待开发的产品,熟悉该产品相关运维操作的同时也了解该OPerator最终是在对哪些k8s内置资源进行管理以及内置资源的相关配置;3 .理清楚OPerator中涉及的操作包含哪些,例如集群构建、节点迁移、资源配额管理等;此外还需要好好设计spec和status;4 .经过前面步骤后我们就进入实际开发过程了,在第三步的基础上我们可以知道operator中涉及到的操作最终都是对k8s内置资源的操作,所以第一步可以对涉及到的k8s内置资源的相关操作进行开发,然后开发集群构建流程、维护流程等。二、开发
3、总结1在对k8s内置资源相关操作进行开发时,可以将所有内置资源相同的方法抽象出一个接口,比如创建资源、判断资源是否存在等2 .在创建内置资源时,例如一个Pod,可以对照k8s源码中对应资源的结构体定义来构建3 .在创建内置资源时,可以使用OWnerRefrenCe来做资源关联,这样当OWner资源被删除时,被。Wn的资源会级联删除,其本质是k8sGC机制。具体调用contro11eruti1的SetContro11erReference如下函数:SetContro11erReference-contro11eruti1.SetContro1IerReference这里涉及到k8sGC原理,下图
4、是k8sGC的GC是GarbageCo11ector的简称,它是负责删除集群中的资源对象,GC由三个部分组成,分别是:Scanner.GarbageProcessor和Propagator0 ScannerSCanner主要完成的任务是周期性地扫描系统中所有资源对象,并将这些资源对象放到DirtyQUeUe中 GarbageProcessorGarbageProcessor由两部分组成,分别是DirtyQUeUe和Workers,每个Worker的任务有三个:(1)从DirtyQUeUe中取出资源(2)判断该资源的OWnerReferenCeS是否为空,如果为空则继续处理DirtyQueue中
5、下一个资源(3)如果资源的OWnerReferenCeS不为空,则检查OWnerReferenCeS中的每个条目是否存在,如果至少有一个存在则什么也不做,如果都不存在则请求AP1Server删除该资源PrOPagatorProPagator是由EVentQUeue、一个WOrker和一个表示owner-dependant关系的DAG组成的。DAG只存储name/uid/orphan三元MoPrOPagator会监控所有资源的创建/更新/删除事件,并将事件放入到EventQueue中OWorker负责从EVentQueue中取出事件并根据事件类型做出对应的处理。如果是创建或者更新事件,则会更新D
6、AG(如果资源对象有一个owner且owner不存在于DAG中,除了会将该资源添加到DAG中还会将该资源添加到DirtyQueue中)。如果是删除事件则会从DAG中删除该资源,并且还会将该资源依赖的资源添加到DirtyQueue中。有关k8sGC相关设计可以参考:官方设计方案(https:/kubernetesdesig-proposa1s-archive/b1ob/main/api-machinery/garbage-co11ection,md)在k8s中资源之间有OWne1dePendant关系,详见:OwnersandDependents(https:/kubernetes.io/doc
7、s/concepts/overview/working-with-objectsowners-dependents)4.在开发过程中会碰到类似于给Pod添加/删除Iabe1、修改PVC存储大小、修改Pod镜像等问题,这些问题实质上是对k8s内置资源的修改,在对资源修改时有两种选择,分别是UPdate和PatCh,这时就需要清楚两者的区别:在k8s的内置资源对象中,有一个全局唯一的版本号metadata.resourceVersion,这个版本号从资源对象创建开始就会被分配一个。如果是使用UPdate对资源进行更新时,需要将整个修改后的对象提交给k8s,而被提交的对象中需要包含resourceV
8、ersion,当k8s收到该请求时会先比较请求中的resourceVersion与当前k8s中的该对象的resourceVersion是否一致,如果一致才会执行UPdate操作,否则会拒绝该请求并返回版本冲突的问题。此外还需要注意:当资源对象更新成功后,其resourceVersion会发生变化。对于PatCh请求,只需要将待修改资源对象中的某些字段的修改提交给k8s即可,但是这里需要注意:在k8s中PatCh有四种类型分别是:JSoNPatChType、MergePatchType%StrategicMergePatchType和APP1yPatChTyPeo比较常用的是JSONPatchT
9、ype和MergePatchType(1) JSONPatchTypeJSoNPatChTyPe的数据格式如下:“path”:“xxx”“va1ue:iixxxff其中OP表示对资源对象的操作类型,主要包括三种:add、removerep1ace;path表示待修改的数据的属性的路径;VaIUe表示修改后的值。(2) MergePatchTypeMergePatChTyPe需要包含对资源对象的部分描述,该请求发送到k8s后会和集群中的当前对象进行合并从而创建新的对象。例如在对POd的Iabe1进行修改时可以进行以下格式数据拼接:atchdate,err:=json.Marsha1(“metad
10、ata:mapstirnginterface1abe1s:mapstringinterface。HFfhirta:b这里需要注意以下两点,一个是如果VaIUe值为ni1,则表示要删除对应的键;另一个是MergePatchType没有办法单独更新一个列表或者数组中的某个元素,所以如果是要在COntainerS中新增容器、修改容器的image等,需要用整个containers列表来提交。5 .判断k8s内置资源是否删除的依据在某些场景下需要判断资源对象是否删除完成,这种情况下可以通过判断该资源对象的de1etionTimestamp字段是否为空,如果不为空则表示该资源正在删除中。67 .对pod的资源进行修改时需要删除pod进行重建8 .修改PVC大小时需要注意只能扩容不能缩容,且对其修改时可以采用JSONPatchType9 .在对pod的image进行修改时,旧的container不会经历running和ready这两个状态而是直接替换为新的container10 .最重要的一点是所有的逻辑需要保持幕等-全文完-