# Distribute workload replicas across clusters

This guide shows how to scale one workload across multiple member clusters using `DistributedScaledObject` (DSO) with a `kubernetes-resource` trigger reading a ConfigMap value.

## Prerequisites

- Kedify Agent is installed in your KEDA cluster.

- Member clusters are registered through one of the [distributed registration providers](https://docs.kedify.io/how-to/multicluster-gitops/).

- `DistributedScaledObject` controller is enabled in Kedify Agent.

- `kubectl` installed and access to: 

  - KEDA cluster context

  - each member cluster context

Select distributed mode in your maintained Agent Helm values and apply through your [Helm/GitOps workflow](https://docs.kedify.io/installation/helm/):

```yaml
global:
  features:
    multicluster:
      enabled: true
      type: distributed
```

This enables the Agent DSO/DSJ controllers. [Dedicated mode](https://docs.kedify.io/features/multi-cluster-scaling/#dedicated-mode) instead uses ordinary ScaledObjects in each member and leaves the DSO controller disabled.

## Architecture used in this guide

[![A central DistributedScaledObject distributes desired replicas to workload targets in member clusters.](https://docs.kedify.io/assets/images/docs/distributed_scaled_object.svg)](https://docs.kedify.io/assets/images/docs/distributed_scaled_object.svg)

Scroll to exploreDiagram description

A central KEDA installation evaluates demand and uses DistributedScaledObject to update member Kubernetes APIs. Member clusters do not require another KEDA installation.

- KEDA cluster runs Kedify Agent and the `DistributedScaledObject` resource.

- Member clusters run identical `Deployment` workloads.

- Trigger source is a ConfigMap in the KEDA cluster.

When ConfigMap key `metric-value` is higher than target value `5`, DSO increases desired replicas and distributes them across member clusters by weights.

## Step 1: Deploy the same workload to member clusters

Apply this manifest to each member cluster in the same namespace (`default` in this example):

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dso-demo-app
  namespace: default
spec:
  replicas: 0
  selector:
    matchLabels:
      app: dso-demo-app
  template:
    metadata:
      labels:
        app: dso-demo-app
    spec:
      containers:
        - name: app
          image: nginx:1.27
          ports:
            - containerPort: 80
```

Example apply commands:

```bash
kubectl --context member-1 apply -f dso-demo-app.yaml
kubectl --context member-2 apply -f dso-demo-app.yaml
```

## Step 2: Create trigger ConfigMap in the KEDA cluster

Create ConfigMap in the KEDA cluster (same namespace where you will create DSO):

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: dso-mock-metric
  namespace: default
data:
  metric-value: "0"
```

```bash
kubectl --context keda-cluster apply -f dso-mock-metric.yaml
```

## Step 3: Create DistributedScaledObject

Apply this `DistributedScaledObject` in the KEDA cluster:

```yaml
apiVersion: keda.kedify.io/v1alpha1
kind: DistributedScaledObject
metadata:
  name: dso-demo
  namespace: default
spec:
  memberClusters:
    - name: member-1
      weight: 4
    - name: member-2
      weight: 6
  scaledObjectSpec:
    scaleTargetRef:
      kind: Deployment
      name: dso-demo-app
    minReplicaCount: 0
    maxReplicaCount: 10
    triggers:
      - type: kubernetes-resource
        metadata:
          resourceKind: ConfigMap
          resourceName: dso-mock-metric
          key: metric-value
          targetValue: "5"
```

```bash
kubectl --context keda-cluster apply -f distributedscaledobject.yaml
```

## Step 4: Trigger scaling

Increase the metric value above the target:

```bash
kubectl --context keda-cluster -n default patch configmap dso-mock-metric \
  --type merge \
  -p '{"data":{"metric-value":"20"}}'
```

Set it back below target to scale down:

```bash
kubectl --context keda-cluster -n default patch configmap dso-mock-metric \
  --type merge \
  -p '{"data":{"metric-value":"0"}}'
```

## Step 5: Verify distribution and status

Check DSO status in KEDA cluster:

```bash
kubectl --context keda-cluster -n default get distributedscaledobject dso-demo -o yaml
```

Check replicas in each member cluster:

```bash
kubectl --context member-1 -n default get deploy dso-demo-app
kubectl --context member-2 -n default get deploy dso-demo-app
```

You should observe replica distribution following weights (`member-1:4`, `member-2:6`) within rounding limits.

## Troubleshooting

- DSO does not scale: 

  - Verify `DSO_ENABLED="true"` on `kedify-agent`.

  - Verify member cluster names in `spec.memberClusters` exactly match registered member names.

  - Verify `Deployment` name and namespace are identical across member clusters.

- Trigger not firing: 

  - Verify ConfigMap exists in the same namespace as DSO.

  - Verify `metric-value` is numeric and above `targetValue`.

- Member cluster stays at 0 replicas: 

  - Check DSO status field `memberClusterStatuses` for connectivity or auth issues.

## Continue with this topic

**Configure and verify:** [Register member clusters with GitOps](https://docs.kedify.io/how-to/multicluster-gitops/).

**Reference:** [DistributedScaledObject API reference](https://docs.kedify.io/reference/kubernetes-api/distributedscaledobject/).

**Diagnose:** [Diagnose multi-cluster and tenant controllers](https://docs.kedify.io/troubleshooting/platform-scaling/).

**Related capabilities:** [Distributed multi-cluster scaling](https://docs.kedify.io/features/multi-cluster-scaling/).

---
Canonical: https://docs.kedify.io/how-to/multicluster-dso/
Source: src/content/docs/how-to/multicluster-dso.md
Documentation index: https://docs.kedify.io/llms.txt
