Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9e368cf
feat(global-router): add a crate for types the Global Router componen…
atchernych Oct 26, 2026
008d8f2
refactor(global-router): drop doc comments that restate their items
atchernych Oct 26, 2026
71f89c9
fix(global-router): check a registration's model and correct three do…
atchernych Oct 27, 2026
8e30f3c
fix(global-router): let a client follow any lease the service grants
atchernych Oct 27, 2026
8b6c23e
feat(global-router): name a pool's PoolRelay by every address of its pod
atchernych Oct 27, 2026
c7ee161
test(global-router): drop checks the JSON round trips already make
atchernych Oct 27, 2026
48637b7
feat(global-router): add the pool discovery contract and its stores
atchernych Oct 27, 2026
03eae14
fix(global-router): mark a stale MCS view incomplete and log empty ones
atchernych Oct 27, 2026
36125d9
docs(global-router): say that an MCS watch stream waits for its first…
atchernych Oct 27, 2026
c410173
perf(global-router): read EndpointSlice lists from the API server's c…
atchernych Oct 27, 2026
959e2d5
perf(global-router): list EndpointSlices unpaged, so the cache serves…
atchernych Oct 27, 2026
a962b76
docs(global-router): say that pool Services need a ServiceExport, not…
atchernych Oct 27, 2026
1a1372a
fix(global-router): address the standards review of the discovery stores
atchernych Oct 27, 2026
ce637fc
fix(global-router): address the second review of the discovery stores
atchernych Oct 27, 2026
130aaef
fix(global-router): address the third review of the discovery stores
atchernych Oct 27, 2026
c6efecb
Merge branch 'main' into atchernych/global-common
atchernych Oct 28, 2026
4bb3f61
Merge branch 'atchernych/global-common' into atchernych/global-discov…
atchernych Oct 28, 2026
7919ee9
Merge branch 'main' into atchernych/global-common
atchernych Oct 29, 2026
4323f2a
refactor(global-router): rename the shared types as reviewers asked
atchernych Oct 29, 2026
5aadafa
refactor(global-router): build the discovery client on the shared types
atchernych Oct 29, 2026
0a33716
Merge branch 'atchernych/global-common' into atchernych/global-discov…
atchernych Oct 29, 2026
69d703e
refactor(global-router): follow the shared types' renames
atchernych Oct 29, 2026
547d554
Merge branch 'main' into atchernych/global-discovery-service
atchernych Oct 29, 2026
2a80836
docs(global-router): document the stores' watch streams, as the bots …
atchernych Oct 29, 2026
459c03f
fix(global-router): use Karmada's real Service name limit, 55
atchernych Oct 29, 2026
f5c0508
docs(global-router): word the Karmada name check for any exported Ser…
atchernych Oct 29, 2026
06b4f63
docs(global-router): call the discovery implementations backends, not…
atchernych Oct 29, 2026
822175e
docs(global-router): say what the watch stream waits for
atchernych Oct 29, 2026
39a56e0
docs(global-router): say how callers treat a partial list
atchernych Oct 29, 2026
0917613
Merge branch 'main' into atchernych/global-discovery-service
atchernych Oct 30, 2026
7332626
fix(global-router): list every Ready PoolRelay pod of a pool
atchernych Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions lib/global-common/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,12 @@ pub struct PoolListing {
pub frontends: Vec<Url>,
#[serde(default)]
pub capacity: Vec<Capacity>,
/// The only PoolRelay allowed to stream this pool's state, by each
/// identity it can connect with. On a trusted network these are its pod's
/// addresses, as [`address_identity`] writes them: two on a dual-stack
/// cluster. Empty when the service does not know the PoolRelay.
/// The PoolRelays allowed to stream this pool's state, by each identity
/// they can connect with. A pool runs active-active PoolRelay replicas,
/// each reporting to every router, and routers dedupe the overlapping
/// reports. On a trusted network these are the addresses of every Ready
/// replica's pod, as [`address_identity`] writes them: two per pod on a
/// dual-stack cluster. Empty when the service does not know the PoolRelays.
#[serde(default)]
pub relay_identities: Vec<String>,
}
Expand Down
18 changes: 18 additions & 0 deletions lib/global-discovery-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,21 @@ edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true

[dependencies]
dynamo-global-common = { workspace = true }

anyhow = { workspace = true }
async-stream = { workspace = true }
async-trait = { workspace = true }
futures = { workspace = true }
k8s-openapi = { workspace = true }
kube = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

[dev-dependencies]
tokio = { workspace = true, features = ["test-util"] }
9 changes: 9 additions & 0 deletions lib/global-discovery-service/src/backends.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! Implementations of [`crate::pool_discovery`], one module per
//! backend.

pub mod kubernetes;
pub mod memory;
mod stream;
41 changes: 41 additions & 0 deletions lib/global-discovery-service/src/backends/kubernetes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! The MCS backend, using SIG Multicluster: pools ([`McsPoolDirectory`]) and
//! Global Router replicas ([`McsReplicaDirectory`]) from the EndpointSlices
//! that MCS imports, named as [`McsImplementation`] describes.
//!
//! It assumes a trusted network where pod addresses are reachable between
//! clusters (for example Azure CNI with peered VNets, or the AWS VPC CNI with
//! peered VPCs), and an MCS implementation, Karmada first.
//!
//! Each pool's PoolRelay Service, named `<DGD name>-pool-relay` by default,
//! needs a `ServiceExport`, and so does the router's Service in the hub, so
//! its replicas appear in every importing cluster. A pool is live while a
//! PoolRelay endpoint is Ready. Its `relay_identities` are the addresses of
//! every Ready PoolRelay pod, for routers on a trusted network to admit each
//! of the pool's active-active replicas.
//!
//! With Karmada, a Service name may have at most 55 characters: DGD names up
//! to 44 with the default `-pool-relay` suffix. Karmada imports a Service as
//! `derived-<name>`, and that name may have at most 63 characters, so
//! Karmada imports nothing for a longer name, and the backend never sees that
//! Service's endpoints. [`McsReplicaDirectory::new`] logs an error for a
//! Service whose name is too long.
//!
//! Create the PoolRelay Service and its `ServiceExport` in the workload
//! cluster, not through Karmada propagation. Kubernetes copies a Service's
//! labels onto its EndpointSlices, so a Karmada-propagated Service gives its
//! slices Karmada's labels. In a test with Karmada v1.19, deleting such a
//! `ServiceExport` made karmada-agent delete the Service's EndpointSlice
//! too. Exporting the Service again then found no slice until the Service
//! changed.

mod cache;
mod endpoints;
mod hub;
mod mcs;

pub use endpoints::{ExportedService, McsReplicaDirectory};
pub use hub::McsPoolDirectory;
pub use mcs::McsImplementation;
Loading
Loading