Network Reference
Network configuration and addressing for the fzymgc-house cluster.
IP Addressing Summary
| Network |
CIDR |
Purpose |
| Node Network |
192.168.20.0/24 |
Physical node IPs |
| Pod Network |
10.42.0.0/16 |
Kubernetes pods |
| Service Network |
10.43.0.0/16 |
Kubernetes services |
| MetalLB Pool 1 |
192.168.20.145-149 |
LoadBalancer VIPs |
| MetalLB Pool 2 |
192.168.20.155-159 |
LoadBalancer VIPs |
IPv6 ULA Addressing
Unique Local Addresses (ULA) provide stable internal IPv6 addressing that works without internet connectivity.
| Prefix |
CIDR |
Purpose |
| ULA Base |
fddb:f665:73f7::/48 |
Site-local IPv6 prefix |
VLAN Subnets
Each VLAN receives a /64 subnet from the ULA prefix:
| VLAN |
Interface |
IPv6 Subnet |
Router Address |
| Main (3000) |
bond0.3000 |
fddb:f665:73f7:1::/64 |
::1 |
| Guest (3100) |
bond0.3100 |
fddb:f665:73f7:2::/64 |
::1 |
| IoT (3020) |
bond0.3020 |
fddb:f665:73f7:3::/64 |
::1 |
| Lab (1000) |
bond0.1000 |
fddb:f665:73f7:4::/64 |
::1 |
| Telework (3200) |
bond0.3200 |
fddb:f665:73f7:5::/64 |
::1 |
Configuration
ULA addresses are configured by the router-ipv6-ula Ansible role:
- Assigns ULA addresses to router interfaces at boot
- Configures dnsmasq for Router Advertisement (RA)
- Clients auto-configure via SLAAC
See: ansible/roles/router-ipv6-ula/defaults/main.yml
Node Addresses
Control Plane Nodes
| Node |
IP Address |
Role |
| tpi-alpha-1 |
192.168.20.101 |
Control plane (etcd) |
| tpi-alpha-2 |
192.168.20.102 |
Control plane (etcd) |
| tpi-alpha-3 |
192.168.20.103 |
Control plane (etcd) |
Worker Nodes
| Node |
IP Address |
Board |
| tpi-alpha-4 |
192.168.20.104 |
alpha |
| tpi-beta-1 |
192.168.20.111 |
beta |
| tpi-beta-2 |
192.168.20.112 |
beta |
| tpi-beta-3 |
192.168.20.113 |
beta |
| tpi-beta-4 |
192.168.20.114 |
beta |
Virtual IPs
| Address |
Purpose |
Provider |
192.168.20.140 |
Kubernetes API VIP |
kube-vip |
192.168.20.145-149 |
Service LoadBalancers |
MetalLB |
192.168.20.155-159 |
Service LoadBalancers |
MetalLB |
DNS Configuration
External DNS (Cloudflare)
Domain: fzymgc.house
| Record |
Type |
Target |
Proxy |
vault |
CNAME |
Cloudflare Tunnel |
No (TCP passthrough) |
auth |
CNAME |
Cloudflare Tunnel |
Yes |
grafana |
CNAME |
Cloudflare Tunnel |
Yes |
argocd |
CNAME |
Cloudflare Tunnel |
Yes |
mealie |
CNAME |
Cloudflare Tunnel |
Yes |
longhorn |
CNAME |
Cloudflare Tunnel |
Yes |
status |
CNAME |
Cloudflare Tunnel |
Yes |
Internal DNS Subdomain
k8s.fzymgc.house - Direct cluster access (not via Cloudflare)
| Record |
Type |
Target |
*.k8s |
A |
MetalLB Traefik VIP |
doltdb |
A |
MetalLB Dolt VIP |
Kubernetes DNS (CoreDNS)
| Pattern |
Resolution |
<svc>.<ns>.svc.cluster.local |
Service ClusterIP |
<pod-ip-dashed>.<ns>.pod.cluster.local |
Pod IP |
<svc>.<ns>.svc |
Short form (within cluster) |
Ingress Architecture
Traffic Flow - External
Internet
|
v
Cloudflare Edge (WAF, DDoS protection)
|
v
Cloudflare Tunnel (encrypted)
|
v
cloudflared pod (namespace: cloudflared)
|
v
Traefik (namespace: traefik)
|
v
Backend Services
Traffic Flow - Internal
Internal Client
|
v
DNS: *.k8s.fzymgc.house -> MetalLB VIP
|
v
Traefik (namespace: traefik)
|
v
Backend Services
Traefik Configuration
Entrypoints
| Name |
Port |
Protocol |
Purpose |
| web |
80 |
HTTP |
Redirect to HTTPS |
| websecure |
443 |
HTTPS |
TLS termination |
Middleware
| Name |
Namespace |
Type |
Purpose |
| authentik-auth |
authentik |
ForwardAuth |
SSO authentication |
| redirect-https |
traefik |
RedirectScheme |
HTTP to HTTPS |
TLS Configuration
| Certificate |
Issuer |
Domains |
| Wildcard |
Let's Encrypt |
*.fzymgc.house |
| Per-service |
Let's Encrypt |
Individual hostnames |
Address Pools
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default
spec:
addresses:
- "192.168.20.145-192.168.20.149"
- "192.168.20.155-192.168.20.159"
L2 Advertisement
All pools use L2 mode (ARP) for service advertisement.
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
spec:
ipAddressPools:
- default
Calico Network Policies
Policy Types
The cluster uses two types of network policy:
- Standard Kubernetes NetworkPolicy (
networking.k8s.io/v1) — used by most namespaces for basic ingress rules
- Calico NetworkPolicy (
projectcalico.org/v3) — used when service-aware rules are needed (e.g., egress to ClusterIP services)
Important: Standard ipBlock rules do not work for ClusterIP services with Calico. Calico evaluates policy before kube-proxy DNAT, so the service VIP never matches. Use Calico's destination.services rules instead. See: Calico service rules
Default Policies
| Policy |
Effect |
| Default deny ingress |
All namespaces start with no ingress allowed |
| Allow DNS egress |
Pods can reach CoreDNS |
| Allow internet egress |
Pods can reach external addresses |
Namespace Isolation
Each namespace has explicit NetworkPolicy resources allowing:
- Ingress from Traefik (for HTTP services)
- Ingress from monitoring (for metrics scraping)
- Ingress from within the same namespace
Namespace Network Policy Usage
| Namespace |
Policy Type |
Reason |
merlin |
Calico NetworkPolicy |
Egress to K8s API, kube-dns, and Vault via service rules |
nats |
Standard k8s NetworkPolicy |
Ingress control |
Cloudflare Tunnel
Tunnel Configuration
| Setting |
Value |
| Tunnel Name |
fzymgc-house-main |
| Namespace |
cloudflared |
| Replicas |
2 |
| Protocol |
QUIC (primary), HTTP/2 (fallback) |
Ingress Rules
Configured in Cloudflare Zero Trust dashboard, routes to:
http://traefik.traefik.svc:80 (most services)
tcp://vault-active.vault.svc:8200 (Vault - TCP passthrough)
Port Reference
External Ports
| Port |
Protocol |
Service |
| 443 |
HTTPS |
All web services (via Cloudflare) |
| 6443 |
HTTPS |
Kubernetes API (internal only) |
Internal Service Ports
| Service |
Port |
Protocol |
| Traefik |
80/443 |
HTTP/HTTPS |
| Vault |
8200 |
HTTPS |
| Authentik |
80 |
HTTP |
| Grafana |
3000 |
HTTP |
| ArgoCD |
80/443 |
HTTP/HTTPS |
| VictoriaMetrics |
8428 |
HTTP |
| Loki |
3100 |
HTTP |
| Dolt |
3306 |
MySQL |
Troubleshooting
kubectl get ipaddresspools -n metallb
kubectl get l2advertisements -n metallb
kubectl get svc -A | grep LoadBalancer
Check Traefik Routes
kubectl get ingressroutes -A
kubectl get ingressroutetcps -A
kubectl get middlewares -A
DNS Resolution
# From within cluster
kubectl run -it --rm debug --image=busybox -- nslookup vault.vault.svc
# External resolution
dig vault.fzymgc.house
Network Policy Debugging
# Standard Kubernetes NetworkPolicies
kubectl get networkpolicies -A
kubectl describe networkpolicy <name> -n <namespace>
# Calico NetworkPolicies (projectcalico.org/v3)
kubectl get networkpolicies.p -A # shorthand for projectcalico.org
calicoctl get networkpolicy -n <namespace> -o yaml
# Check if a Calico policy is blocking traffic
# (requires calicoctl or Calico node logs)
kubectl logs -n calico-system -l k8s-app=calico-node --tail=50