Propagation Policy
The PropagationPolicy and ClusterPropagationPolicy APIs are provided to propagate resources to member clusters. For the differences between the two APIs, please see here.
This guide describes the configuration options of PropagationPolicy by explaining each field in the API specification. ClusterPropagationPolicy shares the same spec structure, so the examples apply to both.
ResourceSelectors
The resourceSelectors field specifies which resources should be propagated. At least one selector must be defined.
A ResourceSelector matches resources by API version and Kind, and can optionally narrow by name, labels, and namespace. If neither name nor labelSelector is set, it matches all resources of the given APIVersion/Kind in the effective namespace (defaults to the policy's namespace).
Matching all resources in the policy namespace
If name and labelSelector are omitted, the selector matches all resources of the specified APIVersion/Kind in the effective namespace (policy namespace by default):
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: all-deployments
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
clusterNames:
- member1
- member2
This matches all Deployments in the policy namespace.
For ClusterPropagationPolicy, the same selector matches Deployments in all namespaces.
Matching by name
Match a specific resource by name:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
This matches only the Deployment named nginx in the policy namespace.
Matching by label
Match resources by label selector:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: app-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
labelSelector:
matchLabels:
app: nginx
placement:
clusterAffinity:
clusterNames:
- member1
This matches Deployments with label app=nginx in the policy namespace.
PropagateDeps
The propagateDeps field controls whether dependent resources should be automatically propagated.
When enabled, resources referenced by the propagated workload (e.g., ConfigMaps and Secrets referenced by a Deployment) will be propagated automatically without needing to list them in resourceSelectors.
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
namespace: default
name: nginx
propagateDeps: true
placement:
clusterAffinity:
clusterNames:
- member1
This propagates the nginx Deployment and its referenced dependencies to member1.
Placement
The placement field specifies how resources should be distributed across clusters. It includes cluster affinity, spread constraints, and replica scheduling strategies.
Cluster Affinity
.spec.placement.clusterAffinity field represents scheduling restrictions that limit which clusters can be selected. If not specified, any cluster can be a scheduling candidate.
ClusterAffinity supports four filtering mechanisms:
- LabelSelector: Filter clusters by labels
- FieldSelector: Filter clusters by fields (provider, region, zone)
- ClusterNames: Explicitly list cluster names
- ExcludeClusters: Explicitly exclude cluster names
When multiple filtering mechanisms are specified, they are combined with logical AND, meaning a cluster must match all specified conditions to be selected.
clusterAffinity defines a candidate set of clusters—it specifies which clusters are eligible for selection, but does not guarantee they will all be selected. The scheduler selects from this candidate set based on various factors such as scheduling strategies, cluster health, and resource availability. To strictly control how many clusters are selected, use spreadConstraints in combination with clusterAffinity.
For example, if you specify 10 clusters in clusterNames but want to ensure only 2 are actually selected, combine it with spreadConstraints using spreadByField: cluster with maxGroups: 2, minGroups: 2.
LabelSelector
LabelSelector is a filter to select member clusters by labels. It uses *metav1.LabelSelector type. If it is non-nil and non-empty, it filters the candidate set to include only clusters matching this filter.
PropagationPolicy can be configured as follows:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
labelSelector:
matchLabels:
location: us
This creates a candidate set of clusters labeled location=us.
PropagationPolicy can also be configured as follows:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
labelSelector:
matchExpressions:
- key: location
operator: In
values:
- us
This filters the candidate set to clusters whose location label is in us using a set-based selector.
For a description of matchLabels and matchExpressions, you can refer to Resources that support set-based requirements.
FieldSelector
FieldSelector is a filter to select member clusters by fields. If it is non-nil and non-empty, it filters the candidate set to include only clusters matching this filter.
PropagationPolicy can be configured as follows:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
fieldSelector:
matchExpressions:
- key: provider
operator: In
values:
- aws
- key: region
operator: NotIn
values:
- us-west-1
This defines a candidate set of clusters from provider aws while excluding those in region us-west-1.
If multiple matchExpressions are specified in the fieldSelector, the cluster must match all matchExpressions.
The key in matchExpressions now supports three values: provider, region, and zone, which correspond to the .spec.provider, .spec.region, and .spec.zone fields of the Cluster object, respectively.
The operator in matchExpressions now supports In and NotIn.
ClusterNames
Users can set the ClusterNames field to specify the selected clusters.
PropagationPolicy can be configured as follows:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
clusterNames:
- member1
- member2
This restricts the candidate set to member1 and member2.
ExcludeClusters
Explicitly exclude clusters from being selected:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinity:
exclude:
- member1
- member3
This excludes member1 and member3 from the candidate set.
ClusterAffinities (Multiple Cluster Groups)
The clusterAffinities field allows defining multiple cluster groups with fallback behavior. clusterAffinity defines one set of selection criteria applied together to produce a single candidate set of clusters. clusterAffinities defines multiple ordered sets of criteria (groups) that are evaluated sequentially: the scheduler tries the first group and falls back to the next only if the previous cannot satisfy scheduling.
clusterAffinities cannot co-exist with clusterAffinity.
How it works
The scheduler evaluates affinity groups in order:
- Try to schedule using the first group
- If the first group doesn't satisfy scheduling restrictions, try the next group
- A cluster can belong to multiple groups
- If no group satisfies the restrictions, scheduling fails
ClusterAffinityTerm
Each group in clusterAffinities is defined by a ClusterAffinityTerm, which includes:
affinityName: a human-readable name for the cluster group- Inline
ClusterAffinityfields such aslabelSelector,fieldSelector,clusterNames, andexclude: these define the primary cluster group for the term overflowAffinities(optional): additional ordered cluster groups that can be used only after the primary group in the same term can no longer accommodate scheduling
With overflowAffinities, you can implement overflow scenarios, such as preferring scheduling to IDC clusters and overflowing to cloud clusters when IDC resources are insufficient.
Because overflow scheduling needs to be aware of member clusters' available resources, Duplicated scheduling and static weight division are currently not supported with overflow scheduling.
How overflowAffinities works

The scheduler evaluates primary group and overflow groups in order:
- Try to assign replicas to the primary cluster group as much as possible.
- If the primary group cannot accommodate all replicas, attempts to assign the remaining replicas to the overflow groups.
- For each overflow group, the number of replicas assigned is the lesser of the remaining unassigned replicas and the group's total available capacity.
- Within each group, replicas are distributed across clusters according to the
placement.replicaSchedulingstrategy. - Scheduling succeeds once all replicas are assigned. If any replicas remain unassigned after evaluating all groups, scheduling fails with this
ClusterAffinityTerm. The scheduler then moves on to evaluate the nextClusterAffinityTerminclusterAffinities, if any.
Use case 1: Local clusters as primary, cloud clusters as backup
The private clusters in the local data center could be the main group, and the managed clusters provided by cluster providers could be the secondary group. The scheduler would prefer scheduling to the main group and only consider the second group if the main group lacks resources.
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinities:
- affinityName: local-clusters
clusterNames:
- local-member1
- local-member2
- affinityName: cloud-clusters
clusterNames:
- public-cloud-member1
- public-cloud-member2
This prefers local clusters first and falls back to the cloud group if they cannot satisfy scheduling.
Use case 2: Disaster recovery (primary and backup clusters)
Clusters are organized into primary and backup groups. Workloads are scheduled to primary clusters first, and migrate to backup clusters if primary clusters fail.
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: test-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinities:
- affinityName: primary-clusters
clusterNames:
- member1
- member2
- affinityName: backup-clusters
clusterNames:
- member3
- member4
This tries primary clusters first and then moves workloads to the backup group if primaries fail.
Use case 3: Overflow from IDC GPU clusters to cloud GPU clusters
The IDC GPU cluster could be the primary group for running GPU-based inference workloads, and the cloud GPU clusters could be the overflow group for handling extra peak traffic. The scheduler would fill replicas into the IDC cluster first and only overflow the remaining replicas to cloud clusters when the IDC cluster cannot accommodate all replicas.
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: gpu-inference-overflow
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterAffinities:
- affinityName: idc-gpu
clusterNames:
- idc-gpu-cluster1
overflowAffinities:
- affinityName: cloud-gpu
clusterNames:
- cloud-gpu-cluster1
- cloud-gpu-cluster2
replicaScheduling:
replicaSchedulingType: Divided
replicaDivisionPreference: Weighted
weightPreference:
dynamicWeight: AvailableReplicas
This prefers the IDC GPU cluster first and overflows to cloud GPU clusters only when the IDC cluster cannot accommodate all replicas. When traffic decreases, replicas are reclaimed from the cloud GPU clusters first, keeping GPU usage cost-efficient.
ClusterTolerations
The .spec.placement.clusterTolerations field represents cluster tolerations. Like Kubernetes, tolerations work in conjunction with taints on clusters.
After setting one or more taints on a cluster, workloads cannot be scheduled to that cluster unless the policy explicitly tolerates those taints. Karmada currently supports taints with NoSchedule and NoExecute effects.
Setting cluster taints
Use karmadactl taint to taint a cluster:
# Update cluster 'foo' with a taint with key 'dedicated' and value 'special-user' and effect 'NoSchedule'
# If a taint with that key and effect already exists, its value is replaced as specified
karmadactl taint clusters foo dedicated=special-user:NoSchedule
Tolerating cluster taints
To schedule to a tainted cluster, declare the toleration in the policy:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
clusterTolerations:
- key: dedicated
value: special-user
effect: NoSchedule
This allows scheduling onto clusters tainted dedicated=special-user:NoSchedule.
The NoExecute effect is also used in Multi-cluster Failover.
SpreadConstraints
The .spec.placement.spreadConstraints field controls how resources are spread across clusters based on topology domains (cluster, region, zone, or provider).
How spread constraints work
Spread constraints divide clusters into groups based on a specified field and enforce constraints on how many groups are selected:
- SpreadByField: Group clusters by a built-in field
cluster(supported)region(supported)zone(not yet implemented)provider(not yet implemented)
- SpreadByLabel: Group clusters by a custom label
- MaxGroups: Maximum number of groups to select
- MinGroups: Minimum number of groups to select (defaults to 1)
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
placement:
replicaScheduling:
replicaSchedulingType: Duplicated
spreadConstraints:
- spreadByField: region
maxGroups: 2
minGroups: 2
- spreadByField: cluster
maxGroups: 2
minGroups: 2
This spreads workloads across exactly two regions with one cluster per region (two clusters total).
If the replica division preference is StaticWeightList, spread constraints are not applied.
If using SpreadByField, you must also specify cluster-level spread constraints. For example, when using SpreadByFieldRegion to specify region groups, you must also use SpreadByFieldCluster to specify how many clusters to select.