自定义资源是Kubernetes API的扩展,本文将讨什么时候应该向Kubernetes集群添加自定义资源以及何时使用独立服务。它描述了添加自定义资源的两种方法以及如何在它们之间进行选择。
资源就是Kubernetes API集合中的某个的对象。例如,内置pods资源包含Pod对象的集合。
自定义资源是扩展了Kubernetes API,但在默认的API集合中是不可用的,因为没有对应的controller处理业务逻辑。使用自定义资源,不仅可以解耦大多数的自研功能,还可用使得Kubernetes更加模块化。
自定义资源可以通过动态注册的方法,于正在running的集群中创建、删除和更新,并且与集群本身的资源是相互独立的。当自定义资源被创建,就可以通过kubectl创建和访问对象,和对内置资源的操作完全一致。
在创建新的API时,应该考虑与Kubernetes的API聚合,还是让API独立运行。
API聚合 | API独立 |
---|---|
声明式 | 非声明式 |
kubectl可读可写 | 不需要kubectl支持 |
接受k8s的REST限制 | 特定API路径 |
可限定为cluster或者namespace | 不适用namespace |
重用k8s API支持的功能 | 不需要这些功能 |
在声明式API,通过具有以下特性:
命令式API,通过具有以下特性:
Kubernetes提供了两种向集群添加自定义资源的方法:
通过CRD创建自定义资源,只要符合CRD结构体定义,均可以被Kubernetes所接收,以下是CRD的定义:
type CustomResourceDefinition struct {
//Kind,APIVersion
metav1.TypeMeta
//metadata
metav1.ObjectMeta
//spec
Spec CustomResourceDefinitionSpec
//status
Status CustomResourceDefinitionStatus
}
type CustomResourceDefinitionSpec struct {
Group string
Version string
//Plural,Singular,ShortNames,Kind,ListKind,Categories
Names CustomResourceDefinitionNames
//cluster or namespace
Scope ResourceScope
//validation methods
Validation *CustomResourceValidation
//status,scale(spec.replicas,status.replicas,status.labelSelector)
Subresources *CustomResourceSubresources
//name,serve,storage
Versions []CustomResourceDefinitionVersion
//定义额外显示的列
AdditionalPrinterColumns []CustomResourceColumnDefinition
//不同版本之间的转换
Conversion *CustomResourceConversion
}
type CustomResourceDefinitionStatus struct {
//描述资源的当前状态,即status.conditions
Conditions []CustomResourceDefinitionCondition
//与spec.names类似,即status.acceptNames
AcceptedNames CustomResourceDefinitionNames
//资源曾经存在的版本,可在etcd中存储,供迁移用
StoredVersions []string
}
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# 名称必须符合下面的格式:.
name: clusterversions.paas
spec:
# REST API使用的组名称:/apis//
group: paas
# REST API使用的版本号:/apis//
versions:
- name: v1alpha1
serve: true
storage: true
# Namespaced或Cluster
scope: Cluster
names:
# URL中使用的复数名称: /apis///
plural: clusterversions
# CLI中使用的单数名称
singular: clusterversion
# CamelCased格式的单数类型。在清单文件中使用
kind: ClusterVersion
# CLI中使用的资源简称
shortNames:
- cv
# 校验方法
validation:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
#类型校验
cronSpec:
type: string
image:
type: string
replicas:
type: integer
只定义资源,不实现资源控制器是没有任何意义的。自定义控制器能够完成业务逻辑,最主要是依赖client-go库的各个组件的交互。下图展示它们之间的关系:
通过图示,可以看到几个核心组件的交互流程,蓝色表示client-go,黄色是自定义controller,各组件作用介绍如下:
简单的说,整个处理流程大概为:Reflector通过检测 Kubernetes API来跟踪该扩展资源类型的变化,一旦发现有变化,就将该Object存储队列中,Informer循环取出该Object并将其存入Indexer进行检索,同时触发Callback回调函数,并将变更的Object Key信息放入到工作队列中,此时自定义Controller里面的Process Item就会获取工作队列里面的Key,并从Indexer中获取Key对应的Object,从而进行相关的业务处理。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha1
names:
kind: Foo
plural: foos
scope: Namespaced
apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
name: example-foo
namespace: fst-manage
spec:
deploymentName: example-foo
replicas: 1
namespace: fst-manage
go build -o $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/sample-controller .
sudo ./sample-controller -kubeconfig=/opt/kube-agent/kubernetes/kubelet/kubeconfig
kubectl get po -n fst-manage -o wide |grep foo
curl podId:80