欢迎访问网易云社区,了解更多网易技术产品运营经验。

前言

默认读者有kubernetes基础概念的背景知识,因此基础概念例如有状态、pod、Replica Sets、Deployments、statefulsets等不在此文详细阐述。 可以看我之前的一些关于kubernetes的文章:

kubernetes 1.3管中窥豹- RS(Replica Sets)

kubernetes pod&container生命周期浅析

kubernetes1.6管中窥豹-StatefulSets概念、约束、原理及实例

本文主要介绍一个1.7+以后出现的新概念CRD(CustomResourceDefinition )的概念、使用场景及实例。

CRD历史来源
k8s1.6~1.7 TRP(CRD的前身):Third Party Resource。
k8s1.7+ CRD: Custom Resource Definition。

CRD的概念

Custom resources:是对K8S API的扩展,代表了一个特定的kubetnetes的定制化安装。在一个运行中的集群中,自定义资源可以动态注册到集群中。注册完毕以后,用户可以通过kubelet创建和访问这个自定义的对象,类似于操作pod一样。

Custom controllers:Custom resources可以让用户简单的存储和获取结构化数据。只有结合控制器才能变成一个真正的declarative API(被声明过的API)。控制器可以把资源更新成用户想要的状态,并且通过一系列操作维护和变更状态。定制化控制器是用户可以在运行中的集群内部署和更新的一个控制器,它独立于集群本身的生命周期。 定制化控制器可以和任何一种资源一起工作,当和定制化资源结合使用时尤其有效。

Operator模式 是一个customer controllers和Custom resources结合的例子。它可以允许开发者将特殊应用编码至kubernetes的扩展API内。

如何添加一个Custom resources到我的kubernetes集群呢? kubernetes提供了两种方式将Custom resources添加到集群。

1. Custom Resource Definitions (CRDs):更易用、不需要编码。但是缺乏灵活性。

2. API Aggregation:需要编码,允许通过聚合层的方式提供更加定制化的实现。

本文重点讲解Custom Resource Definitions (CRD)的使用方法。

CRD使用场景

假设需要在原生kubernetes完成一些额外的功能开发,而且想使用restful风格的API 去调用这个功能。比如像开发容器保存镜像或者重启镜像等操作(一般都通过命令发送给容器内部完成)。就可以在原生kubernetes上增加一个CRD,命名为task。通过task触发一些逻辑。当使用apiserver下发这个task创建时,Custom controllers watch到这个task就开始处理相关业务逻辑,然后通过agent调用docker命令完成容器保存镜像功能并且重启容器。当Custom controllers watch到pod重新运行的时候,本次操作完成。 流程图如下:

CRD使用示例

如果想要完成上述场景的功能,需要定义一个CRD,并且创建出来。 举例如下,以下是一个可以在1.9集群环境中创建成功的crd yaml文件。

apiVersion: apiextensions.k8s.io/v1beta1kind: CustomResourceDefinitionmetadata:
  # name must match the spec fields below, and be in the form: <plural>.<group>  name: tasks.163yun.comspec:
  # group name to use for REST API: /apis/<group>/<version>  group: 163yun.com
  # version name to use for REST API: /apis/<group>/<version>  version: v1
  # either Namespaced or Cluster  scope: Namespaced  names:
    # plural name to be used in the URL: /apis/<group>/<version>/<plural>    plural: tasks
    # singular name to be used as an alias on the CLI and for display    singular: task
    # kind is normally the CamelCased singular type. Your resource manifests use this.    kind: Task
    # shortNames allow shorter string to match your resource on the CLI    shortNames:
    - task

其中几个关键要素是name、group、scope以及names里面的一些定义。

name:用于定义CRD的名字,后缀需要跟group一致,例如tasks.163yun.com,前缀需要跟names中的plural一致。

group以及version用于标识restAPI:即/apis//。 上文中的接口前面一部分就是/apis/163yun.com/v1

scope: 表明作用于,可以是基于namespace的,也可以是基于集群的。 如果是基于namespace的。则API格式为:/apis/{group}/v1/namespaces/{namespace}/{spec.names.plural}/… 如果是基于cluster的。则API格式为:/apis/{group}/v1/{spec.names.plural}/… 上文创建的CRD的API则为:/apis/163yun.com/v1/namespaces/{namespace}/tasks

names:描述了一些自定义资源的名字以及类型的名字(重点是plural定义以及kind定义,因为会在url或者查询资源中用的到)。

当以上面的模板创建出来一个CRD后,可以查到crd的信息:

root@hzyq-k8s-qa-16-master:~/cxq# kubectl  get CustomResourceDefinition tasks.163yun.com   -o yaml 
apiVersion: apiextensions.k8s.io/v1beta1kind: CustomResourceDefinitionmetadata:  creationTimestamp: 2018-03-16T06:17:03Z  generation: 1  name: tasks.163yun.com  resourceVersion: "35442027"  selfLink: /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/tasks.163yun.com  uid: a538030c-28e1-11e8-b047-fa163ef9812dspec:  group: 163yun.com  names:    kind: Task    listKind: TaskList    plural: tasks    shortNames:
    - task    singular: task  scope: Namespaced  version: v1status:  acceptedNames:    kind: Task    listKind: TaskList    plural: tasks    shortNames:
    - task    singular: task  conditions:
  - lastTransitionTime: 2018-03-16T06:17:03Z    message: no conflicts found    reason: NoConflicts    status: "True"    type: NamesAccepted
  - lastTransitionTime: 2018-03-16T06:17:03Z    message: the initial names have been accepted    reason: InitialNamesAccepted    status: "True"    type: Established

这时查询crd中定义的task类型的资源,是空的:

root@hzyq-k8s-qa-16-master:~/cxq# kubectl  get  task   -o yaml 
apiVersion: v1items: []kind: Listmetadata:  resourceVersion: ""  selfLink: ""

这时需要自定义一个task类型的模板,创建,以使得task可以触发自定义的一些事件

root@hzyq-k8s-qa-16-master:~/cxq# cat cxq-task.yaml 
apiVersion: "163yun.com/v1"kind: Taskmetadata:  name: cxq-nce-taskspec:  cronSpec: "* * * * /5"  image: my-awesome-cron-image
root@hzyq-k8s-qa-16-master:~/cxq# kubectl create -f cxq-task.yaml 
task "cxq-nce-task" created
root@hzyq-k8s-qa-16-master:~/cxq#  kubectl get task -o yamlapiVersion: v1items:- apiVersion: 163yun.com/v1  kind: Task  metadata:    clusterName: ""    creationTimestamp: 2018-03-16T06:43:10Z    labels: {}    name: cxq-nce-task    namespace: default    resourceVersion: "35444352"    selfLink: /apis/163yun.com/v1/namespaces/default/tasks/cxq-nce-task    uid: 4ad237aa-28e5-11e8-b047-fa163ef9812d  spec:    cronSpec: '* * * * /5'    image: my-awesome-cron-imagekind: Listmetadata:  resourceVersion: ""  selfLink: ""

注意由于CRD和自定义的Task资源本身是namespace无关的,因此对所有namespace都可见。如果指定了scope为namespace。那么创建的自定义task也需要指定namespace,如果不指定的话,系统会自动将task分配到default 的namespace下。

这时可以通过task的url去对自定义的task资源进行操作,或者watch。结合上一节的流程图来完成实现自定义功能的目的。以下是调用watch接口对task资源进行长连接监控(变化)。

root@hzyq-k8s-qa-16-master:~/cxq# curl http://10.180.156.79:8080/apis/163yun.com/v1/namespaces/default/tasks?watch=true
{"type":"ADDED","object":{"apiVersion":"163yun.com/v1","kind":"Task","metadata":{"clusterName":"","creationTimestamp":"2018-03-16T06:43:10Z","labels":{},"name":"cxq-nce-task","namespace":"default","resourceVersion":"35444352","selfLink":"/apis/163yun.com/v1/namespaces/default/tasks/cxq-nce-task","uid":"4ad237aa-28e5-11e8-b047-fa163ef9812d"},"spec":{"cronSpec":"* * * * /5","image":"my-awesome-cron-image"}}}

总结

CRD提供了一种无须编码就可以扩展原生kubenetes API接口的方式。很适合在云应用中扩展kubernetes的自定义接口和功能。在一些无须太多定制和灵活的开发场景下,CRD的方式已经足够使用。如果想更为灵活的添加逻辑就需要参考API Aggregation的使用了。

网易云容器服务为用户提供了无服务器容器,让企业能够快速部署业务,轻松运维服务。容器服务支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复及性能监测等功能。点击免费试用

相关阅读:浅谈 kubernetes service 那些事(上篇)

浅谈 kubernetes service 那些事 (下篇)

本文来自网易实践者社区,经作者崔晓晴授权发布。

相关文章:
【推荐】 初识Continuation

kubernetes1.9管中窥豹-CRD概念、使用场景及实例的更多相关文章

  1. Oracle dbms_lock.sleep()存储过程使用技巧-场景-分析-实例

    <Oracle dbms_lock.sleep()存储过程使用技巧>-场景-分析-实例 摘要:今天是2014年3月10日,北京,雾霾,下午组织相关部门开会.会议的结尾一名开发工程师找到了我 ...

  2. Unity学习笔记(一)——基本概念之场景(Scene)

    场景,顾名思义就是我们在游戏中所看到的物品.建筑.人物.背景.声音.特效等,基本上和我们玩游戏时所看到的游戏“场景”是同一个概念. Unity 3D中,“场景”是一个视图,我们通过“场景”这个视图,来 ...

  3. android launchmode(四种启动模式)应用场景及实例

    模式介绍 [1] standard 模式 这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中. [2] singleTop 模式 如果在任务的栈顶正好存在该Activ ...

  4. Cocos2d-JS引入其他场景小实例

    创建新项目,目标是把LogoNode.js场景引入app.js 新建LogoNode.js var LogoLayer = cc.Layer.extend({ ctor:function () { t ...

  5. Spring Aop重要概念介绍及应用实例结合分析

    转自:http://bbs.csdn.net/topics/390811099 此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细 ...

  6. Java面向对象_继承——基本概念以及管理化妆品实例分析

    一.继承的基本概念: 1.继承是面向对象三大特征之一 2.被继承的类成为父类(超类),继承父类的类成为子类(派生类) 3.继承是指一个对象直接使用另一个对象的属性和方法 4.通过继承可以实现代码重用 ...

  7. Python面向对象-概念、类、实例

    OOP——Object Oriented Programming,面向对象编程,是一种程序设计思想.该思想将对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 区别于面向过程的程序设计即把计 ...

  8. RPC远程调用概念 &amp;&amp; demo实例

    RPC是指远程过程调用,直观说法就是A通过网络调用B的过程方法. 也就是说两台serverA.B,一个应用部署在Aserver上,想要调用Bserver上应用提供的函数/方法,因为不在一个内存空间,不 ...

  9. redis应用场景及实例

    Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程.另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不 ...

随机推荐

  1. mysql优化概述2

    一.索引的概念 利用关键字,就是记录的部分数据(某个字段,某些字段,某个字段的一部份),建立与记录位置的对应关系,就是索引.索引的关键字一定是排序的. 二.索引的类型 mysql支持四种索引: 1.主 ...

  2. 【原创】VB超强游戏外挂帮助类,封装了很多方法

    ''' <summary> ''' a very nice file that can be used on other projects ''' </summary> ''' ...

  3. silverlight的Datagrid控件列绑定属性笔记

    <data:DataGridTemplateColumn Header="给作者留言"> <data:DataGridTemplateColumn.CellTem ...

  4. jstl标签详解 (转载)

    JSLT标签库,是日常开发经常使用的,也是众多标签中性能最好的.把常用的内容,放在这里备份一份,随用随查.尽量做到不用查,就可以随手就可以写出来.这算是Java程序员的基本功吧,一定要扎实. JSTL ...

  5. winXP使用

    1.获得管理员权限 开机启动时按F8-->进入“安全模式”-->选择“Administrator”-->点击登录 2.Windows XP属于单用户多任务操作系统,Linux属于多用 ...

  6. Storm 系列(二)实时平台介绍

    Storm 系列(二)实时平台介绍 本章中的实时平台是指针对大数据进行实时分析的一整套系统,包括数据的收集.处理.存储等.一般而言,大数据有 4 个特点: Volumn(大量). Velocity(高 ...

  7. exit--进程退出;wait--进程等待;execl--执行程序

    函数原型:void exit(int status) 参数说明:退出状态. 函数原型:pid_t wait(int *status) 头文件:#include<sys/types.h>,# ...

  8. ubuntu系统下安装pyspider:搭建pyspider服务器新手教程

    首先感谢“巧克力味腺嘌呤”的博客和Debian 8.1 安装配置 pyspider 爬虫,本人根据他们的教程在ubuntu系统中进行了实际操作,发现有一些不同,也出现了很多错误,因此做此教程,为新手服 ...

  9. 流程控制 if while for 已及数字类型 进制转换

    一:if 语句 语法一:ifif 条件: code1 code1 code1 语法二:if ...else ... if 条件: code1 code1 code1else: code1 code1 ...

  10. 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)

    传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...