AetherSlice is an automated 5G SA network slicing testbed for Kubernetes. It deploys a 5G core with Open5GS and RAN options based on srsRAN Project, UERANSIM, or srsRAN with real RF hardware.
Developed as part of a project at the Chair "Architekturen der Vermittlungsknoten", Technische Universität Berlin, Germany.
| Field | Information |
|---|---|
| Project name | AetherSlice |
| Initial authors | Lukas Banjamin Roth, Johannes Maria Ruef |
| Supervisor | Elena-Ramona Modroiu |
| License | GNU Affero General Public License v3.0 (AGPLv3), see LICENSE |
Install the Python and Ansible dependencies on the control machine:
pip install -r requirements.txt
ansible-galaxy collection install -r ansible/requirements.ymlEdit ansible/inventory/hosts.yml with the target node IPs, then deploy the full stack:
cd ansible
ansible-playbook deploy.yml -i inventory/hosts.ymlTo redeploy only the 5G stack on an existing Kubernetes cluster:
ansible-playbook deploy.yml --tags 5g -i inventory/hosts.yml┌─ K8s Cluster ─────────────────────────────────────────────────────┐
│ │
│ master (192.168.178.110) worker (192.168.178.111) │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ Open5GS Core (5GC) │ │ Container image builds │ │
│ │ AMF, NRF, SCP, │ │ (nerdctl + buildkit) │ │
│ │ AUSF, UDM, UDR, │ └─────────────────────────┘ │
│ │ PCF, NSSF, BSF │ │
│ │ SMF×3 (per slice) │ ┌─────────────────────────┐ │
│ │ Shared UPF │ │ RAN (srsRAN or UERANSIM)│ │
│ │ MongoDB, WebUI │ │ gNB + 3 UEs (ZMQ) │ │
│ └─────────────────────┘ └─────────────────────────┘ │
│ │
│ Calico CNI + Multus (PFCP bridge for SMF↔UPF) │
└───────────────────────────────────────────────────────────────────┘
| Slice | S-NSSAI | 5QI | DNN | gNB min PRB | gNB max PRB | UE Subnet |
|---|---|---|---|---|---|---|
| Best Effort | SST=1, SD=1 | 9 | internet | 10% | 100% | 10.41.0.0/16 |
| Priority | SST=1, SD=2 | 5 | priority | 25% | 80% | 10.42.0.0/16 |
| Guaranteed | SST=4, SD=3 | 6 | guaranteed | 40% | 80% | 10.43.0.0/16 |
QoS differentiation is enforced by the gNB scheduler via per-slice PRB allocation. A single shared UPF handles all slices (no per-slice traffic shaping).
| Component | Version |
|---|---|
| Open5GS | v2.7.5 |
| srsRAN Project (gNB) | latest main |
| srsRAN 4G (srsUE) | release 25.10 |
| UERANSIM | 3.2.6 |
| Kubernetes | 1.29 |
| Calico | 3.27.0 |
| Multus CNI | 4.0.2 |
| Ubuntu | 22.04 LTS |
- Ansible >= 2.15
- SSH key at
~/.ssh/id_ed25519
Two VMs (or bare-metal machines) with Ubuntu 22.04, root SSH access, and static IPs. In development, both VMs were in the same local network, if this is not the case, also join them together via a VPN or other methods.
| Node | Role | Recommended | Minimum |
|---|---|---|---|
| k8s-master | Core network (Open5GS) | 4 vCPU, 8 GB RAM | 2 vCPU, 4 GB RAM |
| k8s-worker | Image builds + RAN pods | 14 vCPU, 16 GB RAM | 8 vCPU, 8 GB RAM |
The worker needs significant CPU for the srsRAN deployment: gNB (~6 cores), GNU Radio broker (~1.5 cores), and 3 UEs (~1.4 cores each). With fewer than 8 cores, UE attachment may be unreliable.
Edit ansible/inventory/hosts.yml with your node IPs:
k8s_nodes:
hosts:
k8s-master:
ansible_host: 192.168.178.110
k8s_role: master
k8s-worker:
ansible_host: 192.168.178.111
k8s_role: workercd ansible
ansible-playbook deploy.yml -i inventory/hosts.ymlThis runs all stages in order:
- nodes -- K8s prerequisites on all nodes (containerd, kubelet, kernel modules, sysctl)
- cluster -- Initialize K8s master, join workers, install Calico CNI
- images -- Build container images on worker (Open5GS, srsRAN gNB, srsUE)
- 5g -- Deploy core network + RAN
# Only deploy K8s prerequisites
ansible-playbook deploy.yml --tags nodes -i inventory/hosts.yml
# Only deploy 5G stack (assumes cluster is ready)
ansible-playbook deploy.yml --tags 5g -i inventory/hosts.yml
# Only redeploy RAN
ansible-playbook deploy.yml --tags ran -i inventory/hosts.ymlThe default RAN is srsRAN with ZMQ (3 simulated UEs). Switch with -e ran_simulator=:
| Option | Command | Description |
|---|---|---|
srsran (default) |
deploy.yml --tags 5g |
srsRAN gNB + 3 srsUE via GNU Radio ZMQ broker. Full L1/L2 radio simulation with QoS differentiation. |
ueransim |
deploy.yml --tags 5g -e ran_simulator=ueransim |
UERANSIM gNB + 2 UEs. Faster startup, no radio layer (no QoS differentiation in throughput). |
srsran_rf |
deploy.yml --tags 5g -e ran_simulator=srsran_rf |
srsRAN gNB with USRP B210 for real phones. Requires SDR hardware. See docs/real-rf-setup.md. |
Deploys a single pod on the worker with 5 containers: gNB, GNU Radio broker, and 3 srsUEs. Each UE connects to a different slice. Startup takes ~5 minutes (UEs attach sequentially at 130s, 160s, 190s).
ansible-playbook deploy.yml --tags 5g -i inventory/hosts.ymlDeploys UERANSIM gNB + 2 UEs. No radio layer simulation -- useful for testing core network routing and slice selection without the CPU overhead of srsRAN.
ansible-playbook deploy.yml --tags 5g -i inventory/hosts.yml -e ran_simulator=ueransimDeploys only the gNB on a laptop connected to a SDR. Real 5G phones connect over the air (band n78, 3.6 GHz). The laptop is automatically provisioned as a lightweight K8s worker. This is not yet tested and may still need significant development work
ansible-playbook deploy.yml --tags 5g -i inventory/hosts.yml -e ran_simulator=srsran_rfSee docs/real-rf-setup.md for hardware, SIM programming, and phone setup.
# All pods running
kubectl get pods -n open5gs
# UE connectivity (srsRAN ZMQ)
kubectl exec -n open5gs deployment/srsran-multi-ue -c ue1 -- ping -c 3 8.8.8.8
kubectl exec -n open5gs deployment/srsran-multi-ue -c ue2 -- ping -c 3 8.8.8.8
kubectl exec -n open5gs deployment/srsran-multi-ue -c ue3 -- ping -c 3 8.8.8.8
# gNB logs (should show "NG Setup procedure is successful")
kubectl logs deployment/srsran-multi-ue -n open5gs -c gnb | grep "NG Setup"
# Open5GS WebUI
# http://<master-ip>:30300 (admin / 1423)Run the pairwise contention benchmark to verify per-slice QoS differentiation:
./ansible/scripts/contention_benchmark.shTests all 3 UE pairs competing for radio resources. Expected result under contention:
UE1 vs UE2: 1.58 vs 2.99 Mb/s (35% vs 65%)
UE1 vs UE3: 1.58 vs 5.99 Mb/s (21% vs 79%)
UE2 vs UE3: 3.04 vs 5.98 Mb/s (34% vs 66%)
| File | Description |
|---|---|
ansible/deploy.yml |
Main playbook |
ansible/inventory/hosts.yml |
Cluster node IPs |
ansible/roles/srsran/files/multi-ue.yaml |
gNB config, UE configs, GNU Radio flowgraph, K8s deployment |
ansible/roles/srsran/files/subscribers.yaml |
Open5GS subscriber provisioning (3 UEs) |
ansible/roles/open5gs_srsran/files/ |
All Open5GS NF manifests (AMF, SMF, UPF, etc.) |
ansible/scripts/contention_benchmark.sh |
Pairwise QoS benchmark script |
docs/real-rf-setup.md |
USRP B210 + phone setup guide |
- If subscriber config changes, delete the job first:
kubectl delete job add-subscribers -n open5gs - srsRAN uses
Recreatedeployment strategy to avoid rollout hangs - The
--tags rantag redeploys only the RAN (with automatic cleanup of previous deployment) - Monitoring stack (Prometheus + Grafana):
--tags monitoring(Grafana at:30301, admin/admin5g)