Deployment Phases¶
The testbed is deployed in multiple sequential phases, each building on the previous.
Phase Overview¶
Phases fall into three classes. Core phases always run. Optional phases are addons not required for a working core. Some Core phases are edge-conditional (behavior depends on edge_enabled). See status.md for the core versus optional split.
| Phase | Name | Class | Description |
|---|---|---|---|
| 1 | Infrastructure | Core | System packages, Open vSwitch |
| 2 | Kubernetes | Core | K3s cluster |
| 3 | KubeEdge | Core (edge-conditional) | CloudCore always; EdgeCore when edge_enabled |
| 4 | Overlay Network | Core (edge-conditional) | Multus, OVS bridges, VXLAN tunnels |
| 5 | 5G Core | Core | Open5GS network functions, MongoDB |
| 6 | UERANSIM & MEC | Optional (DEPLOY_MODE=full) |
Simulated gNB and UE |
| 7 | Observability | Core | Prometheus, Loki, Grafana |
| 8 | IAM | Core | Keycloak realm and PostgreSQL |
| 9 | Dashboard | Core | Out-of-band FastAPI + React control plane |
| 10 | CAMARA Gateway | Optional addon | CAMARA Location API gateway |
| 11 | Positioning Engine | Optional addon | Positioning engine with pluggable adapters |
| 12 | Positioning Demo | Optional addon | Positioning demo SPA |
Optional addons are off by default (opt-in). Phase 6 (UERANSIM) is gated by ueransim_enabled, set automatically by DEPLOY_MODE=full or by testbed run-phase 06-ueransim-mec. Phases 10-12 are gated by camara_enabled / positioning_enabled / positioning_demo_enabled in all.yml. See gaps.md for the remaining CAMARA/positioning rework.
Running Phases¶
Provisioning Flags (vagrant up)¶
| Flag | Values | Default | Behavior |
|---|---|---|---|
DEPLOY_MODE |
core_only, full |
core_only |
core_only: all phases except 6; full: also phase 6 (UERANSIM + MEC) |
TESTBED_PROFILE |
laptop, server |
laptop |
server creates 3 VMs with optimized resources; laptop creates 4 VMs including edge |
EDGE_ENABLED |
true, false |
true (laptop) / false (server) |
Controls edge VM creation and all edge-related Ansible tasks |
These flags can be set via environment variables or managed with testbed-config. See Server / NUC Deployment for server-specific guidance.
Examples:
# Core only
vagrant up
# Full stack with UERANSIM
DEPLOY_MODE=full vagrant up
Full Deployment¶
# Runs all phases
DEPLOY_MODE=full vagrant up
Core Only (Default)¶
# Runs all phases except 6 (UERANSIM)
DEPLOY_MODE=core_only vagrant up
Specific Phases¶
vagrant ssh ansible
cd ~/ansible-ro
# Run specific phase
ansible-playbook phases/02-kubernetes/playbook.yml
# Run phases with tags
ansible-playbook phases/00-main-playbook.yml --tags phase4,phase5
Phase 1: Infrastructure¶
Location: ansible/phases/01-infrastructure/
What it does¶
- Installs system packages (curl, wget, jq, etc.)
- Installs and configures Open vSwitch
- Configures kernel parameters (IP forwarding, etc.)
- Sets up systemd-networkd
Key files¶
roles/infra_setup/tasks/main.ymlroles/infra_setup/templates/ovs-system.conf.j2
Verify¶
vagrant ssh worker
sudo ovs-vsctl --version
Phase 2: Kubernetes¶
Location: ansible/phases/02-kubernetes/
What it does¶
- Deploys K3s server on master node
- Deploys K3s agents on worker and edge nodes
- Configures kubeconfig
- Verifies cluster health
Key files¶
roles/k3s_master/tasks/main.ymlroles/k3s_agent/tasks/main.yml
Verify¶
vagrant ssh master
sudo k3s kubectl get nodes
Phase 3: KubeEdge¶
Location: ansible/phases/03-kubeedge/
Edge-conditional: EdgeCore deployment and edge node verification are skipped when
edge_enabled=false(server profile without edge). CloudCore on the worker is always deployed.
What it does¶
- Deploys CloudCore on worker node
- Deploys EdgeCore on edge node (when edge enabled)
- Configures edge-cloud communication (WebSocket port 10000)
- Labels edge node
Key files¶
roles/kubeedge_cloudcore/tasks/main.ymlroles/kubeedge_edgecore/tasks/main.yml
Verify¶
sudo k3s kubectl get nodes
# Edge node should show: agent,edge roles
Phase 4: Overlay Network¶
Location: ansible/phases/04-overlay-network/
Edge-conditional: When
edge_enabled=false, OVS bridges are created locally on the worker without VXLAN tunnels. Multus NADs and the OVS CNI still function for pods running on the worker. Edge-specific DaemonSets and Multus configuration are skipped.
What it does¶
- Installs CNI binaries
- Deploys Multus CNI DaemonSets
- Creates OVS bridges (br-n1, br-n2, br-n3, br-n4, br-n6e, br-n6c, br-n6m)
- Establishes VXLAN tunnels between worker and edge (when edge enabled)
- Creates NetworkAttachmentDefinitions (NADs), including
n6m-netin themecnamespace for MEC services - Creates per-cell networks
Key files¶
roles/ovs_network_setup/tasks/main.ymlroles/multus_install/tasks/main.ymlroles/cell_network_setup/tasks/main.ymlscripts/ovs-setup.sh
Verify¶
# Check OVS bridges
vagrant ssh worker
sudo ovs-vsctl show
# Check NADs
sudo k3s kubectl get net-attach-def -A
Phase 5: 5G Core¶
Location: ansible/phases/05-5g-core/
What it does¶
- Creates 5g namespace
- Deploys MongoDB
- Deploys Open5GS Network Functions:
- NRF (NF Repository Function)
- AMF (Access and Mobility Management)
- SMF (Session Management Function)
- UPF (User Plane Function) - cloud and edge
- UDM, UDR, AUSF, PCF, BSF, NSSF
- Imports subscriber data
- Validates NF connectivity
Key files¶
roles/infrastructure_setup/tasks/main.ymlroles/nf_deployments/tasks/main.ymlroles/subscriber_import/tasks/main.ymlconfigs/*.yaml- NF configurations
Verify¶
sudo k3s kubectl get pods -n 5g
sudo k3s kubectl logs -n 5g deploy/amf -c amf --tail=20
Phase 6: UERANSIM¶
Location: ansible/phases/06-ueransim-mec/
Optional. Runs only with DEPLOY_MODE=full.
What it does¶
- Creates discovery token for edge pods
- Deploys gNB (base station simulator)
- Deploys UE (user equipment simulator)
- Configures dynamic IP discovery via init containers
- Optionally deploys MEC applications
Key files¶
roles/infrastructure_setup/tasks/main.yml- Discovery tokenroles/gnb_deployment/tasks/main.ymlroles/ue_deployment/tasks/main.ymlvars/topology.yml- Cell and UE configuration
Topology Configuration¶
# vars/topology.yml
ueransim_topology:
cells:
- id: 1
gnb:
name: "gnb-1"
node: "edge"
nci: "0x000000010"
tac: 1
ues:
- { id: 1, supi_suffix: "895", apn: "internet" }
- { id: 2, supi_suffix: "896", apn: "internet" }
Verify¶
# Check gNB
sudo k3s kubectl get pods -n 5g -l app=gnb-1
# Check UEs
sudo k3s kubectl get pods -n 5g -l app=ue
# Check AMF logs for registrations
sudo k3s kubectl logs -n 5g deploy/amf -c amf | grep -i "registered"
Phase 7: Observability Stack¶
Purpose: Deploy monitoring and logging infrastructure.
Components:
- Prometheus (metrics collection)
- Loki (log aggregation)
- Grafana (visualization)
- Node Exporter (node metrics)
- Promtail (log shipping)
- Traffic Capture (optional, PCAP)
Deploy¶
vagrant ssh ansible
cd ~/ansible-ro
# Deploy observability stack
ansible-playbook phases/07-observability/playbook.yml
# With traffic capture enabled
ansible-playbook phases/07-observability/playbook.yml -e deploy_traffic_capture=true
Access¶
| Service | URL | Credentials |
|---|---|---|
| Grafana | http://192.168.56.11:30300 | admin / admin5g |
| Prometheus | http://192.168.56.11:30090 | - |
Pre-built Dashboards¶
- Cluster Overview - Node health, resource usage
- 5G Core - NF status, logs, metrics
Verify¶
# Check pods
sudo k3s kubectl get pods -n monitoring
# Check Grafana
curl http://192.168.56.11:30300/api/health
Phase 8: IAM (Keycloak)¶
Location: ansible/phases/08-iam/
What it does¶
- Deploys Keycloak and its PostgreSQL backend
- Creates the
5g-testbedrealm with the dashboard and CAMARA OIDC clients - Defines the role model (
dashboard-admin,dashboard-viewer,camara-location-read) - Seeds two end users (
admin,viewer) with temporary passwords - Realm reconcile behavior is gated (
ask/on/off) viatestbed iam reconcile
Verify¶
sudo k3s kubectl get pods -n iam
See security/iam.md for the realm structure and role matrix.
Phase 9: Dashboard Control Plane¶
Purpose: Prepare an out-of-band dashboard on the ansible VM without impacting namespace 5g runtime.
Deploy / Reconcile¶
vagrant ssh ansible
cd ~/ansible-ro
# Prepare dashboard workspace and dependencies
ansible-playbook phases/09-dashboard/playbook.yml
Development mode (live reload)¶
vagrant ssh ansible
cd ~/ansible-ro
ansible-playbook phases/09-dashboard/playbook.yml -e dashboard_mode=dev
What it does¶
- In
prodmode, synchronizesdashboard/into writable/home/vagrant/dashboard-work - Installs backend and frontend dependencies
- Builds frontend bundle with backend API URL
- Creates and starts systemd services on ansible VM
- Keeps dashboard outside
5gnamespace workload path - Supports a single active runtime profile:
prod(default): stable runtime from/home/vagrant/dashboard-workdev: live reload runtime from/vagrant/dashboard
Services¶
sudo systemctl status dashboard-backend
sudo systemctl status dashboard-frontend
sudo systemctl restart dashboard-backend dashboard-frontend
Access¶
Access URLs (cluster baseline, dev frontend, API): see Dashboard Overview.
Phase 10: CAMARA Gateway (optional)¶
Location: ansible/phases/10-camara/
Optional addon, gated by camara_enabled. Deploys the CAMARA Location API gateway in front of the 5G core. Images are built in the 5g-northbound companion repository and pulled by tag.
See architecture/positioning-adapters.md.
Phase 11: Positioning Engine (optional)¶
Location: ansible/phases/11-positioning/
Optional addon, gated by positioning_enabled. Deploys the positioning engine that the CAMARA Location API relays to, with a pluggable adapter model.
See architecture/positioning-adapters.md.
Phase 12: Positioning Demo (optional)¶
Location: ansible/phases/12-positioning-demo/
Optional addon, gated by positioning_demo_enabled. Deploys the positioning demo SPA that exercises the CAMARA Location API end to end.
Troubleshooting Phases¶
Re-run a Phase¶
vagrant ssh ansible
cd ~/ansible-ro
ansible-playbook phases/04-overlay-network/playbook.yml
Skip Phases¶
ansible-playbook phases/00-main-playbook.yml --skip-tags phase6
Debug Mode¶
ansible-playbook phases/05-5g-core/playbook.yml -vvv