Files
homelab/kubernetes/infrastructure/namespaces/namespaces.yaml
T
claude-botandClaude Opus 5.5 444b20d70e
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
feat(cloudflare-lb-sync): manage proxy.renner.uno load balancer from the cluster
New in-house controller (kuma-sync house pattern) that reconciles a
CloudflareLoadBalancer resource into a DNS-only Cloudflare load balancer,
its pool and its health monitor, using cloudflare-go v7.

proxy.renner.uno had round-robin A/AAAA records without health checks, so
every proxy reboot blackholed part of the public traffic. The owner set up
a DNS-only load balancer by hand (hostname origins proxy-1/proxy-2, HTTPS
monitor with Host: status.renner.uno); this moves it into git.

- Identity is the load balancer hostname; pool and monitor are found via
  its references. Hand-made objects are adopted (the account allows only
  2 origins, so a parallel pool would be rejected) and tagged in their
  description; objects with another owner's tag are never written.
- Status shows per-origin health; resync every 2 minutes.
- Token from OpenBao homelab/infrastructure/k8s-cloudflare-lb via
  ExternalSecret; egress limited to api.cloudflare.com:443.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:46:01 +02:00

312 lines
9.4 KiB
YAML

apiVersion: v1
kind: Namespace
metadata:
name: apps
---
apiVersion: v1
kind: Namespace
metadata:
name: crowdsec
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: storage
---
apiVersion: v1
kind: Namespace
metadata:
name: database
---
apiVersion: v1
kind: Namespace
metadata:
name: ingress
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: security
---
apiVersion: v1
kind: Namespace
metadata:
name: rook-ceph
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager
---
apiVersion: v1
kind: Namespace
metadata:
name: authentik
---
apiVersion: v1
kind: Namespace
metadata:
name: paperless
---
# A disposable copy of paperless's database, for measuring how the local LLM
# classifies documents without experimenting on the live archive.
apiVersion: v1
kind: Namespace
metadata:
name: audiobookshelf
---
apiVersion: v1
kind: Namespace
metadata:
name: navidrome
---
apiVersion: v1
kind: Namespace
metadata:
name: immich
---
apiVersion: v1
kind: Namespace
metadata:
name: music-assistant
# Pod runs with hostNetwork + SYS_ADMIN/DAC_READ_SEARCH for audio streaming.
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: home-assistant
# HA Core on hostNetwork + privileged for USB passthrough (edl21, ZWA-2
# added at cutover); Z-Wave JS pod also privileged.
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: velero
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: influxdb
---
apiVersion: v1
kind: Namespace
metadata:
name: spegel
# DaemonSet binds hostPort + mounts containerd socket / content store.
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: v1
kind: Namespace
metadata:
name: evcc
---
apiVersion: v1
kind: Namespace
metadata:
name: openbao
---
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets
---
# Matrix homeserver (Synapse) + Element Web, private, no federation (REN-567).
apiVersion: v1
kind: Namespace
metadata:
name: matrix
---
# Terminus (TRMNL BYOS server) driving the entrance-way e-ink panel.
apiVersion: v1
kind: Namespace
metadata:
name: trmnl
---
# WordPress for www.renner.uno, migrated off the Hetzner VM `wordpress-hochzeit`.
# No privileged label needed: the cluster enforces `baseline`, which permits the
# official Apache image's root master process binding :80. It does trip the
# `restricted` audit/warn level — that is expected and not an error.
apiVersion: v1
kind: Namespace
metadata:
name: wordpress
---
# The Woodpecker service itself — server, agent and its wp-pg Postgres backend,
# moving out of the shared `apps` namespace (issue #433). Distinct from
# `woodpecker-ci`, which enforces pod-security: privileged and holds only
# ephemeral pipeline step pods.
#
# `apps` uses an endpointSelector:{} default-deny, so every allow it carries
# applies to gitea, gatus, external-dns and ical-proxy alike — granting the
# CNPG operator access to wp-pg there would have opened all of `apps` to all of
# `database`. A namespace per service keeps that grant on the one workload.
#
# Declared here rather than alongside the workloads so it is created by the
# `infrastructure` KS. The namespace's CiliumNetworkPolicies ship with the
# `infrastructure-crds` KS (infrastructure/post-crds includes
# ../network-policies/), which itself dependsOn `infrastructure` — so the
# namespace exists before any policy targets it. Creating it in the `woodpecker`
# workload KS would invert that order, since that KS runs after both.
#
# No pod-security labels: the cluster default applies.
apiVersion: v1
kind: Namespace
metadata:
name: woodpecker
---
# Gitea, moving out of the shared `apps` namespace (issue #878). Declared here
# like `woodpecker` above, so it exists before infrastructure-crds applies its
# CiliumNetworkPolicies. No pod-security labels: the cluster default applies.
apiVersion: v1
kind: Namespace
metadata:
name: gitea
---
# Gitea MCP server. Declared here so it exists before infrastructure-crds applies its CNPs.
apiVersion: v1
kind: Namespace
metadata:
name: gitea-mcp
---
# review-bot: reviews pull requests with a Mistral agent. Declared here so it exists before
# infrastructure-crds applies its CNPs.
apiVersion: v1
kind: Namespace
metadata:
name: review-bot
---
# netbird-service-sync, moving out of `openbao` (issue #876). Declared here like
# `woodpecker` above, so it exists before infrastructure-crds applies its
# CiliumNetworkPolicies. No pod-security labels: the cluster default applies.
apiVersion: v1
kind: Namespace
metadata:
name: netbird-service-sync
---
# Local LLM inference (kubernetes/apps/llama-server). Declared here, like
# `woodpecker` above, so the `infrastructure` KS creates it before
# `infrastructure-crds` applies the namespace's CiliumNetworkPolicies.
#
# No pod-security labels: the workload needs no hostPath or privilege — the
# Intel GPU device plugin passes the iGPU in through the device-plugin API —
# so the cluster's default `baseline` enforcement is enough.
apiVersion: v1
kind: Namespace
metadata:
name: ai
---
# Where the Woodpecker kubernetes backend spawns pipeline step pods, isolated
# from `apps`. Distinct from `woodpecker`, which holds the service itself.
#
# Here rather than in apps/woodpecker for the reason spelled out above that
# namespace: post-crds ships this namespace's CiliumNetworkPolicies via
# ../network-policies/, and infrastructure-crds runs before every app KS. With
# the namespace declared in the workload KS the order inverted, and a rebuild
# stopped with
#
# CiliumNetworkPolicy/woodpecker-ci/default-deny-ingress not found:
# namespaces "woodpecker-ci" not found
#
# which held infrastructure-crds, and with it all twenty app Kustomizations
# that depend on it. The same reasoning was already written down for
# `woodpecker` and simply not carried across to its sibling.
#
# Image-build steps run a privileged docker/buildx plugin pod (see the server's
# WOODPECKER_PLUGINS_PRIVILEGED). Talos enforces Pod Security; without the
# label the privileged step pods are rejected at admission. The namespace holds
# nothing but ephemeral CI step pods, so the exemption stays off apps/.
apiVersion: v1
kind: Namespace
metadata:
name: woodpecker-ci
labels:
app.kubernetes.io/name: woodpecker
pod-security.kubernetes.io/enforce: privileged
---
# IngressMonitorController, which syncs UptimeRobot monitors from
# `EndpointMonitor` custom resources (REN-2; not Ingress annotations — those are
# obsolete in IMC v2). Declared here rather than in the workload Kustomization
# for the reason spelled out above `woodpecker`: the `infrastructure` KS creates
# namespaces, and `infrastructure-crds` (post-crds, which includes
# ../network-policies/) runs after it — so declaring it in the workload KS would
# invert that order the moment this namespace gains a CiliumNetworkPolicy. It
# has one now: ../network-policies/uptime-monitor-ns.yaml.
#
# No pod-security labels: the controller needs no hostPath, hostNetwork or
# privilege, so the cluster's default `baseline` enforcement is enough.
apiVersion: v1
kind: Namespace
metadata:
name: uptime-monitor
---
# Renovate (REN-216): a weekly CronJob that opens dependency-update pull
# requests on git.renner.uno. Declared here, not in apps/renovate, for the same
# ordering reason as `uptime-monitor` above: this namespace has a
# CiliumNetworkPolicy (../network-policies/renovate-ns.yaml), and
# infrastructure-crds applies that policy after `infrastructure` creates the
# namespace.
#
# No pod-security labels: the job needs no privilege, so the cluster's default
# `baseline` enforcement is enough.
apiVersion: v1
kind: Namespace
metadata:
name: renovate
---
# kuma-sync controller; declared here because it has a CiliumNetworkPolicy applied by infrastructure-crds.
apiVersion: v1
kind: Namespace
metadata:
name: kuma-sync
---
# cloudflare-lb-sync controller; declared here because it has a CiliumNetworkPolicy applied by infrastructure-crds.
apiVersion: v1
kind: Namespace
metadata:
name: cloudflare-lb-sync
---
# Hermes Agent (kubernetes/apps/hermes). Declared here so it exists before
# infrastructure-crds applies its CNPs. No pod-security labels: the image's
# s6-overlay init starts as root and drops to the `hermes` user, which the
# cluster's default `baseline` enforcement allows.
apiVersion: v1
kind: Namespace
metadata:
name: hermes