Skip to content

Finalizer 终结器

什么是 Finalizer

Finalizer 是对象元数据中的字符串列表,用于在对象删除前执行清理逻辑。当对象有 Finalizer 时,删除操作只会设置 deletionTimestamp,不会真正删除,直到所有 Finalizer 被移除。

使用场景

  • 删除 CR 前清理外部资源(云存储、数据库记录)
  • 确保子资源被正确清理
  • 防止误删除

实现示例

go
const myFinalizer = "apps.mycompany.io/finalizer"

func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    myApp := &appsv1alpha1.MyApp{}
    if err := r.Get(ctx, req.NamespacedName, myApp); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // 处理删除
    if !myApp.DeletionTimestamp.IsZero() {
        if controllerutil.ContainsFinalizer(myApp, myFinalizer) {
            // 执行清理逻辑
            if err := r.cleanupExternalResources(ctx, myApp); err != nil {
                return ctrl.Result{}, err
            }
            // 移除 Finalizer,允许删除
            controllerutil.RemoveFinalizer(myApp, myFinalizer)
            if err := r.Update(ctx, myApp); err != nil {
                return ctrl.Result{}, err
            }
        }
        return ctrl.Result{}, nil
    }

    // 添加 Finalizer
    if !controllerutil.ContainsFinalizer(myApp, myFinalizer) {
        controllerutil.AddFinalizer(myApp, myFinalizer)
        if err := r.Update(ctx, myApp); err != nil {
            return ctrl.Result{}, err
        }
    }

    // 正常 Reconcile 逻辑...
    return ctrl.Result{}, nil
}

func (r *MyAppReconciler) cleanupExternalResources(ctx context.Context, myApp *appsv1alpha1.MyApp) error {
    // 清理 S3 存储桶
    // 清理数据库记录
    // 注销服务注册
    log.FromContext(ctx).Info("清理外部资源", "name", myApp.Name)
    return nil
}

注意事项

bash
# 如果 Finalizer 逻辑卡住,对象会一直处于 Terminating 状态
# 强制删除(移除 Finalizer)
kubectl patch myapp my-app -p '{"metadata":{"finalizers":[]}}' --type=merge

# 查看对象的 Finalizer
kubectl get myapp my-app -o jsonpath='{.metadata.finalizers}'

本站内容由 褚成志 整理编写,仅供学习参考