
Kubernetes(简称K8s)已成为容器编排领域的事实标准。其强大之处不仅在于内置的资源管理能力,更在于其高度可扩展的架构设计。自定义资源定义(Custom Resource Definition,CRD)作为Kubernetes的核心扩展机制,允许用户在不修改Kubernetes源代码的情况下,扩展API以管理自定义资源类型。本文将全面介绍CRD的概念、设计原则、开发流程及最佳实践,帮助开发者掌握这一强大工具。
CRD全称为Custom Resource Definition,是Kubernetes中用于定义自定义资源类型的机制。通过CRD,用户可以将特定业务逻辑抽象为Kubernetes原生资源,使其能够像内置资源(如Pod、Deployment)一样被API服务器管理。
2、CRD的核心价值:
在Kubernetes生态中,CRD常与几个关键概念相关联:
开发高质量的CRD需要考虑以下关键因素:
API设计方面:
/格式明确API版本,如example.com/v1,并考虑后续版本演进;spec(用户期望状态)和status(系统实际状态)字段;功能完整性:
Namespaced或Cluster作用域通过 OpenAPI Schema 声明字段类型和验证规则:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: apps.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema: # 字段验证规则
type: object
properties:
spec:
type: object
properties:
appName: { type: string }
replicas: { type: integer }
image: { type: string }
scope: Namespaced # 命名空间级资源
names:
plural: apps # API 路径:/apis/example.com/v1/apps
singular: app
kind: App
shortNames: ["ap"] # kubectl get ap 简写关键字段说明:
scope:Namespaced(命名空间内)或Cluster(集群级)。validation:通过 OpenAPI Schema 限制字段类型(如 string/integer)。kubectl apply -f app-crd.yaml
kubectl get crd # 验证 CRD 是否注册成功定义资源实例的 YAML:
apiVersion: example.com/v1
kind: App
metadata:
name: myapp
spec:
appName: "my-application"
replicas: 3
image: "nginx:1.25"应用实例:
kubectl apply -f myapp.yaml
kubectl get apps # 查看自定义资源curl -L -o kubebuilder https://github.com/kubernetes-sigs/kubebuilder/releases/download/v3.10.0/kubebuilder_linux_amd64
chmod +x kubebuilder && sudo mv kubebuilder /usr/local/bin/在 controllers/app_controller.go 中实现调和逻辑:
func (r *AppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// 获取 App 实例
app := &examplev1.App{}
if err := r.Get(ctx, req.NamespacedName, app); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 根据 app.Spec 创建 Deployment
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: app.Name, Namespace: app.Namespace},
Spec: appsv1.DeploymentSpec{
Replicas: &app.Spec.Replicas,
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Name: "app",
Image: app.Spec.Image,
}},
},
},
},
}
if err := r.Create(ctx, deployment); err != nil {
return ctrl.Result{}, err
}
// 更新状态
app.Status.Replicas = *deployment.Spec.Replicas
if err := r.Status().Update(ctx, app); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}关键逻辑:
App 资源变更,自动创建 Deployment。App的status字段反馈实际状态。make manifests # 生成 CRD 配置
make install # 部署 CRD
make run # 运行控制器1)检查 CRD 状态:
kubectl get crd apps.example.com -o yaml
kubectl describe app myapp # 查看事件和状态2)控制器日志:
kubectl logs -l control-plane=controller-manager -c manager3)触发扩缩容测试:
修改 myapp.yaml中的replicas字段,观察 Deployment 是否自动调整。
1)Finalizers 机制 防止资源误删,确保删除前执行清理逻辑(如释放外部资源):
app.SetFinalizers([]string{"cleanup.external.com"})通过Finalizers实现优雅删除:
// 在控制器中添加finalizer
func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
app := &appv1.Application{}
if err := r.Get(ctx, req.NamespacedName, app); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 检查删除标记
if app.ObjectMeta.DeletionTimestamp.IsZero() {
if !controllerutil.ContainsFinalizer(app, finalizerName) {
controllerutil.AddFinalizer(app, finalizerName)
if err := r.Update(ctx, app); err != nil {
return ctrl.Result{}, err
}
}
} else {
// 执行清理逻辑
if controllerutil.ContainsFinalizer(app, finalizerName) {
if err := r.cleanupExternalResources(app); err != nil {
return ctrl.Result{}, err
}
controllerutil.RemoveFinalizer(app, finalizerName)
if err := r.Update(ctx, app); err != nil {
return ctrl.Result{}, err
}
}
return ctrl.Result{}, nil
}
// 正常调和逻辑...
}2)多版本支持
支持多版本并存并平滑升级:
versions:
- name: v1beta1
served: true # 提供此版本API
storage: false # 非存储版本
schema: {...}
- name: v1
served: true
storage: true # 唯一存储版本
schema: {...}3)Operator 模式 将 CRD 与控制器打包为 Operator,管理有状态应用(如数据库集群),实现自愈、备份等高级逻辑:
operator-sdk init --domain=example.com
operator-sdk create api --group=app --version=v1 --kind=App4)Python 客户端操作 CRD 使用 kubernetes-client 库动态管理 CRD:
from kubernetes import client, config
config.load_kube_config()
api = client.CustomObjectsApi()
api.create_namespaced_custom_object(group="example.com", version="v1", namespace="default", plural="apps", body=myapp_data)通过OpenAPI v3 Schema可以定义详细的验证规则:
validation:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cpu:
type: string
pattern: '^[0-9]+m?$'
memory:
type: string
pattern: '^[0-9]+(Ei|Pi|Ti|Gi|Mi|Ki)?$'
required: [cpu, memory]spec 描述期望状态,status 记录实际状态,二者分离。开发自定义 CRD 的核心流程为:定义 CRD 结构 → 注册到集群 → 编写控制器逻辑 → 部署控制器。结合 Operator 模式和 Finalizer 等机制,充分释放Kubernetes的扩展潜力。可构建生产级自动化运维能力。CRD作为Kubernetes的核心扩展机制,为平台赋予了近乎无限的扩展能力,CRD设计应当:
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!