Skip to main content

Configure the 5G Core

The 5G core is a pluggable provider (How Core Providers Work, the providers). This page is the operator's three tasks whatever core runs: selecting the provider, declaring the network identity, and bringing your own AMF. Adding a SIM is Add Subscribers. What an upgrade does to the core is on Upgrade Racora: the core rolls when its image or pod spec changes, while a change to its configuration alone (open5gs-env) needs kubectl -n 5g-core rollout restart deploy/open5gs. What an uninstall removes and keeps is on Uninstall Racora.

Select the Provider​

INSTALL_RACORA_CORE on the installer; open5gs, the reference core, is the default:

curl -sfL https://get.racora.io | sh - # Open5GS
curl -sfL https://get.racora.io | INSTALL_RACORA_CORE=external INSTALL_RACORA_AMF_ADDR=amf.my-5gc.example.com sh -

With plain helm the selector is global.core.provider (open5gs or external), and global.core.amfAddr names the AMF for external. Exactly one provider renders.

Two gates refuse a selection that cannot work. The installer stops before touching anything on an unknown provider name, on external without an AMF address, and on an AMF address given with an in-cluster provider (the provider exposes its own AMF). The chart fails the render on the same three, and on the values keys retired in v0.8.0 (core.enabled, global.amfAddr, and racora-core.mcc/mnc when they disagree with global.network.plmn), so a mismatch never becomes a half-working RAN.

On the k3s platform switch providers by re-running the installer with the new selection: the new provider's host units are installed, which a values override alone cannot do. The old provider's units stay on the node until a host-scope uninstall (which also removes the RAN) or you remove them by hand.

The Network Identity​

The PLMN, the tracking areas and the slices are declared once, in global.network, and reach three places from there: the core serves them, the CU-CP advertises them in NG Setup, and every NRCell must declare a plmn and tac that are in them. The default is the reference deployment's identity (PLMN 90170, tracking area 7, slice sst 1) and every cell example in these docs uses it, so a fresh install needs nothing here.

To run another, apply the identity edited. On the k3s platform it goes into the one HelmChartConfig named racora in kube-system: there is exactly one such object, and a registry re-root or a hot-bumped image tag belongs in the same valuesContent, never in a second manifest that would replace this one (Override Chart Values). The example network-identity.yaml:

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: racora
namespace: kube-system
spec:
valuesContent: |-
global:
network:
plmn: "90170"
tacs: [7]
slices:
- sst: 1

On a cluster you run, put the same block in your values file (Install onto an Existing Kubernetes Cluster), not on the command line: a --set on one run is lost on the next, which starts from the file. The release re-renders the core's configuration and the CU-CP's overlay, but neither process re-reads them while running. Restart both, and the new identity is served and advertised after a short NGAP outage from which the CU-CP recovers on its own:

kubectl -n 5g-core rollout restart deploy/open5gs
kubectl -n centralized-unit rollout restart deploy/cu-cp

What holds the identity together:

  • A NRCell whose plmn or tac is not in the identity gets phase: Error and the condition ConfigGenerated=False with reason PlmnNotServed or TacNotServed, plus a Warning Event, and no DU is generated. Correct the cell or the identity; the condition clears on the next reconcile.
  • A provider that cannot serve the identity refuses it at render time: the tracking areas and slice Open5GS serves are fixed in its image, so a tacs entry outside them fails the render with that message rather than NG Setup at runtime.
  • The pre-v0.8.0 chart keyed the PLMN under racora-core.mcc/mnc. Those keys are tolerated while they agree with global.network.plmn and refused when they do not; the upgrade notes have the migration.

Bring Your Own AMF​

INSTALL_RACORA_CORE=external deploys no core. The CU-CP dials INSTALL_RACORA_AMF_ADDR (global.core.amfAddr), a DNS name or IP address every CU-CP pod reaches over SCTP, port 38412. The controller renders the address into the CU-CP's configuration; a change takes effect at the next CU-CP restart. Your core must serve exactly global.network (Racora cannot check that, and the AMF rejects NG Setup for a PLMN it does not serve) and it owns UE addressing and egress. Subscribers you declare are reported Unmanaged; provision them in your core. The External Core page has the whole contract.

Reach the CU-UP from Your UPF​

The CU-UP binds GTP-U on its pod IP, not on the node, so the UPF's N3 traffic must reach the pod network. Find the address, the node it runs on, and that node's pod subnet:

kubectl -n centralized-unit get pod -l app=cu-up -o wide # IP and NODE columns
kubectl get node <node> -o jsonpath='{.spec.podCIDR}{"\n"}' # the subnet the pod IP lies in

On the UPF host add a route for that subnet through the node's address (ip route add <pod-subnet> via <node ip>), and check the node forwards (sysctl net.ipv4.ip_forward is 1). The reverse path, CU-UP to UPF, goes out through the node's default route and needs nothing unless the UPF sits on a network the node cannot reach. Prove it with a PDU session: the phone attaches and carries data, or Troubleshoot has the log lines to read.