当前位置: 首页 > news >正文

Kubernetes CRD 开发实践指南

Kubernetes CRD 开发实践指南

引言

自定义资源定义(CRD)是 Kubernetes 扩展能力的核心机制,允许用户定义自己的资源类型。本文将深入探讨 CRD 的开发流程、最佳实践和常见模式。

一、CRD 架构概述

1.1 CRD 层次结构

┌─────────────────────────────────────────────────────────────┐ │ CRD 架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ API Server │ │ │ │ - CRD 注册与验证 │ │ │ │ - REST API 端点生成 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ CRD 资源 │ │ │ │ - CustomResourceDefinition │ │ │ │ - CustomResource │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Controller │ │ │ │ - Reconcile Loop │ │ │ │ - 状态同步 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 底层资源 │ │ │ │ - Deployment/Pod/Service │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

1.2 CRD 定义结构

组件描述作用
GroupAPI 组名组织相关资源
VersionAPI 版本版本管理
Scope作用域Namespaced/Cluster
Names命名规则Kind/ListKind/Plural/Singular
Schema字段定义验证和默认值

二、CRD 定义

2.1 基础 CRD 定义

apiVersion: crd.k8s.io/v1 kind: CustomResourceDefinition metadata: name: databases.example.com spec: group: example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: version: type: string replicas: type: integer minimum: 1 maximum: 10 storage: type: string backup: type: object properties: enabled: type: boolean schedule: type: string required: - version - replicas scope: Namespaced names: plural: databases singular: database kind: Database shortNames: - db

2.2 CRD 版本管理

apiVersion: crd.k8s.io/v1 kind: CustomResourceDefinition metadata: name: databases.example.com spec: group: example.com versions: - name: v1alpha1 served: true storage: false schema: openAPIV3Schema: type: object properties: spec: type: object properties: version: type: string - name: v1beta1 served: true storage: false schema: openAPIV3Schema: type: object properties: spec: type: object properties: version: type: string replicas: type: integer - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: version: type: string replicas: type: integer storage: type: string

2.3 CRD 子资源配置

apiVersion: crd.k8s.io/v1 kind: CustomResourceDefinition metadata: name: databases.example.com spec: group: example.com versions: - name: v1 served: true storage: true subresources: status: {} scale: specReplicasPath: .spec.replicas statusReplicasPath: .status.replicas labelSelectorPath: .status.selector schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer status: type: object properties: replicas: type: integer nullable: true selector: type: string nullable: true

三、自定义资源使用

3.1 创建自定义资源

apiVersion: example.com/v1 kind: Database metadata: name: my-postgres namespace: default spec: version: "14.0" replicas: 3 storage: "100Gi" backup: enabled: true schedule: "0 2 * * *"

3.2 查看自定义资源

# 查看所有 Database 资源 kubectl get databases # 查看特定资源 kubectl get database my-postgres # 查看详细信息 kubectl describe database my-postgres # 输出 YAML 格式 kubectl get database my-postgres -o yaml

四、Controller 开发

4.1 Controller 结构

package main import ( "context" "time" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" examplev1 "example.com/api/v1" ) type DatabaseReconciler struct { client.Client Scheme *runtime.Scheme Log logr.Logger } func (r *DatabaseReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { log := log.FromContext(ctx) var db examplev1.Database if err := r.Get(ctx, req.NamespacedName, &db); err != nil { return reconcile.Result{}, client.IgnoreNotFound(err) } log.Info("Reconciling Database", "name", db.Name) // 业务逻辑处理 if err := r.reconcileDeployment(ctx, &db); err != nil { return reconcile.Result{}, err } if err := r.reconcileService(ctx, &db); err != nil { return reconcile.Result{}, err } if err := r.updateStatus(ctx, &db); err != nil { return reconcile.Result{}, err } return reconcile.Result{RequeueAfter: time.Minute * 5}, nil } func main() { mgr, err := manager.New(cfg, manager.Options{}) if err != nil { log.Error(err, "Unable to start manager") os.Exit(1) } if err := (&DatabaseReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), Log: log.Log.WithName("controllers").WithName("Database"), }).SetupWithManager(mgr); err != nil { log.Error(err, "Unable to create controller", "controller", "Database") os.Exit(1) } if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { log.Error(err, "Manager exited non-zero") os.Exit(1) } }

4.2 Reconcile 逻辑

func (r *DatabaseReconciler) reconcileDeployment(ctx context.Context, db *examplev1.Database) error { // 检查 Deployment 是否存在 var deploy appsv1.Deployment deployName := db.Name if err := r.Get(ctx, client.ObjectKey{Namespace: db.Namespace, Name: deployName}, &deploy); err != nil { if client.IgnoreNotFound(err) != nil { return err } // 创建 Deployment deploy = *newDeployment(db) if err := r.Create(ctx, &deploy); err != nil { return err } return nil } // 更新 Deployment if !reflect.DeepEqual(deploy.Spec.Replicas, &db.Spec.Replicas) { deploy.Spec.Replicas = &db.Spec.Replicas if err := r.Update(ctx, &deploy); err != nil { return err } } return nil }

五、CRD 最佳实践

5.1 版本化策略

versions: - name: v1alpha1 served: true storage: false - name: v1beta1 served: true storage: false - name: v1 served: true storage: true

5.2 状态管理

subresources: status: {}
func (r *DatabaseReconciler) updateStatus(ctx context.Context, db *examplev1.Database) error { db.Status.ReadyReplicas = 3 db.Status.Phase = "Ready" if err := r.Status().Update(ctx, db); err != nil { return err } return nil }

5.3 验证与默认值

schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer minimum: 1 maximum: 10 default: 1 version: type: string enum: - "12.0" - "13.0" - "14.0" default: "14.0"

六、CRD 部署

6.1 RBAC 配置

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: database-manager rules: - apiGroups: ["example.com"] resources: ["databases", "databases/status"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: [""] resources: ["services"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: database-manager roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: database-manager subjects: - kind: ServiceAccount name: database-controller namespace: default

6.2 Controller 部署

apiVersion: apps/v1 kind: Deployment metadata: name: database-controller spec: replicas: 1 selector: matchLabels: app: database-controller template: metadata: labels: app: database-controller spec: serviceAccountName: database-controller containers: - name: controller image: my-registry/database-controller:latest args: - --metrics-addr=:8080 - --enable-leader-election resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mi

七、常见问题与解决方案

7.1 CRD 创建失败

问题分析:

  • Schema 定义错误
  • 版本配置错误
  • 命名冲突

解决方案:

# 检查 CRD 状态 kubectl get crd databases.example.com -o yaml # 查看事件 kubectl describe crd databases.example.com

7.2 Controller 无法获取资源

问题分析:

  • RBAC 权限不足
  • 资源未正确注册
  • 缓存未同步

解决方案:

# 检查 ServiceAccount 权限 kubectl auth can-i get databases --as=system:serviceaccount:default:database-controller

7.3 状态更新失败

问题分析:

  • 未配置 subresources.status
  • 更新策略错误
  • 并发冲突

解决方案:

subresources: status: {}
// 使用 Status().Update if err := r.Status().Update(ctx, db); err != nil { if apierrors.IsConflict(err) { return reconcile.Result{Requeue: true}, nil } return err }

结论

CRD 是 Kubernetes 扩展能力的核心机制,通过定义自定义资源和开发 Controller,可以将复杂业务逻辑封装为 Kubernetes 原生资源。遵循版本化、状态管理、验证等最佳实践,可以构建稳定、可维护的 CRD 解决方案。

http://www.jsqmd.com/news/826151/

相关文章:

  • GEE python:获取影像的信息和两景NDVI影像差异和影像方差
  • Kubernetes服务网格深度解析
  • Piral未来路线图:微前端技术的演进方向与发展趋势
  • 量子物理到底是啥?原理、核心概念与经典实验全面解析
  • lodash-webpack-plugin插件
  • 别再死记硬背了!用Python实战搞定贾俊平《统计学》第四章核心考点(附代码与数据)
  • 开源法律知识库:结构化数据驱动法律科技应用
  • Python-ADB安全认证详解:从RSA密钥到设备授权的最佳实践
  • WebStorm模板通配符
  • 别再只跑回归了!用Stata做异方差检验与修正的完整工作流(含稳健标准误)
  • 拆解MC1496乘法器:如何在没有现成库的Multisim里,手动封装一个调幅核心模块
  • AI编码助手:从架构设计到工程实践,打造你的智能开发副驾驶
  • AI智能体技能库:构建可复用、标准化与安全的应用能力模块
  • Web前端之指定元素优先列布局的实现原理、使用数据驱动实现Grid布局、Grid首列锚定算法
  • AI提示词工程化:从GitHub项目到团队协作的工程实践
  • Arm SystemReady ACS测试指南与硬件兼容性认证
  • sagents框架实战:从零构建具备记忆与协作能力的AI智能体
  • 儒卓力CITE首秀:技术分销如何赋能嵌入式、汽车电子与物联网创新
  • Adv_Fin_ML_Exercises特征重要性分析:5种方法对比
  • GEE python:影像的一元线性趋势性分析linearfit函数
  • Blender FLIP Fluids渲染与合成:打造电影级液体效果的10个关键技术要点
  • Kubernetes监控与可观测性最佳实践
  • Simplefolio最佳实践案例:10个成功的开发者作品集展示
  • 构建AI智能体调度平台:从微服务架构到工程实践
  • VTK开发精要:数据与管线机制
  • Cursor AI代码优化工具:自动检测与重构冗余API调用
  • Coding Agent 正在偷走你的控制权?慢下来,守住开发者的核心地位!
  • Augustus核心功能深度解析:路障、劳动力池与仓库管理
  • Jdbc手动实现事务管理
  • 深入PEX8796:从Serdes到Virtual Switch,图解PCIe交换芯片的三种工作模式