IP Allocation

IP address allocation and DNS record tables for the cluster. Networks and DHCP reservations are managed in terraform/unifi/.


Networks

NetworkVLANSubnetDHCP range
Defaultuntagged192.168.0.0/24192.168.0.6 - 192.168.0.190
home1010.10.0.0/1610.10.0.46 - 10.10.255.254
servers2010.20.0.0/1610.20.200.1 - 10.20.255.254
management5010.50.0.0/2410.50.0.6 - 10.50.0.254
iot10110.101.0.0/1610.101.0.46 - 10.101.255.254

On VLAN 20, everything below 10.20.200.0 is static: nodes, the API VIP, the LoadBalancer pool, Multus pod IPs, and reservations. IPv6 comes from the Init7 delegated prefix 2a02:16a:2a0a::/56: VLAN 20 is slice 2 (2a02:16a:2a0a:2::/64, nodes use SLAAC) and the LoadBalancer pool uses slice 3.


Node Addresses

IP AddressHostnameRoleArchitecture
10.20.10.0--Kubernetes API VIP (control planes)Virtual IP
10.20.10.1worker-01Control PlaneAMD64
10.20.10.2worker-02Control PlaneAMD64
10.20.10.3worker-03Control PlaneAMD64
10.20.10.4worker-04Worker (Intel)AMD64
10.20.10.5worker-05Worker (Intel)AMD64
10.20.10.6worker-06Worker (Intel)AMD64
10.20.10.7worker-07Worker (Dell R630)AMD64
10.20.10.8worker-08Worker (Raspberry Pi 4)ARM64
10.20.10.9worker-09Worker (Raspberry Pi 4)ARM64
10.20.10.10worker-10Worker (Raspberry Pi 4)ARM64
10.20.10.11worker-ai-01Worker (GPU)AMD64

Other Reservations

IP AddressHostPurpose
10.20.0.1UniFi Cloud Gateway FiberVLAN 20 gateway, DNS, BGP peer (ASN 64512)
10.20.10.100dataSynology NAS (NFS)
10.20.85.197nutNUT server for the UPSes
10.101.13.61homeassistantHome Assistant OS (Pi 4) on the iot VLAN
192.168.0.248netbootPXE server on the untagged LAN (Multus networking/lan)

LoadBalancer IP Pool

Cilium LB-IPAM allocates LoadBalancer IPs from 10.20.10.128 - 10.20.10.255 (and 2a02:16a:2a0a:3::/112 for IPv6). Addresses are pinned per Service with the lbipam.cilium.io/ips annotation and announced over L2 (ARP) and BGP to the gateway. worker-ai-01 takes part in neither.

IP AddressNamespaceService
10.20.10.229mediajellyfin
10.20.10.230devforgejo-ssh
10.20.10.231devdev-desktop
10.20.10.232devherdr-app
10.20.10.233vmsomarchy
10.20.10.234vmsdev
10.20.10.235home-automationfrigate-webrtc-udp
10.20.10.238networkingenvoy-internal
10.20.10.239networkingenvoy-external

Gateway Details

GatewayIPTarget DomainPurpose
envoy-external10.20.10.239external.wibrow.devReceives public traffic from the towonel agent
envoy-internal10.20.10.238internal.wibrow.devReceives traffic from the home network and Tailscale; also serves Kanidm LDAP on port 389

Network Diagram

flowchart TB
    subgraph Internet
        CF[Cloudflare DNS<br/>*.wibrow.dev]
        Hub[towonel hub<br/>tunnel.wibrow.dev]
    end

    subgraph GW["UniFi Cloud Gateway Fiber (10.20.0.1, ASN 64512)"]
        DHCP[DHCP / DNS]
        BGP[BGP]
    end

    subgraph Cluster["VLAN 20 (10.20.0.0/16)"]
        subgraph ControlPlane["Control Plane (VIP 10.20.10.0)"]
            CP[10.20.10.1-3<br/>worker-01..03]
        end
        subgraph Workers["Workers"]
            W[10.20.10.4-11<br/>worker-04..10, worker-ai-01]
        end
        subgraph LB["LoadBalancers (10.20.10.128-255)"]
            EE[10.20.10.239<br/>envoy-external]
            EI[10.20.10.238<br/>envoy-internal]
        end
    end

    CF --> Hub
    Hub -->|tunnel via towonel-agent| EE
    DHCP --> ControlPlane
    DHCP --> Workers
    ControlPlane -.->|LB + pod routes| BGP
    Workers -.->|LB + pod routes| BGP

DNS Records

Cloudflare-Managed Records

RecordTypeTargetProxiedPurpose
*.wibrow.devCNAMEtunnel.wibrow.devNoCatch-all to the towonel edge (unmatched names hit the fallback 404 route)
external.wibrow.devCNAMEtunnel.wibrow.devNoTarget for public app records
internal.wibrow.devA10.20.10.238NoTarget for internal app records
<app>.wibrow.devCNAMEexternal.wibrow.dev or internal.wibrow.devNoCreated by external-dns from each HTTPRoute

The wildcard and external records come from the towonel-agent DNSEndpoint, internal from the envoy-internal DNSEndpoint. A second external-dns instance (networking/external-dns-unifi) publishes records to the UniFi gateway's local DNS.

Traffic Flow by Record

flowchart LR
    subgraph External["External Access"]
        W1["app.wibrow.dev"] -->|CNAME| E1["external.wibrow.dev"]
        E1 -->|CNAME| T1["tunnel.wibrow.dev"]
        T1 -->|towonel tunnel| A1[towonel-agent]
        A1 --> EE1[envoy-external<br/>10.20.10.239]
    end

    subgraph Internal["Internal Access"]
        W3["app.wibrow.dev"] -->|CNAME| I3["internal.wibrow.dev"]
        I3 -->|A record| EI1[envoy-internal<br/>10.20.10.238]
    end

Address Space Summary

RangePurpose
10.20.0.1Gateway
10.20.10.0Kubernetes API VIP
10.20.10.1 - 10.20.10.11Nodes
10.20.10.100Synology NAS
10.20.10.128 - 10.20.10.255Cilium LB-IPAM pool
10.20.200.1 - 10.20.255.254DHCP
10.244.0.0/16, fd10:244::/56Pod CIDRs (routable from the LAN via BGP, except on worker-ai-01)
10.96.0.0/12, fd10:96::/112Service CIDRs