前言
有些场景,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: 2021-10-20T09: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、高级主题
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
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