【K8s 精选】Kubernetes CRD 简介
1 CRD 简介
CRD 全称是 Custom Resource Definition, 其特点如下
● CRD 本身是 Kubernetes 的一种资源,允许用户自定义新的资源类型
● 除了 CRD 还需要用户提供一个 Controller 以实现自己的逻辑
● CRD 允许用户基于已有的 Kubernetes 资源,例如 Deployment、Configmap 等,拓展集群能力
● CRD 可以自定义一套成体系的规范,自造概念
CRD 本身是一种 Kubernetes 内置的资源类型,即自定义资源的定义,用于描述用户定义的资源是什么样子。CRD 的相关概念:① 从 Kubernetes 的用户角度来看,所有东西都叫资源 Resource,就是 Yaml 里的字段 Kind 的内容,例如 Service、Deployment 等。② 除了常见内置资源之外,Kubernetes 允许用户自定义资源 Custom Resource,而 CRD 表示自定义资源的定义。
$kubectl get crd
NAME CREATED AT
apps.app.my.cn 2021-07-25T07:02:47Z
microservices.app.my.cn 2021-07-25T07:02:47Z
参考 Future of CRDs: Structural Schemas ,Schema 可以确保 Yaml 描述的资源是规范的、合法的。CRD 本质是一个 Open Api 的 Schema,向 Kubernetes 集群注册一种新资源,并告诉 ApiServer,这种资源怎么被合法的定义。
2 CRD 能做什么
拓展:什么是控制器模式?
以 Deployment 为实例,Deployment 没有直接创建 Pod,而是管理 RS,而 RS 管理 Pod,这就是控制器模式。控制器模式允许基于已有的资源定义更高阶的控制器,用来实现更复杂的能力,详情可参考Kubernetes 控制器的工作原理解读
用户可以自定义控制器的逻辑,实现 Kubernetes 集群原生不支持的功能。下面利用 Kubebuilder 创建 CRD 实现 Kubernetes 集群内置微服务管理。
2.1 样例 - 微服务管理总览
微服务管理具备部署、发布的能力。
App
负责管理整个应用的生命周期,MicroService
负责管理微服务的生命周期。① 部署方面:App
可以直接管理多个 MicroService
,同时 MicroService
利用控制器模式,可以为每个版本创建一个 Deployment
, 实现多个版本同时部署。
② 发布方面:微服务管理具备蓝绿发布、灰度发布的功能。MicroService
为自己创建 1 个的 LoadBalance
,也为每个版本创建了 Service
。如下图所示,MicroService
下的每个版本(对应每个 Deployment
)都有 Service
,而本身也有 LoadBalance
,即总共拥有 n+1
个 Service
。LoadBalance
和 CurrentVersion
实现了蓝绿发布。MicroService
利用 nginx ingress controller 的能力,通过修改 LoadBalance
的 canary
配置,实现按照 header/cookie/比例 的灰度发布
2.2 样例 - 创建 Yaml 配置
CRD 配置详解可以参考 Kuberneters(K8s)CRD资源详解
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
# 名称必须与下面的spec字段匹配,格式为: <plural>.<group>
name: apps.app.o0w0o.cn
spec:
# 用于REST API的组名称: /apis/<group>/<version>
group: app.o0w0o.cn
names:
# kind字段使用驼峰命名规则. 资源清单使用如此
kind: App
# URL中使用的复数名称: /apis/<group>/<version>/<plural>
plural: apps
# 指定crd资源作用范围在命名空间或集群
scope: Namespaced
# 自定义资源的子资源的描述
subresources:
# 启用状态子资源
status: {}
# 验证机制
validation:
# openAPIV3Schema is the schema for validating custom objects.
openAPIV3Schema:
properties:
...
2.3 样例 - 自定义 Controller 逻辑
利用 Kubebuilder 实现 Kubernetes 集群内置微服务管理,App
和 MicroService
的 Controller 的主要逻辑如下:
func (r *ReconcileApp) Reconcile(request reconcile.Request) (reconcile.Result, error) {
...
// 状态 App 同步
if err := r.syncAppStatus(instance); err != nil {
log.Info("Sync App error", err)
return reconcile.Result{}, err
}
// 协调资源 MicroService
if err := r.reconcileMicroService(request, instance); err != nil {
log.Info("Creating MicroService error", err)
return reconcile.Result{}, err
}
...
}
func (r *ReconcileMicroService) Reconcile(request reconcile.Request) (reconcile.Result, error) {
...
// 同步 MicroService 状态
if err := r.syncMicroServiceStatus(instance); err != nil {
log.Info("Sync MicroServiceStatus error", err)
return reconcile.Result{}, err
}
// 协调实例
if err := r.reconcileInstance(instance); err != nil {
log.Info("Reconcile Instance Versions error", err)
return reconcile.Result{}, err
}
// 协调负载均衡器
if err := r.reconcileLoadBalance(instance); err != nil {
log.Info("Reconcile LoadBalance error", err)
return reconcile.Result{}, err
}
...
}
3 结论
① 从功能角度分析,CRD 是积木。用户可以把 Kubernetes 已有的资源和能力自由堆砌起来,从而拓展了 Kubernetes 原生不具备的能力。
② 从产品角度分析,CRD 允许用户基于自己产品的概念,让 Kubernetes 已有的资源为用户服务,而不是思考如何将场景应用到 Kubernetes。基于 Kubernetes 开发产品,无法避免如何将产品概念想 Kubernetes 靠拢,例如一个服务就是一个 Deployment
,一个实例就是一个 Pod
等。