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}'