K8s Operator 开发¶
一句话概述:Operator 是 K8s 的扩展机制,把运维知识编码成软件,用自定义控制器自动管理复杂应用的生命周期(安装、升级、备份、恢复等),相当于给 K8s 写一个"智能管理员"。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| Operator | 操作员 = 自动化管理应用的控制器程序 |
| CRD | 自定义资源定义 = 给 K8s 添加新的资源类型 |
| CR | 自定义资源 = CRD 的实例(如"一个 MySQL 集群") |
| Controller | 控制器 = 持续监听资源变化并执行操作的程序 |
| Reconcile | 调和 = 让实际状态趋向期望状态的过程 |
| Operator SDK | Red Hat 的 Operator 开发框架 |
| Kubebuilder | Kubernetes 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 refused | Webhook 未运行 | 确保 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 年