Files
home-network-k3s-impl/apps/vms/unifi/40-networkpolicy.yaml
T
jakman85andClaude Opus 4.8 317b3f02f1 feat(vms): onboard UniFi OS Server as a KubeVirt VM on a non-gating track
First KubeVirt VM app + first real CDI http import. UniFi OS Server (UOS) is
Ubiquiti's current self-host product (the .deb is deprecated); it bundles UniFi
OS + Network app + its own datastore, so no MongoDB companion.

- apps/vms/unifi: CDI DataVolume (Ubuntu 24.04 cloud image -> longhorn-vm
  RWX/Block, live-migratable) + VirtualMachine (evictionStrategy: LiveMigrate)
  with cloud-init that installs podman/slirp4netns/jq and runs the UOS installer
  NON-INTERACTIVELY. The installer URL is resolved at boot from Ubiquiti's public
  firmware API (fw-update.ui.com/api/firmware-latest) — always-latest, no pinned
  URL to maintain (currently UOS v5.1.37).
- L4 exposure: two LoadBalancer Services (TCP+UDP) sharing a pinned, L2-announced
  Cilium VIP 192.168.1.54 (device inform/adoption + STUN can't ride the L7
  Gateway); external-dns publishes unifi.home.keithjackson.dev. UI on :11443.
- default-deny + additive CNPs (controller ingress, egress, and CDI-importer
  egress for the image pull).
- clusters/base/apps-vms.yaml: NON-GATING Flux Kustomization (wait:false,
  dependsOn platform-config) — VMs are a separate lifecycle from the app waves,
  so a slow VM import/install can't stall the app tier.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-26 15:05:05 -05:00

94 lines
3.4 KiB
YAML

---
# STAGING / DRAFT — see namespace.yaml header.
#
# Additive ALLOWs on top of the 10-default-deny baseline. Cilium enforces the UNION of the k8s
# NetworkPolicy (default-deny) and these CiliumNetworkPolicies (same pattern as pihole). The VM's
# datapath is the virt-launcher pod, so endpointSelector kubevirt.io/vm=unifi targets the VM.
#
# NOTE on selector pinning: fromEntities/toEntities (world/cluster/host) are entity-based and need
# no namespace pin. The endpointSelector is already namespace-scoped by each CNP's own namespace.
# (The "must carry io.kubernetes.pod.namespace" caution applies to fromEndpoints/toEndpoints PEER
# selectors, which we deliberately avoid here.)
# --------------------------------------------------------------------------------------------
# 1) INGRESS to the controller: LAN devices + admin browsers reach the L4 ports. LAN hosts are
# entity `world` to Cilium (off-cluster); `host`/`cluster` cover node-local health probes and
# any in-cluster caller.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: unifi-allow-l4-ingress
namespace: unifi
labels:
app.kubernetes.io/name: unifi
spec:
endpointSelector:
matchLabels:
kubevirt.io/vm: unifi
ingress:
- fromEntities:
- world
- cluster
- host
toPorts:
- ports:
- { port: "8080", protocol: TCP } # inform / adoption
- { port: "11443", protocol: TCP } # UOS UI
- { port: "8443", protocol: TCP } # legacy UI
- { port: "8880", protocol: TCP } # guest portal http
- { port: "8843", protocol: TCP } # guest portal https
- { port: "6789", protocol: TCP } # throughput
- { port: "3478", protocol: UDP } # STUN
- { port: "10001", protocol: UDP } # discovery
---
# 2) EGRESS from the controller: internet (apt, the UOS installer download, UniFi updates + remote
# access/STUN to Ubiquiti) + DNS. `world` = default WAN egress (egress-class: internet).
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: unifi-allow-egress
namespace: unifi
labels:
app.kubernetes.io/name: unifi
spec:
endpointSelector:
matchLabels:
kubevirt.io/vm: unifi
egress:
- toEntities:
- world
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- { port: "53", protocol: UDP }
- { port: "53", protocol: TCP }
---
# 3) EGRESS for the CDI IMPORTER pod (one-shot, during the DataVolume http import). It runs in this
# default-deny namespace, so without this it cannot reach cloud-images.ubuntu.com and the import
# hangs. Selects the importer by its CDI label; allows DNS + world. (This is the app-namespace
# analogue of the CDI-import allow the vm-data-survival runbook notes.)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: unifi-allow-cdi-import-egress
namespace: unifi
labels:
app.kubernetes.io/name: unifi
spec:
endpointSelector:
matchExpressions:
- { key: cdi.kubevirt.io, operator: Exists }
egress:
- toEntities:
- world
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- { port: "53", protocol: UDP }
- { port: "53", protocol: TCP }