Deploy Cells
Declare cells on real radios, one per radio, on the nodes you choose; check them, change
them, remove them. The examples follow the reference deployment: a control node running
the CU planes and the core, and two radio nodes each with a USRP B210. A control node
that is itself rf-ready carries a radio too; the same declaration then names it. For an
end-to-end walkthrough with a phone, see the tutorials
Attach a Phone to a Live Cell and
Hand Over Between Two Cells.
Before You Declare
-
The platform is installed and dormant.
kubectl get deploy -n centralized-unitshowscu-cp,cu-upandcuipat0/0. (Install the Control Node) -
Each real radio has a node. The host is provisioned and joined, carries
racora.io/rf-ready=true, and advertises the radio:kubectl get nodes -L racora.io/rf-readykubectl get node <node> -o jsonpath='{.status.allocatable.ettus\.com/usrp}{"\n"}' # 1 per USRPIf either is missing, see Add a Radio Node and Connect a Radio.
-
The network identity. Every cell declares
spec.plmnandspec.tac, and both must be in the identity the network serves (global.network: PLMN 90170, tracking area 7 by default — what the cells below and every example in these docs use). A cell outside it is refused with the conditionConfigGenerated=False(PlmnNotServed/TacNotServed) and never reaches the core; to run another identity, change it in one place (Configure the 5G Core). -
A radio plan. Band, ARFCN, bandwidth and subcarrier spacing per cell, under your own spectrum authorization. The PCI is optional: leave it out and the controller assigns a temporary one, which the Intelligence Plane replaces with a planned one.
-
Timing, if there is more than one cell. Handover needs frame-aligned cells, which on USRPs means a GPSDO with GPS lock on every radio; decide this before you buy antennas (How Mobility Reaches the CU-CP).
One Cell on a USRP B210
A 10 MHz n78 carrier on a B210 over USB 3. The lines that are yours to change are the radio's serial, the node and, once the cell has a neighbor to hand over to, the clock:
apiVersion: racora.io/v1alpha1
kind: NRCell
metadata:
name: nr-n78-b210
namespace: racora-system
spec:
band: 78
dlArfcn: 632628
channelBandwidthMHz: 10
commonScs: 30
plmn: "90170"
tac: 7
pci: 1
radioBackend:
ruType: uhd
uhd:
deviceArgs: "type=b200,serial=35912B3,num_recv_frames=64,num_send_frames=64" # your radio's serial
clockSource: internal # gpsdo once cells hand over (needs GPS lock)
otwFormat: sc12
srate: 23.04
txGain: 80
rxGain: 40
duAssignment:
nodeName: radio-node-2 # your radio node
position:
xCoord: 0
yCoord: 0
heightM: 1
azimuthDeg: 0
The four carrier fields, plmn and tac are the only required ones; pci is optional
(the controller assigns one when it is missing); duAssignment.nodeName pins the DU to a
node; position and azimuthDeg are read by the Intelligence Plane
for its graph geometry and never reach the gNB. What every radio field does is
Connect a Radio; the full list with defaults and ranges is the
NRCell API.
kubectl apply -f nr-n78-b210.yaml
What the Controller Does with It
It assigns the cell's identity (sectorId, gnbDuId, gnbId, the resulting nci),
fills in a temporary PCI when you left pci out, generates the DU (a ConfigMap and a
Deployment in distributed-unit, scheduled onto rf-ready nodes and the one you named,
requesting one USRP), scales the CU plane 0 → 1 on the first cell, and regenerates the
CU-CP's overlay with every cell's identity and mobility configuration. The DU connects to
the CU-CP over F1 and the cell goes on air, unless you declared it adminState: Locked.
The identity rules are Cell Identity; what lands in
status is NRCell Status and Conditions. A PCI you set
yourself is kept unless the Intelligence Plane finds it in a two-hop confusion with
another cell, in which case it retunes it.
Check It
kubectl get nrcell -n racora-system
# NAME PCI PCI-SOURCE SECTOR DU-ID NCI BAND PHASE AGE
# nr-n78-b210 1 spec 0 0 0x66C000 78 ConfigGenerated 3m
kubectl get pods -n distributed-unit # du-nr-n78-b210 Running
kubectl get deploy -n centralized-unit # cu-cp / cu-up / cuip 1/1 (cuip needs the control node's GPU)
kubectl get nrcell nr-n78-b210 -n racora-system -o jsonpath='{.status.conditions}{"\n"}'
Phase is Pending while a temporary PCI is being assigned, ConfigGenerated once the
DU exists, Error with a condition saying why otherwise
(NRCell Status and Conditions). cuip reaches 1/1
only on a node with a GPU (Requirements). Whether the cell is actually on the
air is the CU-CP's answer, not Kubernetes'; ask it with the cell's decimal NCI
(status.nciDecimal) over the Runtime Commands:
{"cmd": "cell_status", "cgi": {"plmn": "90170", "nci": 6733824}}
The reply says operational_state: enabled for a cell on the air; how to reach the
command surface is the runtime commands reference.
A DU that is Running but restarting is usually waiting on the radio's GPS lock; that and
every other way a cell fails to come up is in Troubleshoot.
A Second Cell on Another Radio Node
The same declaration with its own radio and node; nothing else has to be coordinated — identity is assigned, the PCI is planned apart from the first cell's, and the CU-CP's configuration grows to hold both:
apiVersion: racora.io/v1alpha1
kind: NRCell
metadata:
name: nr-n78-b210-node1
namespace: racora-system
spec:
band: 78
dlArfcn: 632628
channelBandwidthMHz: 10
commonScs: 30
plmn: "90170"
tac: 7
radioBackend:
ruType: uhd
uhd:
deviceArgs: "type=b200,serial=3591266,num_recv_frames=64,num_send_frames=64"
clockSource: internal # gpsdo once cells hand over (needs GPS lock)
otwFormat: sc12
srate: 23.04
txGain: 80
rxGain: 40
duAssignment:
nodeName: radio-node-1
No pci this time: the controller assigns a temporary one and the Intelligence Plane
replaces it with a planned one that does not collide with the first cell's
(status.pciSource: controller-retuned).
Two cells that can hand UEs over to each other need two more things: frame alignment
(both clockSource: gpsdo with GPS lock), and the neighbor relations, declared on each
cell toward the other (Configure Mobility and Cell State); automatic
neighbor relations can also discover them for you. The tutorial
Hand Over Between Two Cells walks through both.
Change a Cell
Edit the NRCell and the controller reconciles it. Which changes cost what:
- Radio parameters (
band,dlArfcn, bandwidth, SCS, theradioBackendblock,pci) change the DU's rendered configuration, so the DU pod rolls — the cell leaves the air for the restart. The DU rolls only when its rendered configuration actually changed. - Mobility and administrative state (
neighbors,mobility,periodicReportCfgId,adminState,cellBarred) are applied to the running CU-CP; no restart. pci: when the Intelligence Plane retunes it, the controller does it behind a cell lock and unlocks after the DU rolled; when you change it by hand, only the DU roll happens.duAssignment.nodeNamemoves the DU to another node: a new pod there, the old one gone.
Remove a Cell
kubectl delete nrcell nr-n78-b210-node1 -n racora-system
The DU Deployment and ConfigMap (and a zmq DU's Service) go with it, its identity is freed for the next
cell, and the CU-CP's configuration is regenerated without it. Deleting the last cell
dissolves the CU plane back to 0/0.
Virtual Cells
For a pipeline or a lab without radios, radioBackend.ruType: dummy runs a DU with no radio
(what the example cell uses), and
ruType: zmq exchanges IQ samples with a UE simulator over ZeroMQ. Both schedule on any node;
neither needs rf-ready. Their fields are in Connect a Radio.
When It Does Not Come Up
Every symptom, its cause and its fix: Troubleshoot. The conditions the controller sets are listed in NRCell Status and Conditions.