2

我使用 operator-sdk 创建了一个自定义资源DatabaseService。创建DatabaseServiceCR 应触发Reconcile从第三方获取机密后在 CR 命名空间中创建机密的函数。

我将 CR 设置为秘密的所有者,这样每当手动删除秘密时,协调功能就会再次触发并重新创建秘密。

这是代码:

func (r *DatabaseServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    requeueResult := ctrl.Result{Requeue: true, RequeueAfter: time.Minute}
    emptyResult := ctrl.Result{Requeue: false, RequeueAfter: 0}

    ds := &operatorsv1alpha1.DatabaseService{}
    if err := r.Client.Get(context.Background(), req.NamespacedName, ds); err != nil {
        if misc.IsNotFound(err) {
            return emptyResult, nil
        })
        return requeueResult, err
    }

    secret, err := getSecretFromThirdParty(ds)
    if err != nil {
        return requeueResult, err
    }

    if err := controllerutil.SetControllerReference(ds, secret, r.Scheme); err != nil {
        logger.Error("failed to set controller reference for the secret", zap.Error(err))
        return requeueResult, err
    }

    if err := r.createOrUpdateSecret(secret, logger); err != nil {
        return requeueResult, err
    }

    return emptyResult, nil
}

func (r *DatabaseServiceReconciler) createOrUpdateSecret(secret *corev1.Secret) error {
    if err := r.createNamespaceIfNotExist(secret.Namespace, logger); err != nil {
        return err
    }
    if err := r.Client.Create(context.TODO(), secret); err == nil {
        return nil
    }
    if !apierrors.IsAlreadyExists(err) {
        return err
    }
    if err := r.Client.Update(context.TODO(), secret); err != nil {
        return err
    }
    return nil
}

我观察到,如果我在调用之前将 CR 设置为秘密的所有者createOrUpdateSecret- 将再次触发协调功能,因为拥有的对象(秘密)中的某些内容发生了变化。

我的 Reconcile 逻辑是幂等的,所以这不是一个大问题。但是,在从内部对拥有的对象进行更改后,我无需Reconcile再次运行Reconcile。现在,每次 Reconcile 创建/更新秘密时,它都会再次运行。这种行为似乎有点笨拙,并导致操作员的额外工作以及对第三方的额外调用。

有没有办法绕过从内部重新激活 Reconcile 创建/更新拥有的对象Reconcile?还是不建议这样做,我应该允许反复运行协调直到没有任何改变?

4

0 回答 0