环境部署2: OAI
在网络上找到的有关 Dockerized OAI 的部署经验帖:
| 资源 |
说明 |
链接 |
| OAI 官方 RFsimulator 示例 |
OAI CI 测试用的 docker-compose |
https://github.com/OPENAIRINTERFACE/openairinterface5g/tree/develop/ci-scripts/yaml_files/5g_rfsimulator |
| OAI Docker Hub 镜像 |
官方预构建镜像 |
https://hub.docker.com/u/oaisoftwarealliance |
| OAI nrUE 教程 |
官方 SA 模式教程 |
https://github.com/OPENAIRINTERFACE/openairinterface5g/blob/develop/doc/NR_SA_Tutorial_OAI_nrUE.md |
| Open5GS + OAI-gNB (Gradiant) |
Helm 集成参考 |
https://gradiant.github.io/5g-charts/open5gs-oaignb.html |
| Open-Cells 博客 |
社区经验 |
https://open-cells.com/index.php/2020/05/27/5g-openair-first-run/ |
下面给出笔者自己的步骤:
环境: Ubuntu 24.04, 采用本机部署 OAI Docker, 不考虑虚拟机
本地构建/配置
| Bash |
|---|
| # OAI gNB 镜像
docker pull oaisoftwarealliance/oai-gnb:develop
# OAI NR-UE 镜像
docker pull oaisoftwarealliance/oai-nr-ue:develop
# 验证镜像
docker images | grep oaisoftwarealliance
|
| Bash |
|---|
| # 查看 Open5GS 的 Docker 网络
docker network ls | grep open5gs
# 查看 AMF 容器的 IP 地址
docker inspect amf | grep IPAddress
# 查看 UPF 容器的 IP 地址
docker inspect upf | grep IPAddress
|
记录一下:
- AMF IP: 例如
172.22.0.10
- Docker 网络名: 例如
docker_open5gs_default
创建如图所示结构的本地仓库: [推荐开git]

文件参考: gnb.conf
注意这里面的三个“修正”, 需要读者/用户根据本机情况更改:
- AMF 地址: 在 herlesupreeth 仓库中, AMF IP 通常在
sa-deploy.yaml 中静态分配为 172.22.0.10
| Bash |
|---|
| # 方法1:从运行中的容器获取
docker inspect amf --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
# 方法2:查看 docker-compose 定义
grep -A 5 "amf:" ~/docker_open5gs/sa-deploy.yaml | grep ipv4_address
# 方法3:查看 .env 文件
grep AMF ~/docker_open5gs/.env
|
- gNB 网络接口: eth0 是 Docker 容器内部的默认网络接口名
- 当 Docker 容器连接到网络时, Docker 会自动创建一个名为
eth0 的虚拟网卡
- 这与宿主机的网卡名(如
wlp44s0, enp0s31f6)无关
- gNB 地址: 在 OAI 的
docker-compose.yaml 中定义, 自行检查即可
| Bash |
|---|
| # 查看当前网络中所有已分配的 IP
docker network inspect docker_open5gs_default --format '{{range .Containers}}{{.Name}}: {{.IPv4Address}}{{"\n"}}{{end}}'
|
| YAML |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 | Active_gNBs = ( "gnb-rfsim");
Asn1_verbosity = "none";
gNBs =
(
{
gNB_ID = 0xe00;
gNB_name = "gnb-rfsim";
tracking_area_code = 1;
// ===== 修正1: PLMN 匹配 Open5GS =====
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1 }) });
nr_cellid = 12345678L;
min_rxtxtime = 6;
servingCellConfigCommon = (
{
physCellId = 0;
absoluteFrequencySSB = 621312;
dl_absoluteFrequencyPointA = 620040;
dl_offstToCarrier = 0;
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
initialDLBWPlocationAndBandwidth = 28875;
initialDLBWPsubcarrierSpacing = 1;
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
ul_frequencyBand = 78;
ul_offstToCarrier = 0;
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
initialULBWPlocationAndBandwidth = 28875;
initialULBWPsubcarrierSpacing = 1;
prach_ConfigurationIndex = 98;
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
preambleTransMax = 6;
powerRampingStep = 1;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
msg1_SubcarrierSpacing = 1;
restrictedSetConfig = 0;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
ssb_periodicityServingCell = 2;
dmrs_TypeA_Position = 0;
subcarrierSpacing = 1;
referenceSubcarrierSpacing = 1;
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
SCTP :
{
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
// ===== 修正2: AMF 地址 =====
amf_ip_address = ({ ipv4 = "172.22.0.10"; });
// ===== 修正3: gNB 网络接口 =====
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.22.0.200";
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
GNB_IPV4_ADDRESS_FOR_NGU = "172.22.0.200";
GNB_PORT_FOR_S1U = 2152;
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
);
RUs = (
{
local_rf = "yes";
nb_tx = 1;
nb_rx = 1;
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
sf_extension = 0;
sdr_addrs = "serial=XXXXXXX";
}
);
rfsimulator: {
serveraddr = "server";
};
security = {
ciphering_algorithms = ( "nea0" );
integrity_algorithms = ( "nia2", "nia0" );
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "debug";
f1ap_log_level = "debug";
};
|
文件参考: nr-ue.conf
照抄即可:
| YAML |
|---|
| uicc0 = {
imsi = "001010000000001";
key = "465B5CE8B199B49FAA5F0A2EE238A6BC";
opc = "E8ED289DEBA952E4283B54E88E6183CA";
amf = "8000";
dnn = "internet";
nssai_sst = 1;
}
|
文件参考: docker-compose.yaml
| YAML |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 | services:
oai-gnb:
image: oaisoftwarealliance/oai-gnb:develop
container_name: oai-gnb
cap_add:
- SYS_NICE
- NET_ADMIN
environment:
USE_ADDITIONAL_OPTIONS: --rfsim -E --log_config.global_log_options level,nocolor,time
volumes:
- ./conf/gnb.conf:/opt/oai-gnb/etc/gnb.conf
networks:
default:
ipv4_address: 172.22.0.200
healthcheck:
test: ["CMD", "pgrep", "nr-softmodem"]
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: oaisoftwarealliance/oai-nr-ue:develop
container_name: oai-nr-ue
cap_add:
- NET_ADMIN
- NET_RAW
environment:
USE_ADDITIONAL_OPTIONS: -E --rfsim -r 106 --numerology 1 --band 78 -C 3619200000 --rfsimulator.serveraddr 172.22.0.200
volumes:
- ./conf/nrue.conf:/opt/oai-nr-ue/etc/nr-ue.conf
devices:
- /dev/net/tun:/dev/net/tun
depends_on:
oai-gnb:
condition: service_healthy
networks:
default:
ipv4_address: 172.22.0.201
networks:
default:
external: true
name: docker_open5gs_default
|
Open5GS WebConsole 用户注册
在浏览器里, localhost:9999, 在 Subscriber 里注册一个用户:
| YAML |
|---|
| IMSI: 001010000000001
K: 465B5CE8B199B49FAA5F0A2EE238A6BC
OPc: E8ED289DEBA952E4283B54E88E6183CA
AMF: 8000
SST: 1
DNN: internet
|
检查, 与上述 nr-ue.conf 中的配置一致即可.
启动 RAN 和 UE
| Bash |
|---|
| cd ~/d2c-oai
# 启动 gNB
docker compose up -d oai-gnb
# 启动 UE
docker compose up -d oai-nr-ue
|
现在就大功告成了!
汇总现在的工作流
Before Everything:
| Bash |
|---|
| # 开机自启docker (现在就生效开启)
sudo systemctl enable --now docker
# 检查状态
systemctl status docker
|
启动顺序必须严格遵循: open5gs -> oai-gnb -> oai-nr-ue
- 开启 open5gs
| Bash |
|---|
| cd ~/paper/d2c-open5gs
docker compose -f sa-deploy.yaml up -d
|
- 开启 oai-gnb + oai-nr-ue
| Bash |
|---|
| cd ~/paper/d2c-oai
docker compose up -d oai-gnb
docker compose up -d oai-nr-ue
|
- 检查:
docker ps
- 关闭 oai-gnb + oai-nr-ue
| Bash |
|---|
| cd ~/paper/d2c-oai
docker compose down
|
- 关闭 open5gs
| Bash |
|---|
| cd ~/paper/d2c-open5gs
docker compose -f sa-deploy.yaml down
|