workspace (component)
A Kustomize component that does the unglamorous-but-required boilerplate every app needs: create the namespace, label it for the platform controllers, set up a baseline ServiceAccount, and ensure the homelab-standard annotations are present.
It's the first component most apps pull in. Other components (cnpg, valkey, backups, app-network-policy) assume workspace already established the namespace and labels.
What it composes
Namespace<app>— created with the standard homelab labels:kubernetes.io/metadata.name: <app>(set automatically; restated for cross-cluster consistency)pod-security.kubernetes.io/enforce: restricted(with per-app override patches when an app legitimately needs root, e.g. linuxserver images using PUID/PGID).homelab.kueber.eu/cluster: <cluster>— for the monitoring and Kyverno layers.
ServiceAccount<app>— the default identity any pod runs as if not otherwise configured.Role/RoleBindingfor the per-app ServiceAccount — minimum permissions to read its own Secrets and ConfigMaps, nothing more.
How an app uses it
Almost always pulled in first:
# k8s/apps/talos/<app>/kustomization.yaml
namespace: <app>
components:
- ../../../components/talos/workspace # always first
- ../../../components/talos/app-network-policy
- ../../../components/talos/cnpg # if needed
- ../../../components/talos/backups # if PVCs exist
The order in the components: list matters when components override each other; in practice workspace is always first because everything else assumes its labels are already set.
Why a component, not just a hand-written namespace per app
- Single point of policy. Pod Security Standards, default ServiceAccount tokens, default annotations — change once and every app picks up the new defaults at the next reconciliation.
- Consistency for cross-cluster tooling. Monitoring scrapes, Kyverno policies, and the backup scheduler all key off the
homelab.kueber.eu/clusterlabel. If one app's namespace forgot to set it, the silence is hard to debug. - No boilerplate copy-paste. A new app's
kustomization.yamldoesn't need to repeat the namespace + RBAC plumbing.
Operational notes
- Restricted Pod Security is the default. Apps that legitimately need root (linuxserver images, Gitea for SSH) patch their namespace's pod-security label to
baselineand document the reason in the cluster README — see Content model. - Deleting the namespace deletes everything in it. The component doesn't add finalizers — if an app is being decommissioned, deleting the
Namespacedirectly is the cleanest path. - The same component on the edge cluster is slightly thinner — no
homelab.kueber.eu/cluster: taloslabel, no monitoring annotation (edge apps aren't scraped from the production Prometheus).
Composition source
No partial — there's no README.md in k8s/components/<cluster>/workspace/ yet. See k8s/components/talos/workspace for the actual manifests.