Skip to content

[Feature]: Centrally assign indices to daemons and update the Compute Domain Clique state. #1107

Description

@sakura-3

Component

compute-domain-controller

Problem Statement

After a training workload is submitted under a compute domain, all compute-domain-associated daemons must negotiate a unique index for each daemon. This index is used to generate DNS configuration. Only after that can the imex process start in each daemon, and the daemon pod becomes Ready.

Only when all daemons associated with the compute domain are Ready can the PrepareResourceClaims phase of the compute-domain-kubelet-plugin complete, allowing the training pods to start.

In large-scale training scenarios, we have observed slow pod startup times. The main bottleneck is the negotiation process described above. The negotiation is based on optimistic locking: each daemon updates the status of the same compute domain object, which leads to a large number of conflicts and update requests.

This high request volume triggers API server APF throttling (code 429) and Retry-After: 30s, while update conflicts (code 409) further amplify the problem.

Related Progress

Proposed Solution

Based on the lessons learned so far, we can draw the following conclusions:

I suggest revisiting the centralized index allocation approach, with the help of CDC.

Component Changes

Compute Domain Kubelet Plugin

The DRA plugin needs to add an additional cliqueID label to each node, which helps the controller build clique domains.

Compute Domain Daemon

The daemon no longer needs to manage CDC lifecycle operations such as creation, update, deletion, or index registration logic (currently handled by DaemonInfoManager in the code).

The daemon only needs to watch the CDC object associated with itself, read the assigned index from it, generate DNS configuration, and start the imex process. When an ipset change is observed, it should regenerate the configuration and restart imex.

Compute Domain Controller

The controller will now be responsible for allocating indexes and updating CDC and CD status. Concretely, the controller will watch cd, node, daemonset, and pods.

When the controller starts, it watches nodes and builds both the clique domains and the node -> index mapping. The node -> index mapping is mostly stable and is only updated when nodes are added or removed.

cliqueID nodeName index
clique-1 node-1 0
clique-1 node-2 1
clique-1 node-3 2
clique-2 node-4 0
clique-2 node-5 1

When allocating mappings, a simple first-fit strategy is used. On restart, the controller first reconstructs the clique domains and mappings from existing CDC objects.

The controller spawns one cdcWorker per CDC. Workers across different CDCs run in parallel, while within each cdcWorker, events are processed serially via a workqueue.

Taking the lessons from #810 into account, daemon pod events are dispatched to the corresponding cdcWorker based on a nodeName → clique mapping. This is a fast, lightweight operation and therefore will not cause backlog accumulation at the controller.

Tasks handled by cdcWorker include:

  • Updating the daemon pod IP received from events into the CDC
  • Watching the corresponding daemonset, and when Ready = DESIRED, updating the CDC status to Ready

After all CDCs are Ready, the controller updates the CD status to Ready.

Batch Update

In the centralized update design, we can further reduce request volume by using batch updates. Given the structure of CDC, each individual update request is essentially updating or appending one entry in the daemons slice. We can merge multiple update requests inside the controller and flush them in batches.

Estimated Optimization Impact

Using a 5k-node scenario as an example, and consider using a batch size of 5 in the new design.:

Scenario Step Request Count Total
Current Update CDC to register DNS index 5000 * 3~5 retries = 15000~25000 25000~40000
Current Update CDC status = Ready 5000 * 2~3 retries = 10000~15000 25000~40000
Optimized Update CDC to register DNS index 5000 * 0.2~1 = 1000~5000 2000~10000
Optimized Update CDC status = Ready 5000 * 0.2~1 = 1000~5000 2000~10000

Alternatives Considered

No response

Scope

Large: New feature gate, API change, or multi-component change

Upstream Kubernetes Dependencies

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions