25.修神篇:使用CRD扩展Kubernetes-API和高级主题
25.修神篇:使用CRD扩展Kubernetes-API和高级主题
有些场景,kubernetes内建的资源类型往往不能满足我们的需求,如redis集群初始化、扩容、缩容、备份等操作。
这时候就需要我们考虑如何去扩展kubernetes的API。
1.扩展方式
为了增强kubernetes的定制化功能,我们可以通过以下三种方式来扩展Kubernetes API:
1>修改kubenetes的apiserver源码:难度最大、kubernetes版本更新太快,兼容性很困难
2>自定义API server(Custom API server)并聚合到API(Aggregation)中:难度较大,需要开发能力
需要考虑的问题也不少:例如数据如何存储、API版本之间如何转换和支持等
3>1.7以下版本编写TPR,kubernetes1.7及以上版本用CRD:常用方式
2.扩展架构图
如图所示,用户对集群的请求首先到apiserver内部的Aggregator(聚合器),然后再到实际的apiserver模块。
上面提到的三种扩展方式,可以在图中清晰看到。
特别注意:
对于三种扩展方式的访问如何分配,这是基于kube-aggregator(APIservice)进行筛选的,可以理解成路由表、或者是nginx动静分离的效果。
CRD(Custom Resource Definition)在用法上和原生资源基本相同,都支持通过kubectl命令行或者API方式进行访问和操作。
正是CRD的灵活和强大,从另一方面催生k8s生态的快速发展。
CRD经常和对应的Operator配合出现,来完成一些复杂操作的封装。比如Prometheus Operator和Prometheus CRD,来部署和运维对应的Prometheus 实例
3.使用CRD扩展Kubernetes API
1)首先,我们先创建自定义资源类型:编辑resourcedefinition.yaml
apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: # 名称必须符合下面的格式:<plural>.<group> name: crontabs.stable.example.com spec: # REST API使用的组名称:/apis/<group>/<version> group: stable.example.com # REST API使用的版本号:/apis/<group>/<version> version: v1 # 定义哪个级别的资源类型:Namespaced或Cluster scope: Namespaced names: # URL中使用的复数名称: /apis/<group>/<version>/<plural> plural: crontabs # CLI中使用的单数名称 singular: crontab # CamelCased格式的单数类型。在清单文件中使用 kind: CronTab # CLI中使用的资源简称 shortNames: - ct
2)apply配置文件
[root@centos-1 dingqishi]# kubectl apply -f resourcedefinition.yaml customresourcedefinition.apiextensions.k8s.io/crontabs.stable.example.com created
3)创建自定义资源的对象:my-new-cron-object.yaml,其中kind引用上面自定义的资源类型:CronTab,并apply
apiVersion: "stable.example.com/v1" kind: CronTab metadata: name: my-new-cron-object spec: cronSpec: "* * * * /5" image: my-awesome-cron-image
4)查看自定义资源类型上的pod资源,此时你可以像查看别的原生基础资源那样进行相关操作了。
[root@centos-1 dingqishi]# kubectl get CronTab NAME AGE my-new-cron-object 23s [root@centos-1 dingqishi]# kubectl describe CronTab my-new-cron-object Name: my-new-cron-object Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"stable.example.com/v1","kind":"CronTab","metadata":{"annotations":{},"name":"my-new-cron-object","namespace":"default"},"sp... API Version: stable.example.com/v1 Kind: CronTab Metadata: Creation Timestamp: 2019-12-13T09:40:26Z Generation: 1 Resource Version: 151136 Self Link: /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object UID: 778d9359-bdb8-4f07-a07b-8a20b95f1398 Spec: Cron Spec: * * * * /5 Image: my-awesome-cron-image Events: <none>
5)你可以也可以使用我们定义的shortNames来获取信息
kubectl get ct -o yaml
4.高级主题
4.1.Validation(验证)
在项目中用自定义资源对象时,如果创建自定义资源时某些字段不符合要求,会导致监听该资源对象的异常和报错
所以Validation这个功能在创建时就进行校验是非常实用的,减少后面的排错和异常处理的麻烦。
通过 OpenAPI v3 schema和ValidatingAdmissionWebhook验证自定义对象是否符合标准。
1)在自定义资源类型CronTab中,定义crontabs-crd-with-validation.yaml,新增Validation(验证)功能
kind: CustomResourceDefinition metadata: name: crontabs.stable.example.com spec: group: stable.example.com version: v1 names: kind: CronTab plural: crontabs singular: crontab shortNames: - ct scope: Namespaced validation: #新增功能 openAPIV3Schema: properties: spec: properties: userID: type: integer minimum: 1 maximum: 65535 groups: type: array email: type: string password: type: string format: password required: ["userID","groups"]
你也可以通过以下命令,查看openAPIV3Schema的语法结构
kubectl explain CustomResourceDefinition.spec.validation.openAPIV3Schema
2)编辑crontabs-with-invalid-field.yaml,引用kind: CronTab,并设置非法userID,验证Validation(验证)功能是否work,并apply
apiVersion: stable.example.com/v1 #定义规范: <group>/<version> kind: CronTab metadata: name: tony namespace: default spec: userID: 999999
3)这时候发现Validation(验证)已经生效,拦截了pod初始化和运行
[root@centos-1 dingqishi]# kubectl apply -f users-with-invalid-field.yaml The CronTab "tony" is invalid: * spec.userID: Invalid value: 65535: spec.userID in body should be less than or equal to 65535 * spec.groups: Required value
4.2.Category(分类)
类别是自定义资源所属分组资源的列表(例如all)。
你可以使用kubectl get category-name列出属于该类别的资源。此功能是beta,可用于v1.10 中的自定义资源。
以下示例将CustomResourceDefinition添加至all的类别列表,并说明如何使用 kubectl get all输出自定义资源 。
1)首先,编辑resourcedefinition-with-category.yaml,并apply
apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: crontabs.stable.example.com spec: group: stable.example.com versions: - name: v1 served: true storage: true scope: Namespaced names: plural: crontabs singular: crontab kind: CronTab shortNames: - ct # categories is a list of grouped resources the custom resource belongs to. categories: - all
API配置:kubectl explain CustomResourceDefinition.spec.names.categories
2)接着,编辑my-crontab.yaml,并apply
apiVersion: "stable.example.com/v1" kind: CronTab metadata: name: my-new-cron-object spec: cronSpec: "* * * * */5" image: my-awesome-cron-image
3)使用kubectl get all,这时候就可以看到我们自定义的Crontab类型资源了
[root@centos-1 ~]# kubectl get all NAME READY STATUS RESTARTS AGE pod/ngx-new-cb79d555-2c7qq 1/1 Running 0 3d NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18d NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/ngx-new 1/1 1 1 17d NAME DESIRED CURRENT READY AGE replicaset.apps/ngx-new-cb79d555 1 1 1 3d4h NAME AGE crontab.stable.example.com/my-new-cron-object 1s
@版权声明:51CTO独家出品,未经允许不能转载,否则追究法律责任