Skip to content

Operator 开发流程

1. 定义 CRD(Custom Resource Definition)

  • 理解 CRD 的作用:CRD 是 Kubernetes 中用于定义自定义资源(Custom Resource)的机制。它允许你扩展 Kubernetes API,创建自己特定的资源类型。

  • 定义资源类型:通过 YAML 文件定义资源的 apiVersionkindmetadataspec 等字段,描述资源的字段结构。

    示例

    yaml
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: apps.mycompany.com
    spec:
      group: mycompany.com
      versions:
        - name: v1
          served: true
          storage: true
          schema:
            openAPIV3Schema:
              type: object
              properties:
                spec:
                  type: object
                  properties:
                    replicas:
                      type: integer
                      description: "Number of replicas"
                    image:
                      type: string
                      description: "Application container image"
      names:
        plural: apps
        singular: app
        kind: App
      scope: Namespaced
  • 注册 CRD:将定义好的 CRD 文件应用到 Kubernetes 集群中。

    bash
    kubectl apply -f crd.yaml

2. 使用 Scaffold 或 Kubebuilder 创建控制器骨架

  • 选择工具kubebuilderoperator-sdk 都是创建 Kubernetes Operator 的标准工具。你可以选择一个工具来快速生成项目框架。

  • 初始化 Operator 项目

    bash
    kubebuilder init --domain mycompany.com --repo github.com/myorg/myoperator
  • 创建 API 类型和控制器骨架

    bash
    kubebuilder create api --group mycompany --version v1 --kind App
  • 生成文件结构:通过这些命令会生成一套完整的文件结构,包含 API 和控制器代码。

    • api/v1/app_types.go:定义资源类型的结构体。
    • controllers/app_controller.go:包含控制器逻辑的文件。

3. 定义并实现控制器逻辑(Reconcile)

  • 编写 Reconcile 方法:控制器的核心是 Reconcile 方法,它定期检查自定义资源的当前状态,并采取必要的行动来将资源状态与期望状态对齐。

    示例

    go
    func (r *AppReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
        app := &mycompanyv1.App{}
        if err := r.Get(ctx, req.NamespacedName, app); err != nil {
            log.Error(err, "unable to fetch App")
            return ctrl.Result{}, client.IgnoreNotFound(err)
        }
    
        // 更新或管理相关资源,如创建 Pod
        return ctrl.Result{}, nil
    }
  • 添加业务逻辑:你可以在 Reconcile 方法中编写自己的业务逻辑,例如监控资源的变化,自动调整相关 Pod 数量等。

4. 使用 Webhook 实现数据验证与调整

  • 创建 Webhook:Webhooks 可以在资源创建或更新时进行验证(Validating Webhook)和调整(Mutating Webhook)。

  • 生成 Webhook 骨架

    bash
    kubebuilder create webhook --group mycompany --version v1 --kind App --defaulting --validation
  • 添加默认值设置和验证逻辑

    • Mutating Webhook(默认值设置)

      go
      func (r *App) Default() {
          if r.Spec.Replicas == 0 {
              r.Spec.Replicas = 1
          }
      }
    • Validating Webhook(数据验证)

      go
      func (r *App) ValidateCreate() error {
          if r.Spec.Image == "" {
              return fmt.Errorf("Image field is required")
          }
          return nil
      }

5. 部署控制器和 Webhook

  • 部署控制器:使用 kubectl 部署生成的控制器代码到 Kubernetes 集群中。

    bash
    kubectl apply -f config/default
  • 部署 Webhook:使用 Kubernetes 部署生成的 webhook 配置文件(包括 Mutating 和 Validating Webhook)到集群中。

6. 实现业务逻辑(Pod 资源管理、状态同步等)

  • Pod 管理:你可以在控制器中根据自定义资源的变化创建、更新或删除 Pod。

    示例

    go
    func (r *AppReconciler) reconcilePods(app *mycompanyv1.App) error {
        // 根据 spec.Replicas 来调整 Pod 数量
        // 比如,通过 Deployment 或 StatefulSet 来管理 Pod
        return nil
    }
  • 状态同步:确保资源的 status 字段与当前状态保持一致。

    go
    app.Status.AvailableReplicas = currentReplicas
    err := r.Status().Update(ctx, app)

7. 启用 CRD 版本控制与升级

  • CRD 版本管理:确保 CRD 的版本在不同版本间兼容。在需要对 CRD 进行更改时,注意增加新的版本并进行迁移。

  • 数据迁移:通过控制器的升级,迁移现有资源的数据结构,确保系统平稳升级。

8. 添加 Metrics 和日志

  • 添加 Prometheus Metrics:为了监控控制器的健康状态和性能,你可以为控制器添加 Prometheus metrics。

    示例

    go
    controllerMetrics := promauto.NewCounterVec(prometheus.CounterOpts{
        Name: "operator_reconcile_count",
        Help: "The total number of reconciles",
    }, []string{"controller"})
  • 日志记录:使用 log 来记录控制器的执行状态,便于问题排查。

9. 自动化测试和单元测试

  • 编写单元测试:为控制器逻辑编写单元测试,验证业务逻辑是否按预期运行。

    示例

    go
    func TestReconcile(t *testing.T) {
        // 模拟 App 资源的创建,测试 Reconcile 方法
    }
  • 集成测试:进行集成测试,确保 CRD、控制器、Webhook 在集群中的协同工作。

10. 部署到生产环境

  • 创建 Helm Charts 或 Kustomize 配置:为了方便部署,你可以创建 Helm charts 或 Kustomize 配置,简化生产环境中的部署。

  • 自动化部署:结合 GitOps 或 CI/CD 工具实现自动化部署,确保每次代码变更后,控制器都能自动部署到生产环境。

11. 处理资源的生命周期管理

  • 监听资源变化:确保控制器能够及时监听并处理 CRD 资源的创建、更新和删除事件。

    go
    r.Log.Info("Reconciled resource", "name", req.Name)
  • 删除资源:实现资源删除逻辑,确保相关资源(例如 Pod、Service)在 CRD 被删除时自动清理。

12. 处理并发与性能优化

  • 控制并发:确保控制器能够高效处理多个资源实例,并限制并发执行的数量。

  • 性能优化:对控制器的性能进行分析与优化,例如避免不必要的资源访问,使用缓存等。

13. 版本化与回滚支持

  • 支持多版本:通过 kubebuilder 支持多个 CRD 版本,确保用户可以从旧版本平滑升级到新版本。

  • 回滚支持:如果新版本的控制器有问题,需要确保能够回滚到旧版本。

14. 安全性与 RBAC 配置

  • RBAC 配置:确保为控制器和 Webhook 配置正确的角色权限,限制对资源的访问权限。

    示例

    yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: mynamespace
      name: app-operator
    rules:
      - apiGroups: ["mycompany.com"]
        resources: ["apps"]
        verbs: ["create", "update", "delete"]

15. 优化与监控

  • 监控控制器:集成监控工具(如 Prometheus),监控控制器的健康状况和性能指标。

  • 日志和告警:设置日志系统(如 ELK Stack)进行日志收集,并配置告警机制,确保及时发现问题。