在 Kubernetes 中,CRD(Custom Resource Definition)和 CR(Custom Resource)是用于扩展 Kubernetes 功能的机制。它们的关系和使用可以用一个完整案例来说明。
定义
CRD(Custom Resource Definition): 自定义资源定义,描述了一种新的资源类型。通过创建 CRD,用户可以向 Kubernetes 集群中添加新资源类型,类似于 Pod、Service 等内置资源。
CR(Custom Resource): 自定义资源,是基于 CRD 创建的资源实例。CR 使用 CRD 定义的规格,可以像管理其他 Kubernetes 资源一样进行管理。
Kubernetes Custom Resource Definitions(CRD)提供了许多好处,使其成为扩展 Kubernetes 平台功能的重要工具:
1.自定义资源类型:CRD 允许你定义和创建自定义资源类型,与 Kubernetes 内置资源一起工作,满足特定业务需求。
2.无缝集成:自定义资源可以与 Kubernetes 的 RBAC、监控和日志工具集成,实现统一管理和监控。
3.原生API交互:通过定义 CRD,你可以使用 Kubernetes API 和 kubectl 命令来管理自定义资源,保持一致的操作体验。
4.可扩展性:CRD 提供了一种无需外部服务即可扩展 Kubernetes 平台的方法,使开发者可以根据需要添加新的功能和特性。
5.自动化和高效:通过自定义控制器和操作器,CRD 可以实现自动化操作流程,提高系统运维的效率和可靠性。
6.复用性和共享:CRD 可以打包成 Helm Chart 等形式,方便分享和复用,促进社区和企业内部的协作和标准化。
7.分层管理:利用 CRD,可以实现应用的分层和模块化管理,清晰定义应用中的每个部分及其配置。
8.综合来看,CRD 提供了一种灵活且强大的方式来定制和扩展 Kubernetes,适应不同场景和需求。
案例:管理自定义“应用程序”资源
假设我们要在 Kubernetes 中管理一个自定义的应用程序资源。
Step 1: 定义 CRD
首先,创建一个 CRD 文件 application-crd.yaml:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: applications.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
name:
type: string
replicas:
type: integer
scope: Namespaced
names:
plural: applications
singular: application
kind: Application
shortNames:
- app
Step 2: 应用 CRD
使用 kubectl 命令应用这个 CRD:
kubectl apply -f application-crd.yaml
这样,你就创建了一个新的资源类型 Application。
Step 3: 创建一个实例 CR
创建一个自定义资源 my-application.yaml:
apiVersion: example.com/v1
kind: Application
metadata:
name: my-app
spec:
name: "My Custom App"
replicas: 3
Step 4: 应用实例 CR
使用 kubectl 命令创建这个自定义资源实例:
kubectl apply -f my-application.yaml
Step 5: 验证创建
你可以使用以下命令查看自定义资源实例:
kubectl get applications
或者查看详细信息:
kubectl describe application my-app
总结
CRD 定义了一个新的资源类型,它告诉 Kubernetes 如何解释和管理这种新的资源。
CR 是这种新类型的资源实例,遵循 CRD 的定义进行配置。
通过 CRD 和 CR 的结合,Kubernetes 可以支持多种不同的自定义资源,为应用的部署和管理提供了强大的扩展能力。
查看相关CRD
列出所有的 CRDs:
kubectl get crds
查看某个 CRD 类型的资源:kubectl get myresources.example.com
查看所有命名空间中的某个类型的 CR: kubectl get myresources.example.com --all-namespaces
查看详细信息:
kubectl describe myresources.example.com
kubectl get myresources.example.com -o yaml
Controller
只定义一个 CRD 其实没有什么作用,它只会被 API Server 简单地计入到 etcd 中。如何依据这个 CRD 定义的资源和 Schema 来做一些复杂的操作,则是由 Controller,也就是控制器来实现的。
Controller 其实是 Kubernetes 提供的一种可插拔式的方法来扩展或者控制声明式的 Kubernetes 资源。它是 Kubernetes 的大脑,负责大部分资源的控制操作。以 Deployment 为例,它就是通过 kube-controller-manager 来部署的。
比如说声明一个 Deployment 有 replicas、有 2 个 Pod,那么 kube-controller-manager 在观察 etcd 时接收到了该请求之后,就会去创建两个对应的 Pod 的副本,并且它会去实时地观察着这些 Pod 的状态,如果这些 Pod 发生变化了、回滚了、失败了、重启了等等,它都会去做一些对应的操作。
所以 Controller 才是控制整个 Kubernetes 资源最终表现出来的状态的大脑。
用户声明完成 CRD 之后,也需要创建一个控制器来完成对应的目标。比如之前的 Foo,它希望去创建一个 Deployment,replicas 为 1,这就需要我们创建一个控制器用于创建对应的 Deployment 才能真正实现 CRD 的功能。
Operators
Operators是CRDs的高级应用,结合了自定义控制器逻辑,
监听并响应自定义资源的变化,自动化执行复杂任务。
Operator 和Controller没有太大区别,一般称对 k8s 原生资源的控制叫为 Controller,对于自定义资源(CRD)的控制较为 Operator,Operator中实现相关controller重写方法(可简单理解为Java web的controller)。
总结
CRD,类似struct (POD)的定义(API 的类型,资源的类型)
用户提交的 yaml —— 在 k8s 形成 API 对象 (对 struct 的内容填充)
CR资源对象 —— 可以理解为 实例 (最后形成的 struct 对象)
Controller、Operator—— 监听 CRD 的各种事件来添加自定义的业务逻辑。 (比如,可以读取相关如下图CR的信息后,去创建deploy,service等)。
Pod 也是遵循上述流程,一般对于原生资源的控制 成为 Controller
Operator 有很多脚手架(kubuilder、Operator-sdk),就是对 Controller 进行封装,便于编写
例:某个实例CR附带的信息