观看未“拥有“的辅助资源

在某些情况下,控制器可能需要监视并响应它并不“拥有“的资源的变化,这意味着这些资源是由另一个控制器创建和管理的。

以下示例演示了控制器如何监控和对账它不直接管理的资源。这适用于任何不是由控制器“拥有“的资源,包括由其他控制器或项目管理的核心类型自定义资源,并在单独的流程中进行对账。

例如,考虑两个自定义资源——BusyboxBackupBusybox。如果对 Busybox 的更改应该触发 BackupBusybox 控制器的调整,我们可以配置 BackupBusybox 控制器来监视 Busybox 的更新。

示例:监视未拥有的 Busybox 资源以重新调整 BackupBusybox

考虑一个控制器,它管理一个自定义资源 BackupBusybox,同时需要监控整个集群中 Busybox 资源的变化。我们只希望在 Busybox 实例启用备份功能时触发对其的调整。

  • 为什么观看二次资源?
    • BackupBusybox 控制器并不负责创建或拥有 Busybox 资源,但这些资源的变化(例如更新或删除)会直接影响主要资源(BackupBusybox)。
    • 通过监视具有特定标签的 Busybox 实例,控制器确保只有相关资源触发必要的操作(例如备份)。

配置示例

以下是如何配置 BackupBusyboxReconciler 以监视 Busybox 资源的更改并触发 BackupBusybox 的对账:

// SetupWithManager 用于设置控制器与管理器。
// 控制器将监视 BackupBusybox 主要资源和 Busybox 资源。func (r *BackupBusyboxReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&examplecomv1alpha1.BackupBusybox{}).  // 观察主要资源(BackupBusybox)
        Watches(
            &source.Kind{Type: &examplecomv1alpha1.Busybox{}},  // 观察 Busybox CR
            handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
                // 在同一命名空间中触发 BackupBusybox 的同步                return []reconcile.Request{
                    {
                        NamespacedName: types.NamespacedName{
                            Name:      "backupbusybox",  // 对关联的 BackupBusybox 资源进行调整
                            Namespace: obj.GetNamespace(),  // 使用已更改的 Busybox 命名空间
                        },
                    },
                }
            }),
        ).  // 当 Busybox 资源发生变化时触发调整。        Complete(r)
}

以下是我们如何配置控制器,以仅过滤和监视具有特定标签的 Busybox 资源的变化:

// SetupWithManager 用于将控制器与管理器进行设置。
// 控制器将监视 BackupBusybox 主要资源和 Busybox 资源,并按标签进行过滤。func (r *BackupBusyboxReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&examplecomv1alpha1.BackupBusybox{}).  // 观察主要资源(BackupBusybox)
        Watches(
            &source.Kind{Type: &examplecomv1alpha1.Busybox{}},  // 观察 Busybox CR
            handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
                // 检查 Busybox 资源是否有标签 'backup-needed: "true"'                 if val, ok := obj.GetLabels()["backup-enable"]; ok && val == "true" {
                    // 如果标签存在并设置为"true",则触发 BackupBusybox 的对账                    return []reconcile.Request{
                        {
                            NamespacedName: types.NamespacedName{
                                Name:      "backupbusybox",  // 对关联的 BackupBusybox 资源进行调整
                                Namespace: obj.GetNamespace(),  // 使用已更改的 Busybox 命名空间
                            },
                        },
                    }
                }
                // 如果标签不存在或不匹配,则不触发和解                return []reconcile.Request{}
            }),
        ).  // 当标记的 Busybox 资源发生变化时触发重对账        Complete(r)
}