Skip to main content

How Core Providers Work

Racora's network layer dials an AMF and advertises a network identity. It never learns which 5G core sits behind that AMF. The core is a pluggable provider, the way the cluster underneath is a pluggable platform: one selector picks it, the network identity is declared once and every provider serves it, and a SIM is declared the same way whatever the core. What differs per core lives in cores/<name>/ in the repository and nowhere else. The controllers never branch on the provider's name; the umbrella chart's render gate and the installer's supported list name the known providers, and treat external specially: no module chart, an AMF address instead.

Two providers ship today, Open5GS (the default, in-cluster) and an external core (bring your own AMF). What each provides, side by side, is The 5G Core; selecting one and declaring the identity is Configure the 5G Core.

The Core Contract​

Every provider gives the RAN the same seven things. They are what the RAN relies on and what the contract tests assert for any provider.

  1. An NGAP endpoint. An in-cluster provider renders a Service named amf in the core namespace (5g-core) with a port ngap, SCTP, 38412, and gtpu, UDP, 2152 when it terminates N3; the controller then dials amf.5g-core.svc.cluster.local with no configuration. An endpoint-only provider names its AMF in global.core.amfAddr, a DNS name or IP address every CU-CP pod reaches over SCTP.
  2. The network identity, consumed. global.network (the PLMN, the tracking areas, the slices) is declared once. The core serves it and never declares its own; the CU-CP advertises it in NG Setup; every NRCell must declare a PLMN and TAC from it, and a cell outside it is refused with a condition instead of failing NG Setup. A provider that cannot serve what is asked fails the render with the reason.
  3. A UE pool and egress. The provider states who allocates UE addresses and who provides internet egress: for Open5GS the UPF's pool and the egress-nat host unit; for an external core, the core's own.
  4. Subscribers. The provider states how a subscriber is provisioned and where it is stored; storage is the provider's. Open5GS keeps its database on a PersistentVolumeClaim; an external core is provisioned by you.
  5. Placement. An in-cluster core follows the CU planes: it shares the control node with CU-CP, CU-UP and CU-IP.
  6. Host requirements. What the control node must allow: for Open5GS hostNetwork, privileged and three host units; for an external core nothing.
  7. Uninstall. The ran scope removes the provider with the release; the host scope removes its units, its environment file and what its host teardown clears.

How a Subscriber Reaches the Core​

A Subscriber is provisioned by racora-core-controller, the core-side controller (the two controllers), and never by the operator against the core directly. The provider declares how, in a ConfigMap named racora-core-provider in 5g-core, whose keys are listed for builders below.

The Open5GS chart renders this ConfigMap with exec and adapters built on the image's own provisioning helpers; the umbrella renders it with none for the external provider, so a declared Subscriber is reported Unmanaged and you provision the SIM in your core. The controller reads the ConfigMap on every reconcile, so a provider change reaches it without a restart. Outcomes land on the Subscriber as conditions: Provisioned; ProviderNotReady and AdapterFailed, retried; SecretMissing; Unmanaged. A periodic resync re-applies every Subscriber, so a core whose database was wiped heals from the declarations.

The core controller holds only the rights this needs: read access to the CRDs and namespaces, Subscriber resources and their status cluster-wide, the credentials Secrets in racora-system, and the provider ConfigMap, pods and pods/exec in 5g-core. The RAN controller holds no Secret, Subscriber or pods/exec rights.

For Builders​

The provider declaration's keys:

KeyMeaning
providerthe provider's name
subscribers.modeexec: run an adapter inside the core's pod; none: the core is not provisioned by Racora
subscribers.selector, subscribers.containerwhich pod and container the adapter runs in
subscribers.apply, subscribers.removethe two adapter scripts; each receives one JSON object on stdin (the IMSI, the keys, the QoS class, the DNN, the static address, the slices)

The provider modules themselves (the directory layout, the values overlay, the optional chart and host units, and how a core is added) are documented in the repository at cores/README.md; the model is Extending Racora.