ITPub博客

首页 > 应用开发 > Node.js > PropagationPolicy(传播策略)

PropagationPolicy(传播策略)

投稿 Node.js 作者:crucz025 时间:2026-01-28 18:52:33 0 删除 编辑

type PropagationSpec struct { // ResourceSelectors used to select resources. // Nil or empty selector is not allowed and doesn't mean match all kinds // of resources for security concerns that sensitive resources(like Secret) // might be accidentally propagated. // +required // +kubebuilder:validation:MinItems=1 ResourceSelectors []ResourceSelector `json:"resourceSelectors"` // Association tells if relevant resources should be selected automatically. // e.g. a ConfigMap referred by a Deployment.


// default false. // Deprecated: in favor of PropagateDeps. // +optional Association bool `json:"association,omitempty"` // PropagateDeps tells if relevant resources should be propagated automatically. // Take 'Deployment' which referencing 'ConfigMap' and 'Secret' as an example, when 'propagateDeps' is 'true', // the referencing resources could be omitted(for saving config effort) from 'resourceSelectors' as they will be // propagated along with the Deployment. In addition to the propagating process, the referencing resources will be // migrated along with the Deployment in the fail-over scenario. // // Defaults to false. // +optional PropagateDeps bool


`json:"propagateDeps,omitempty"` // Placement represents the rule for select clusters to propagate resources.、

type ResourceSelector struct { // APIVersion represents the API version of the target resources. // +required APIVersion string `json:"apiVersion"` // Kind represents the Kind of the target resources. // +required Kind string `json:"kind"` // Namespace of the target resource. // Default is empty, which means inherit from the parent object scope. // +optional Namespace string `json:"namespace,omitempty"` // Name of the target resource. // Default is empty, which means selecting all resources. // +optional Name string `json:"name,omitempty"` // A label query over a set of resources. // If name is not empty, labelSelector will be ignored.



定义

Placement 包含以下主要字段:

  1. ClusterAffinity: 集群亲和性(首选哪些集群)
  2. ClusterTolerations: 集群容忍度(可以调度到哪些集群)
  3. SpreadConstraints: 分散约束(如何在不同集群间分配)
  4. ReplicaScheduling: 副本调度策略(副本如何分配到集群)

示例:

  • Duplicated: 所有集群都运行相同的副本数(如 ConfigMap、Secret)
  • Divided: 副本按比例分配到不同集群(如 Deployment)

0.3 ResourceBinding(资源绑定)

ResourceBinding(RB) 是 PropagationPolicy 和资源对象的绑定结果。它记录了:

  1. 资源引用: 指向原始资源对象(Deployment、StatefulSet 等)
  2. 副本信息: 从资源中提取的副本数和资源需求
  3. 调度结果: 由 Scheduler 填充的目标集群列表
  4. 策略信息: 从 PropagationPolicy 复制的策略配置



Spec WorkSpec `json:"spec"` // Status represents the status of PropagationStatus. // +optional Status WorkStatus `json:"status,omitempty"` } // WorkSpec defines the desired state of Work. type WorkSpec struct { // Workload represents the manifest workload to be deployed on managed cluster. Workload WorkloadTemplate `json:"workload,omitempty"` // SuspendDispatching controls whether dispatching should //


be suspended, nil means not suspend. // Note: true means stop propagating to the corresponding member cluster, and // does not prevent status collection. // +optional SuspendDispatching *bool `json:"suspendDispatching,omitempty"` // PreserveResourcesOnDeletion controls whether resources should be preserved on the // member cluster when the Work object is deleted. // If set to true, resources will be preserved on the member cluster. // Default is false, which means resources will be deleted along with the Work object. // +optional


// Start initializes the resource interpreter and performs cache synchronization. Start(ctx context.Context) (err error) // HookEnabled tells if any hook exist for specific resource type and operation. HookEnabled(objGVK schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) bool  sytianxing.cn // GetReplicas returns the desired replicas of the object as well as the requirements of each replica. GetReplicas(object *unstructured.Unstructured) (replica int32, replicaRequires *workv1alpha2.ReplicaRequirements, err error) // ReviseReplica revises the replica of the given object.  huome.cn   ReviseReplica(object *unstructured.Unstructured, replica int64) (*unstructured.Unstructured, error) // GetComponents extracts the resource requirements for multiple components from the given object. // This hook is designed for CRDs with multiple components (e.g., FlinkDeployment), but can // also be used for single-component resources like Deployment.


// If implemented, the controller will use this hook to obtain per-component replica and resource // requirements, and will not call GetReplicas. // If not implemented, the controller will fall back to GetReplicas for backward compatibility. // This hook will only be called when the feature gate 'MultiplePodTemplatesScheduling' is enabled. GetComponents(object *unstructured.Unstructured) (components []workv1alpha2.Component, err error) // Retain returns the objects that based on the "desired" object but with values retained from the "observed" object. Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) // AggregateStatus returns the objects that based on the 'object' but with status aggregated. AggregateStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (*unstructured.Unstructured, error)


var hookEnabled bool replica, requires, hookEnabled, err = i.configurableInterpreter.GetReplicas(object) if err != nil { return } if hookEnabled {xmich.cn return } replica, requires, hookEnabled, err = i.customizedInterpreter.GetReplicas(context.TODO(), &request.Attributes{ Operation: configv1alpha1.InterpreterOperationInterpretReplica, Object:    object, }) if err != nil { return } if hookEnabled { return } replica, requires, hookEnabled, err = i.thirdpartyInterpreter.GetReplicas(object) if err != nil {


func (d *ResourceDetector) BuildResourceBinding(object *unstructured.Unstructured, policySpec *policyv1alpha1.PropagationSpec, policyID string, policyMeta metav1.ObjectMeta, claimFunc func(object metav1.Object, policyId string, objectMeta metav1.ObjectMeta)) (*workv1alpha2.ResourceBinding, error) { bindingName := names.GenerateBindingName(object.GetKind(), object.GetName()) propagationBinding   murnis.cn:= &workv1alpha2.ResourceBinding{ ObjectMeta: metav1.ObjectMeta{ Name:      bindingName,



Namespace: object.GetNamespace(), OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(object, object.GroupVersionKind()), }, Finalizers: []string{util.BindingControllerFinalizer}, }, Spec: workv1alpha2.ResourceBindingSpec{ PropagateDeps:               policySpec.PropagateDeps, SchedulerName:          


    policySpec.SchedulerName, Placement:                   &policySpec.Placement, Failover:                    policySpec.Failover, ConflictResolution:          policySpec.ConflictResolution, PreserveResourcesOnDeletion: policySpec.PreserveResourcesOnDeletion, Resource: workv1alpha2.ObjectReference{ APIVersion:      object.GetAPIVersion(), Kind:            object.GetKind(), Namespace:       object.GetNamespace(), Name:            object.GetName(), UID:             object.GetUID(),



ResourceVersion: object.GetResourceVersion(), yqfh.cn }, }, } if policySpec.Suspension != nil { propagationBinding.Spec.Suspension = &workv1alpha2.Suspension{Suspension: *policySpec.Suspension} } claimFunc(propagationBinding, policyID, policyMeta) if err := d.applyReplicaInterpretation(object, &propagationBinding.Spec); err != nil { yqfh.cn return nil, err } if features.FeatureGate.Enabled(features.PriorityBasedScheduling) && policySpec.SchedulePriority != nil { // ... 处理调度优先级


func (d *ResourceDetector) applyReplicaInterpretation(object *unstructured.Unstructured, spec *workv1alpha2.ResourceBindingSpec) error { gvk := object.GroupVersionKind() name := object.GetName() // Prioritize component interpretation if the feature and GetComponents are enabled. if features.FeatureGate.Enabled(features.MultiplePodTemplatesScheduling) && d.ResourceInterpreter.HookEnabled(gvk, configv1alpha1.InterpreterOperationInterpretComponent) { components, err := d.ResourceInterpreter.GetComponents(object) yqfh.cn if err != nil { klog.Errorf("Failed to get components for %s(%s): %v", gvk, name, err)



return err } spec.Components = components return nil } // GetReplicas is executed if the MultiplePodTemplatesScheduling feature gate is disabled, or if GetComponents is not implemented. if d.ResourceInterpreter.HookEnabled(gvk, configv1alpha1.InterpreterOperationInterpretReplica) { replicas, replicaRequirements, err := d.ResourceInterpreter.GetReplicas(object) if err != nil { klog.Errorf("Failed to customize replicas for %s(%s): %v", gvk, name, err)


binding, err := d.BuildResourceBinding(object, &policy.Spec, policyID, policy.ObjectMeta, AddPPClaimMetadata) if err != nil { klog.Errorf("Failed to build resourceBinding for object: %s. error: %v", objectKey, err) return err } bindingCopy := binding.DeepCopy() err = retry.RetryOnConflict(retry.DefaultRetry, func() (err error) { operationResult, err = controllerutil.CreateOrUpdate(context.TODO(), d.Client, bindingCopy, func() error { // If this binding exists and its owner is not the input object, return error and let garbage collector // delete this binding and try again later. See https://github.com/karmada-io/karmada/issues/2090. if ownerRef := metav1.GetControllerOfNoCopy(bindingCopy); ownerRef != nil && ownerRef.UID != object.GetUID() { return fmt.Errorf("failed to update binding due to different owner reference UID, will " +


"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090") xmich.cn } // Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists. bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations) bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels) bindingCopy.OwnerReferences = binding.OwnerReferences czjzz.com bindingCopy.Spec.Placement = binding.Spec.Placement bindingCopy.Spec.Resource = binding.Spec.Resource bindingCopy.Spec.ConflictResolution = binding.Spec.ConflictResolution  xmich.cn if binding.Spec.Suspension != nil { if bindingCopy.Spec.Suspension == nil { bindingCopy.Spec.Suspension = &workv1alpha2.Suspension{} } bindingCopy.Spec.Suspension.Suspension = binding.Spec.Suspension.Suspension }

murnis.cn  

if err := c.removeOrphanWorks(ctx, binding); err != nil { return controllerruntime.Result{}, err } needWaitForCleanup, err := c.checkDirectPurgeOrphanWorks(ctx, binding) if err != nil { return controllerruntime.Result{}, err } psnsd.com   if needWaitForCleanup { msg := fmt.Sprintf("There are works in clusters with PurgeMode 'Directly' not deleted for ResourceBinding(%s/%s), skip syncing works", binding.Namespace, binding.Name)huome.cn klog.V(4).InfoS(msg, "namespace", binding.GetNamespace(), "binding", binding.GetName()) return controllerruntime.Result{RequeueAfter: requeueIntervalForDirectlyPurge}, nil } workload, err := helper.FetchResourceTemplate(ctx, c.DynamicClient, c.InformerManager, c.RESTMapper, binding.Spec.Resource) if err != nil { if apierrors.IsNotFound(err) {



// It might happen when the resource template has been removed but the garbage collector hasn't removed // the ResourceBinding which dependent on resource template. // So, just return without retry(requeue) would save unnecessary loop. return controllerruntime.Result{}, nil } klog.ErrorS(err, "Failed to fetch workload for ResourceBinding", "namespace", binding.GetNamespace(), "binding", binding.GetName()) return controllerruntime.Result{}, err } start := time.Now() err = ensureWork(ctx, c.Client, c.ResourceInterpreter, workload, c.OverrideManager, binding, apiextensionsv1.NamespaceScoped) metrics.ObserveSyncWorkLatency(err, start) if err != nil { klog.ErrorS(err, "Failed to transform ResourceBinding to works", "namespace", binding.GetNamespace(), "binding", binding.GetName()) bakmk.com   c.EventRecorder.Event(binding, corev1.EventTypeWarning, events.EventReasonSyncWorkFailed, err.Error()) c.EventRecorder.Event(workload, corev1.EventTypeWarning, events.EventReasonSyncWorkFailed, err.Error()) return controllerruntime.Result{}, err





来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048956/viewspace-3109303/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-28

  • 博文量
    15
  • 访问量
    13025