-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Motivation
The current k8s-d2 implementation organizes resources by type within each namespace: all workloads together, all services together, all PVCs together. This creates a fundamental mismatch with how Kubernetes resources actually relate to each other, causing arrow crossings that worsen as we add more connection types.
When a namespace contains multiple applications, arrows must cross long distances between type-based sections (service section → workload section → PVC section). For production namespaces with 10-20 workloads, this becomes a tangled web that defeats the purpose of visualization.
The problem compounds with each new feature from the roadmap:
- Ingress → Service → Workload → PVC = arrows spanning 4 type-based sections
- ConfigMaps, Secrets, NetworkPolicies add more crossings
The fundamental issue: users think in terms of logical applications (frontend = deployment + service + ingress), but the diagram groups by resource type. This cognitive mismatch makes diagrams harder to understand, especially when users ask "Which resources belong to the frontend application?" and related resources are scattered across the diagram.
Additionally, the current hardcoded grid-columns: 3 inside namespaces prevents D2's pathfinding algorithms from working. According to D2 documentation, grids impose positioning outside the layout engine's control, resulting in center-center straight segments with no smart routing to avoid overlaps.
Proposal
Refactor the rendering logic from type-based grouping to relationship-based grouping, where each workload and its related resources (services, PVCs, and future ConfigMaps/Secrets) are rendered together in a logical group.
Approach:
Each workload becomes the center of a group containing:
- The workload itself (Deployment/StatefulSet/DaemonSet)
- Services targeting this workload
- PVCs used by this workload
- Future: ConfigMaps, Secrets referenced by this workload
Groups are rendered as D2 sub-containers with direction: down to keep connections within the group. Orphaned resources (services without workloads, unbound PVCs) go into a separate _unmatched group.
Implementation:
- Add
buildResourceGroups()function to analyze relationships before rendering - Add
findOrphans()function to identify unmatched resources - Refactor
renderNamespaceIndented()to render groups instead of types - Change namespace
grid-columns: 2for wider application groups
Benefits:
- Minimal arrow crossings (connections stay within groups)
- Matches user mental model (each box = logical application)
- Scales to future features (ConfigMaps, Ingress, NetworkPolicies group naturally)
- Self-documenting (grouping shows which resources work together)
Success criteria:
- Related resources appear together in labeled groups
- Orphaned resources clearly identified
- Generated D2 is valid and backwards compatible
- Works for namespaces with 1-20+ workloads