跳转至

K8s Operator 开发

一句话概述:Operator 是 K8s 的扩展机制,把运维知识编码成软件,用自定义控制器自动管理复杂应用的生命周期(安装、升级、备份、恢复等),相当于给 K8s 写一个"智能管理员"。

核心知识点

概念白话解释
Operator操作员 = 自动化管理应用的控制器程序
CRD自定义资源定义 = 给 K8s 添加新的资源类型
CR自定义资源 = CRD 的实例(如"一个 MySQL 集群")
Controller控制器 = 持续监听资源变化并执行操作的程序
Reconcile调和 = 让实际状态趋向期望状态的过程
Operator SDKRed Hat 的 Operator 开发框架
KubebuilderKubernetes SIG 的 Operator 开发框架

安装配置

# === 安装 Operator SDK ===
# macOS
brew install operator-sdk

# Linux
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; esac)
export OS=$(uname | awk '{print tolower($0)}')
curl -LO "https://github.com/operator-framework/operator-sdk/releases/latest/download/operator-sdk_${OS}_${ARCH}"
chmod +x operator-sdk_${OS}_${ARCH} && sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk

# === 安装 Kubebuilder(替代方案) ===
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder && sudo mv kubebuilder /usr/local/bin/

# 验证
operator-sdk version

基本使用(Operator SDK + Go)

1. 创建项目

mkdir memcached-operator && cd memcached-operator
operator-sdk init --domain example.com --repo github.com/example/memcached-operator
# 初始化项目(domain 用于 CRD 的 API Group)

# 创建 API(CRD + Controller)
operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller
# 创建 Memcached 资源的 CRD 和控制器

2. 定义 CRD 类型

// api/v1alpha1/memcached_types.go
package v1alpha1

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

// MemcachedSpec 定义期望状态(用户填写的配置)
type MemcachedSpec struct {
    Size int32 `json:"size"` // Pod 副本数
    // +optional
    Image string `json:"image,omitempty"` // 镜像(可选)
}

// MemcachedStatus 定义实际状态(控制器更新的状态)
type MemcachedStatus struct {
    Nodes []string `json:"nodes"` // 当前运行的 Pod 名列表
    Ready bool     `json:"ready"` // 是否就绪
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Size",type=integer,JSONPath=`.spec.size`
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
type Memcached struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec   MemcachedSpec   `json:"spec,omitempty"`
    Status MemcachedStatus `json:"status,omitempty"`
}

3. 编写控制器逻辑

// controllers/memcached_controller.go
func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    log := log.FromContext(ctx) // 获取日志器

    // 1. 获取 Memcached CR
    memcached := &cachev1alpha1.Memcached{}
    err := r.Get(ctx, req.NamespacedName, memcached)
    if err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err) // 资源被删了就忽略
    }

    // 2. 检查 Deployment 是否存在
    found := &appsv1.Deployment{}
    err = r.Get(ctx, types.NamespacedName{
        Name: memcached.Name, Namespace: memcached.Namespace,
    }, found)

    if err != nil && errors.IsNotFound(err) {
        // 3. 不存在则创建 Deployment
        dep := r.deploymentForMemcached(memcached)
        log.Info("Creating Deployment", "name", dep.Name)
        if err = r.Create(ctx, dep); err != nil {
            return ctrl.Result{}, err
        }
        return ctrl.Result{Requeue: true}, nil // 重新入队,下次继续检查
    }

    // 4. 检查副本数是否正确
    size := memcached.Spec.Size
    if *found.Spec.Replicas != size {
        found.Spec.Replicas = &size
        if err = r.Update(ctx, found); err != nil {
            return ctrl.Result{}, err
        }
    }

    // 5. 更新状态
    podList := &corev1.PodList{}
    r.List(ctx, podList, client.InNamespace(req.Namespace),
        client.MatchingLabels{"app": memcached.Name})
    podNames := []string{}
    for _, pod := range podList.Items {
        podNames = append(podNames, pod.Name)
    }
    memcached.Status.Nodes = podNames
    memcached.Status.Ready = len(podNames) == int(size)
    r.Status().Update(ctx, memcached)

    return ctrl.Result{}, nil // 调和完成
}

4. 部署和使用

# 生成 CRD YAML
make manifests

# 安装 CRD 到集群
make install

# 本地运行 Operator(开发测试)
make run

# 创建 CR 实例
kubectl apply -f - <<EOF
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: my-memcached
spec:
  size: 3
  image: memcached:1.6
EOF

# 查看自定义资源
kubectl get memcached
kubectl describe memcached my-memcached

# 构建并推送 Operator 镜像
make docker-build docker-push IMG=example.com/memcached-operator:v0.1.0

# 部署到集群
make deploy IMG=example.com/memcached-operator:v0.1.0

高级用法

Webhook 验证

// 为 CRD 添加验证 Webhook
// +kubebuilder:webhook:path=/validate-cache-v1alpha1-memcached,mutating=false,failurePolicy=fail,groups=cache.example.com,resources=memcacheds,verbs=create;update,versions=v1alpha1,name=vmemcached.kb.io

func (r *Memcached) ValidateCreate() (admission.Warnings, error) {
    if r.Spec.Size < 1 || r.Spec.Size > 10 {
        return nil, fmt.Errorf("size must be between 1 and 10") // 验证副本数范围
    }
    return nil, nil
}

常见报错

报错信息原因解决方法
no matches for kind "Memcached"CRD 未安装make install 安装 CRD
controller-runtime error控制器代码错误检查 Reconcile 逻辑
RBAC: access denied权限不足检查 config/rbac/ 下的角色配置
webhook connection refusedWebhook 未运行确保 cert-manager 已安装

速查表

# === Operator SDK 命令 ===
operator-sdk init --domain x --repo y   # 初始化项目
operator-sdk create api --group g --version v --kind K  # 创建 API
make manifests     # 生成 CRD/RBAC YAML
make install       # 安装 CRD 到集群
make run           # 本地运行 Operator
make deploy IMG=x  # 部署到集群
make undeploy      # 从集群卸载

# === Operator 成熟度模型 ===
# Level 1: 基本安装(自动部署应用)
# Level 2: 无缝升级(自动升级应用版本)
# Level 3: 全生命周期(备份、恢复)
# Level 4: 深度洞察(监控、指标、告警)
# Level 5: 自动驾驶(自动调优、自动修复)

# === 何时需要 Operator ===
# 需要:有状态应用、复杂运维逻辑、多步骤工作流
# 不需要:无状态应用用 Deployment 就够了

参考:Operator SDK 文档 | Kubebuilder 文档 | 更新于 2026 年