Grouping and Co-location
Applications are often made up of multiple Kubernetes resources that must be placed together.
For example, an application might include:
- a
Deployment - a
ConfigMap - a
Secret - a
Service - a
ServiceAccount - one or more supporting services, such as Redis, Postgres, Kafka, or RabbitMQ
In a multi-cluster environment, related resources often need to run on the same workload cluster so they can communicate using cluster-local networking and DNS.
Nova supports this through grouping and co-location.
How Grouping Works
Grouping is defined through the groupBy field in a SchedulePolicy.
groupBy tells Nova to treat resources that share the same label value as a single placement unit.
Nova automatically manages the resulting groups. Users generally define grouping behavior through SchedulePolicy; they do not usually modify the generated group objects directly.
Example SchedulePolicy
This policy groups resources by the kubernetes.io/part-of label:
apiVersion: policy.elotl.co/v1alpha1
kind: SchedulePolicy
metadata:
name: web-app-policy
spec:
resourceSelectors:
labelSelectors:
- matchExpressions:
- key: kubernetes.io/part-of
operator: Exists
values: []
groupBy:
labelKey: kubernetes.io/part-of
Example Workload Resources
The following resources share labels that identify which application group they belong to:
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-app-config
labels:
kubernetes.io/part-of: web-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-app
labels:
kubernetes.io/part-of: web-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
kubernetes.io/part-of: web-app
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-db
labels:
kubernetes.io/part-of: web-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
labels:
kubernetes.io/part-of: observability-stack
Resulting Behavior
Nova creates two placement groups from these resources:
-
web-app, containing:backend-app-configbackend-appredisweb-db
-
observability-stack, containing:prometheus
Each group is treated as one placement unit. Nova places the resources in a group on the same workload cluster when sufficient resources are available.
Capacity-aware Group Placement
When grouped workloads are updated, Nova evaluates whether the current workload cluster still has sufficient CPU, memory, and, optionally, GPU resources for the entire group.
If the current workload cluster no longer has sufficient capacity, Nova will reschedule the group to another eligible workload cluster unless capacity-based relocation is disabled.
Multi-cluster Group Placement
By default, Nova places a group on a single workload cluster.
If Nova cannot find one workload cluster with enough available resources and multi-cluster capacity placement is enabled, Nova may consider placing replica-count-based members of the group across multiple workload clusters.
This mode should only be used when workload clusters share a network layer that allows pods and services to span clusters, such as with Cisco Cilium Cluster Mesh.
When using Cilium Cluster Mesh, services fronting pods across clusters are expected to include:
metadata:
annotations:
service.cilium.io/global: "true"
For headless services, also include:
metadata:
annotations:
service.cilium.io/global-sync-endpoint-slices: "true"
Cilium Cluster Mesh must also be configured with endpoint slice synchronization enabled.