Shared clusters with team namespaces
Many platform teams run one big cluster (often AKS, EKS, or GKE) where each team gets its own namespaces, isolated with network policies. Shoehorn handles this with one agent and zero per-workload config.
How ownership resolves
Section titled “How ownership resolves”The agent assigns every workload to a team using the first match:
- A
shoehorn.dev/ownerorshoehorn.dev/teamlabel on the workload, then the same keys as annotations (labels win over annotations) - A
shoehorn.dev/teamlabel on the workload’s namespace - Falls back to
unassigned
shoehorn.dev/team and shoehorn.dev/owner are the recommended keys. Legacy
alias keys (owner, app.kubernetes.io/owner, and team on namespaces) also
work; see the annotations reference for
the full list.
So the whole setup is one label per namespace:
kubectl label namespace payments shoehorn.dev/team=paymentskubectl label namespace checkout shoehorn.dev/team=checkoutEvery Deployment, StatefulSet, DaemonSet, and CronJob in those namespaces now
shows up in the catalog owned by the right team. Individual workloads can still
override with their own shoehorn.dev/team label.
Network policies don’t get in the way
Section titled “Network policies don’t get in the way”The agent only needs two connections: the Kubernetes API server and your Shoehorn API endpoint. It never connects to kubelets, pods, or node ports, so deny-by-default policies between team namespaces don’t affect it. Allow egress from the agent’s namespace to the API server and to your Shoehorn URL and you’re done.
Permissions
Section titled “Permissions”Helm release detection lets the agent read the contents of every secret in the namespaces it watches, not just Helm’s own. Leave it off unless you need Helm release discovery.
One agent or many?
Section titled “One agent or many?”One agent per cluster is the default and covers the shared-cluster case: teams
are separated in the catalog by ownership, not by agent. If you need hard
separation (different Shoehorn tenants on one physical cluster), run one agent
per scope with agent.kubernetes.scopeMode: namespaces. Each agent registers
as its own cluster and uses one license slot. See the agent guide for scoped mode.
The optional network observer (eBPF) watches pods across the whole cluster, so it doesn’t work with per-tenant scoped agents on a shared cluster. Leave it off in that setup.
Large clusters
Section titled “Large clusters”For clusters past roughly 200 nodes, start from the large-cluster values preset so the agent’s buffers match your event volume. See Tuning for large clusters.