Files
homelab/kubernetes/infrastructure/namespaces/namespaces.yaml
T
claude-botandClaude Opus 5 40362925fa feat(llama-server): local LLM inference on the Intel iGPU
Adds llama.cpp's server in router mode as the cluster's OpenAI-compatible
inference endpoint, in a new `ai` namespace, running entirely on the on-board
Iris Xe via the `gpu.intel.com/i915` resource.

One Deployment serves both a chat model and an embedding model: started with
--models-preset and no -m, llama-server supervises each INI section as its own
subprocess behind a single port, routed by the request body's "model" field.
That gives /v1/chat/completions, /v1/embeddings and /v1/rerank from one pod,
with a crash in one model not taking out the other.

Backend and build are chosen from measurement rather than documentation. On
this hardware (i9-12900H, Iris Xe 96 EU) Vulkan beats the SYCL/oneAPI build by
+50% prefill and +36% decode, so the Vulkan image is pinned to b10731 — the
exact build benchmarked. Full offload (-ngl 99) matches CPU throughput at
~10.8 tok/s decode and ~137 t/s prefill while leaving the node's 14 cores free
for the rest of the cluster; the iGPU is here for that isolation, not speed.

The weights are fetched by an initContainer on first start, so no manual
seeding step stands between a merge and a working endpoint. They land on a
prune-disabled CephFS RWX PVC and are skipped on later starts.

Exposed LAN-only at llm.renner.uno: the API is unauthenticated, so the
`dns.renner.uno/public` label is deliberately omitted and only the UDM
external-dns instance publishes the record.

The pod needs no hostPath and no privilege — the device plugin passes the
render node in through the device-plugin API — so `ai` takes the cluster's
default `baseline` enforcement with no pod-security labels.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 14:24:54 +02:00

198 lines
5.0 KiB
YAML

apiVersion: v1
kind: Namespace
metadata:
name: apps
---
# Pull-based off-VPS backup of the NetBird controller state
# (kubernetes/infrastructure/netbird-backup).
apiVersion: v1
kind: Namespace
metadata:
name: netbird-backup
---
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
---
apiVersion: v1
kind: Namespace
metadata:
name: audiobookshelf
---
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
---
# 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
---
# 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