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>
312 lines
9.4 KiB
YAML
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
|