blob: cb59fb58e726d3e30c63aadae0c8c61890db5db9 [file] [log] [blame]
Andy Bavierf73c3d22021-08-30 10:29:06 -07001.. vim: syntax=rst
2
Andy Bavierf3e24b62022-03-30 19:53:01 -04003Aether-in-a-Box for Developers
4==============================
Andy Bavierf73c3d22021-08-30 10:29:06 -07005
Andy Bavier840e0b42021-09-16 17:10:23 -07006Aether-in-a-Box (AiaB) provides an easy way to deploy Aether's SD-CORE and ROC
7components, and then run basic tests to validate the installation.
8This guide describes the steps to set up AiaB.
Andy Bavierf73c3d22021-08-30 10:29:06 -07009
Andy Bavier840e0b42021-09-16 17:10:23 -070010AiaB can be set up with a 4G or 5G SD-CORE. In either case, SD-CORE configuration
11can be done with or without the ROC. The ROC
12provides an interactive GUI for examining and changing the configuration, and is used to
13manage the production Aether; it can be deployed to test the integration between
14ROC and SD-CORE. If the ROC is not deployed, a simple tool called SimApp
15is used to configure the required state in SD-CORE for testing core functionality.
16
17Helm charts are the primary method of installing the SD-CORE and ROC resources.
18AiaB offers a great deal of flexibility regarding which Helm chart versions to install:
19
20* Local definitions of charts (for testing Helm chart changes)
21* Latest published charts (for deploying a development version of Aether)
22* Specified versions of charts (for deploying a specific Aether release)
23
24AiaB can be run on a bare metal machine or VM. System prerequisites:
Andy Bavierf73c3d22021-08-30 10:29:06 -070025
Andy Bavier296bfa52022-02-10 17:48:37 -070026* Ubuntu 18.04 clean install
Andy Bavierf73c3d22021-08-30 10:29:06 -070027* Kernel 4.15 or later
28* Haswell CPU or newer
Andy Bavier72547672022-02-03 14:45:16 -070029* At least 4 CPUs and 12GB RAM
Andy Bavier296bfa52022-02-10 17:48:37 -070030* Ability to run "sudo" without a password. Due to this requirement, AiaB is most suited to disposable environments like a VM or a `CloudLab <https://cloudlab.us>`_ machine.
Andy Bavierf73c3d22021-08-30 10:29:06 -070031
32Clone Repositories
33------------------
34
Andy Bavier296bfa52022-02-10 17:48:37 -070035To initialize the AiaB environment, first clone the following repository::
Andy Bavierf73c3d22021-08-30 10:29:06 -070036
Andy Bavier840e0b42021-09-16 17:10:23 -070037 cd ~
Hyunsun Moon09d63bb2022-03-16 09:45:55 -070038 git clone "https://gerrit.opencord.org/aether-in-a-box"
Andy Bavier840e0b42021-09-16 17:10:23 -070039
40If you are going to install AiaB using published Helm charts, you can proceed to the
41next section.
42
Andy Bavier99892132022-03-11 14:49:10 -070043If you wish to install from local Helm charts, clone these additional repositories::
Andy Bavier840e0b42021-09-16 17:10:23 -070044
45 mkdir -p ~/cord
46 cd ~/cord
Hyunsun Moon09d63bb2022-03-16 09:45:55 -070047 git clone "https://gerrit.opencord.org/sdcore-helm-charts"
48 git clone "https://gerrit.opencord.org/roc-helm-charts"
Andy Bavier840e0b42021-09-16 17:10:23 -070049
50Now change to *~/aether-in-a-box* directory.
Andy Bavierf73c3d22021-08-30 10:29:06 -070051
Andy Bavierb40b8fe2022-05-27 15:45:27 -070052.. _rke2-vs-kubespray-install:
53
Andy Bavier62678402022-04-18 12:06:52 -070054RKE2 vs. Kubespray Install
55--------------------------
56
57The AiaB installer will bring up Kubernetes on the server where it is run. By default it
58uses `RKE2 <https://docs.rke2.io>`_ as the Kubernetes platform. However, older versions of AiaB
59used `Kubespray <https://kubernetes.io/docs/setup/production-environment/tools/kubespray/>`_
60and that is still an option. To switch to Kubespray as the Kubernetes platform, edit the
61Makefile and replace *rke2* with *kubespray* on this line::
62
Andy Bavier320bb452022-05-27 15:22:28 -070063 K8S_INSTALL ?= rke2
64
65You may wish to use Kubespray instead of RKE2 if you want to use locally-built images with AiaB
66(e.g., if you are developing SD-CORE services). The reason is that RKE2 uses containerd instead of
67Docker and so cannot access images in the local Docker registry. More details can be found in
Andy Bavierb40b8fe2022-05-27 15:45:27 -070068the :ref:`developer-loop` section below.
Andy Bavier62678402022-04-18 12:06:52 -070069
Andy Bavier840e0b42021-09-16 17:10:23 -070070Installing the ROC
71------------------
Andy Bavierf73c3d22021-08-30 10:29:06 -070072
Andy Bavier840e0b42021-09-16 17:10:23 -070073Note that you must install the ROC *before* installing SD-CORE.
74If you are not using the ROC to configure SD-CORE, you can skip this step.
Andy Bavierf73c3d22021-08-30 10:29:06 -070075
Andy Bavier840e0b42021-09-16 17:10:23 -070076First choose whether you will install the 4G or 5G SD-CORE. To install the ROC to
77configure the 4G SD-CORE::
Andy Bavierf73c3d22021-08-30 10:29:06 -070078
Andy Bavier840e0b42021-09-16 17:10:23 -070079 make roc-4g-models
80
81To install the ROC to configure the 5G SD-CORE::
82
83 make roc-5g-models
84
85By default the above commands install the ROC from the local charts in the Git repos cloned
86earlier. In order to install the ROC using the latest published charts, add *CHARTS=latest*
87to the command, e.g.,::
88
89 CHARTS=latest make roc-4g-models
90
Andy Bavier99892132022-03-11 14:49:10 -070091To install the Aether 2.0 release, add *CHARTS=release-2.0*::
Andy Bavier840e0b42021-09-16 17:10:23 -070092
Andy Bavier99892132022-03-11 14:49:10 -070093 CHARTS=release-2.0 make roc-4g-models
Andy Bavier840e0b42021-09-16 17:10:23 -070094
Andy Bavier4d27e4e2022-02-07 14:49:45 -070095The ROC has successfully initialized when you see output like this::
96
97 echo "ONOS CLI pod: pod/onos-cli-5b947f8f6-4r5nm"
98 ONOS CLI pod: pod/onos-cli-5b947f8f6-4r5nm
99 until kubectl -n aether-roc exec pod/onos-cli-5b947f8f6-4r5nm -- \
100 curl -s -f -L -X PATCH "http://aether-roc-api:8181/aether-roc-api" \
101 --header 'Content-Type: application/json' \
Andy Bavier99892132022-03-11 14:49:10 -0700102 --data-raw "$(cat /root/aether-in-a-box//roc-5g-models.json)"; do sleep 5; done
Andy Bavier4d27e4e2022-02-07 14:49:45 -0700103 command terminated with exit code 22
104 command terminated with exit code 22
105 command terminated with exit code 22
106 "9513ea10-883d-11ec-84bf-721e388172cd"
107
108Don't worry if you see a few lines of *command terminated with exit code 22*; that command is trying to
109load the ROC models, and the message appears if the ROC isn't ready yet. However if you see that message
110more than 10 times then something is probably wrong with the ROC or its models.
111
Andy Bavier840e0b42021-09-16 17:10:23 -0700112Start the 4G SD-CORE
113--------------------
114
115If you are installing the 5G SD-CORE, you can skip this step.
116
117To deploy the 4G SD-CORE and run a simple ping test::
118
119 make test
120
121By default the above commands install the 4G SD-CORE from the local charts in the Git repos cloned
122earlier. In order to install the SD-CORE using the latest published charts, add *CHARTS=latest*
123to the command, e.g.,::
124
125 CHARTS=latest make test
126
Andy Bavier99892132022-03-11 14:49:10 -0700127To install the Aether 2.0 release, add *CHARTS=release-2.0*::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700128
Andy Bavier99892132022-03-11 14:49:10 -0700129 CHARTS=release-2.0 make test
Andy Bavierf73c3d22021-08-30 10:29:06 -0700130
Fatemeh Rouzbeh104c01a2022-05-16 14:08:27 -0700131Getting Started with 4G AiaB
132^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1334G SD-CORE deploys the following core components to provide mobile connectivity:
134
135* SPGW (Serving/PDN Gateway): Combined Serving Gateway and Packet Data Network (PDN) Gateway
136* UPF (User Plane Function): The interconnect between the mobile infrastructure and the Data Network (DN).
137* PCRF (Policy and Charging Rules Function): Data flow detection, policy enforcement, and flow-based charging.
138* MME (Mobility Management Entity): Manages UE access network and mobility, and establishing the bearer path for UE.
139* HSS (Home Subscriber Server): The main subscriber database.
140
141.. figure:: images/4g-call-flow.png
142 :align: center
143 :width: 80 %
144
145 *Communication between 4G SD-CORE Components*
146
147The eNB (evolved Node B) is the Radio Access Network (RAN) of the 4G architecture and allows
148the UEs to connect to the Mobile network.
149It passes UE's attach request to MME via S1AP interface to be identified and authenticated through HSS.
150MME sends the session request to SPGW to create the GTP tunnel and request the default bearer. SPGW sends back the UPF
151address to establish the connectivity (GTP tunnel) to the DN through the user plane.
152
153When the AiaB is up, by configuring the routing table you
154can route traffic to arbitrary destinations through the AiaB user plane::
155
156 ip route add <Destination-Network-Address> dev oip1
157
158Or you can explicitly specify the *oip1* interface within the command, such as::
159
160 curl --interface oip1 google.com
161 ping -I oip1 google.com
162
163AiaB deploys a router pod in the "default" namespace with four interfaces: *ran-gw* for the radio network,
164*access-gw* for access network, *core-gw* for core network, and *eth0* for the external network.
165When a UE starts sending traffics to the data network through the user plane (access network),
166the outgoing data packets traverse the following path across the pods::
167
168 (oip1) enb-0 (enb) ==GTP==> (ran-gw) router (access-gw) ==GTP==> (access) upf-0 (core)
169 ----> (core-gw) router (NAT,eth0)
170
171And the incoming packets follow as::
172
173 (NAT,eth0) router (core-gw) ----> (core) upf-0 (access) ==GTP==> (access-gw) router (ran-gw)
174 ==GTP==> (enb) enb-0 (oip1)
175
176**Notes:** In the above notations, network interfaces within each pod are shown in parenthesis.
177The IP packets sent/received between the UE and external host via the user plane are GTP-encapsulated
178and tunneled between the eNB and UPF.
179
180Ksniff
181~~~~~~
182Ksniff is a Kubernetes-integrated packet sniffer shipped as a kubectl plugin.
183Ksniff uses tcpdump and Wireshark (Wireshark 3.x) to capture traffic on a specific pod within the cluster.
184After installing Ksniff using Krew and Wireshark, by running the following command
185you can see the communications between the components. Ksniff uses kubectl to upload
186the tcpdump binary into the target container (e.g. mme, upf, ...), and redirects the output to Wireshark::
187
188 kubectl ksniff -n omec mme-0
189
190You can see the packets sent/received between the core components from the moment an
191UE initiates the attach procedure through eNB until
192the dedicated bearer (uplink and downlink) has been established (see figure below).
193After the bearer has been established, traffic sent from UE's interface (*oip1*) will go through the eNB and UPF.
194
195.. figure:: images/wireshark-4g.png
196 :width: 80 %
197 :align: center
198
199 *Wireshark output of ksniff on mme pod*
200
201Using Ksniff on the router pod you can see all the packets exchanged between the UE and external hosts
202(e.g. ping an external host from the UE interface)::
203
204 kubectl ksniff -n default router
205
206.. figure:: images/4g-ue-ping.png
207 :width: 80 %
208 :align: center
209
210 *Data Flow from UE to an external host through the User Plane (filtered on UE's IP address)*
211
212Looking at the packet's details, the first and second packets are from *enb* to *router*
213and then to *upf* in a GTP tunnel. And the third packet is sent from *router* to the external network via NAT.
214The rest are the reply packets from the external host to the UE.
215
216By default, Ksniff runs *tcpdump* on all interfaces (i.e. *-i any*). To retrieve more details
217of packets (e.g. ethernet header information) on a specific interface,
218you can explicitly specify the interface along with options (e.g. *-e*). e.g.::
219
220 kubectl sniff -n default router -i access-gw -f "-e"
221
222For more information, please visit the links below:
223
224* `Ksniff <https://github.com/eldadru/ksniff>`_
225* `3gpp Spec <https://www.etsi.org/deliver/etsi_ts/136100_136199/136101/14.05.00_60/ts_136101v140500p.pdf>`_
226* `4G LTE Concepts and Call Flow <https://www.udemy.com/course/4g-lte-evolved-packet-core-deep-dive-and-call-flows/>`_
227
228
Andy Bavier840e0b42021-09-16 17:10:23 -0700229Start the 5G SD-CORE
230--------------------
Andy Bavierf73c3d22021-08-30 10:29:06 -0700231
Andy Bavier840e0b42021-09-16 17:10:23 -0700232If you have already installed the 4G SD-CORE, you must skip this step. Only one version of
233the SD-CORE can be installed at a time.
Andy Bavierf73c3d22021-08-30 10:29:06 -0700234
Andy Bavier1d631762022-01-10 15:47:51 -0800235To deploy the 5G SD-CORE and run a test with gNBSim that performs Registration + UE-initiated
236PDU Session Establishment + sends User Data packets::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700237
Andy Bavier1d631762022-01-10 15:47:51 -0800238 make 5g-test
Andy Bavierf73c3d22021-08-30 10:29:06 -0700239
Andy Bavier840e0b42021-09-16 17:10:23 -0700240By default the above commands install the 5G SD-CORE from the local charts in the Git repos cloned
241earlier. In order to install the SD-CORE using the latest published charts, add *CHARTS=latest*
242to the command, e.g.,::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700243
Andy Bavier1d631762022-01-10 15:47:51 -0800244 CHARTS=latest make 5g-test
Andy Bavierf73c3d22021-08-30 10:29:06 -0700245
Andy Bavier99892132022-03-11 14:49:10 -0700246To install the Aether 2.0 release, add *CHARTS=release-2.0*::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700247
Andy Bavier05eca6b2022-04-01 15:14:34 -0400248 CHARTS=release-2.0 make 5g-test
Andy Bavierf73c3d22021-08-30 10:29:06 -0700249
Andy Bavier1d631762022-01-10 15:47:51 -0800250To change the behavior of the test run by gNBSim, change the contents of *gnb.conf*
Andy Bavier4cda1402022-02-15 15:33:31 -0700251in *sd-core-5g-values.yaml*. Consult the
Andy Bavier1d631762022-01-10 15:47:51 -0800252`gNBSim documentation <https://docs.sd-core.opennetworking.org/master/developer/gnbsim.html>`_ for more information.
Andy Bavierf73c3d22021-08-30 10:29:06 -0700253
Andy Bavier4d27e4e2022-02-07 14:49:45 -0700254Exploring AiaB
255--------------
256
257The *kubectl* tool is the best way to get familiar with the pods and other Kubernetes objects installed by AiaB.
258The SD-CORE services, UPF, and simulated edge devices run in the *omec* namespace, while the ROC is running
259in the *aether-roc* namespace.
260
261The ROC GUI is available on port 31194 on the host running AiaB.
262
Andy Bavier840e0b42021-09-16 17:10:23 -0700263Cleanup
264-------
Andy Bavierf73c3d22021-08-30 10:29:06 -0700265
Andy Bavier840e0b42021-09-16 17:10:23 -0700266The first time you build AiaB, it takes a while because it sets up the Kubernetes cluster.
267Subsequent builds will be much faster if you follow these steps to clean up the Helm charts without
268destroying the Kubernetes cluster.
Andy Bavierf73c3d22021-08-30 10:29:06 -0700269
Andy Bavier840e0b42021-09-16 17:10:23 -0700270* Clean up the 4G SD-CORE: *make reset-test*
Andy Bavier72547672022-02-03 14:45:16 -0700271* Reset the 4G UE / eNB in order to re-run the 4G test: *make reset-ue*
Andy Bavier840e0b42021-09-16 17:10:23 -0700272* Clean up the 5G SD-CORE: *make reset-5g-test*
273* Clean up the ROC: *make roc-clean*
274
275It's normal for the above commands to take a minute or two to complete.
276
277As an example, suppose that you want to test the 4G SD-CORE with the ROC, and then the 5G SD-CORE
278with the ROC. You could run these commands::
279
280 CHARTS=latest make roc-4g-models # Install ROC with 4G configuration
281 CHARTS=latest make test # Install 4G SD-CORE and run ping test
282 make reset-test
283 make roc-clean
284 CHARTS=latest make roc-5g-models # Install ROC with 5G configuration
Andy Bavier1d631762022-01-10 15:47:51 -0800285 CHARTS=latest make 5g-test # Install 5G SD-CORE and run gNB Sim test
Andy Bavier840e0b42021-09-16 17:10:23 -0700286 make reset-5g-test
287 make roc-clean
288
Andy Bavier62678402022-04-18 12:06:52 -0700289To completely remove AiaB by tearing down the Kubernetes cluster, run *make clean*.
290
Andy Bavierb40b8fe2022-05-27 15:45:27 -0700291.. _developer-loop:
292
Andy Bavier840e0b42021-09-16 17:10:23 -0700293Developer Loop
294--------------
295
296Suppose you wish to test a new build of a 5G SD-CORE services. You can deploy custom images
Andy Bavier4cda1402022-02-15 15:33:31 -0700297by editing `~/aether-in-a-box/sd-core-5g-values.yaml`, for example::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700298
Andy Bavier4cda1402022-02-15 15:33:31 -0700299 omec-control-plane:
300 images:
301 tags:
302 webui: registry.aetherproject.org/omecproject/5gc-webui:onf-release3.0.5-roc-935305f
303 pullPolicy: IfNotPresent
Andy Bavierf73c3d22021-08-30 10:29:06 -0700304
Andy Bavier840e0b42021-09-16 17:10:23 -0700305To upgrade a running 5G SD-CORE with the new image, or to deploy the 5G SD-CORE with the image::
Andy Bavierf73c3d22021-08-30 10:29:06 -0700306
Andy Bavier4cda1402022-02-15 15:33:31 -0700307 make reset-5g-test; make 5g-test
Andy Bavier840e0b42021-09-16 17:10:23 -0700308
Andy Bavier320bb452022-05-27 15:22:28 -0700309Note that RKE2 (the default Kubernetes installer) is based on containerd rather than Docker.
310Containerd has its own local image registry that is separate from the local Docker Registry. With RKE2,
311if you have used `docker build` to build a local image, it is only in the Docker registry and so is not
312available to run in AiaB without some additional steps. An easy workaround
313is to use `docker push` to push the image to a remote repository (e.g., Docker Hub) and then modify your
314Helm values file to pull in that remote image. Another option is to save the local Docker image
315into a file and push the file to the containerd registry like this::
316
317 docker save -o /tmp/lte-uesoftmodem.tar omecproject/lte-uesoftmodem:1.1.0
318 sudo /var/lib/rancher/rke2/bin/ctr --address /run/k3s/containerd/containerd.sock --namespace k8s.io \
319 images import /tmp/lte-uesoftmodem.tar
320
321The above commands save the local Docker image `omecproject/lte-uesoftmodem:1.1.0` in a tarball, and then upload
Andy Bavier9c003dc2022-05-27 15:50:55 -0700322the tarball into the containerd registry where it is available for use by RKE2. Of course you should replace
323`omecproject/lte-uesoftmodem:1.1.0` with the name of your image.
Andy Bavier320bb452022-05-27 15:22:28 -0700324
325If you know that you are going to be using AiaB to test locally-built images, probably the easiest thing to do is to
326use the Kubespray installer. If you have already installed using RKE2 and you want to switch to Kubespray, first
Andy Bavierb40b8fe2022-05-27 15:45:27 -0700327run `make clean` before following the steps in the :ref:`rke2-vs-kubespray-install` section above.
Andy Bavier320bb452022-05-27 15:22:28 -0700328
Andy Bavier840e0b42021-09-16 17:10:23 -0700329Troubleshooting / Known Issues
330------------------------------
331
332If you suspect a problem, first verify that all pods are in Running state::
333
334 kubectl -n omec get pods
335 kubectl -n aether-roc get pods
336
Andy Bavier840e0b42021-09-16 17:10:23 -07003374G Test Fails
338^^^^^^^^^^^^^
339Occasionally *make test* (for 4G) fails for unknown reasons; this is true regardless of which Helm charts are used.
Andy Bavier72547672022-02-03 14:45:16 -0700340If this happens, first try recreating the simulated UE / eNB and re-running the test as follows::
341
342 make reset-ue
343 make test
344
345If that does not work, try cleaning up AiaB as described above and re-building it.
346
347If *make test* fails consistently, check whether the configuration has been pushed to the SD-CORE::
Andy Bavier840e0b42021-09-16 17:10:23 -0700348
349 kubectl -n omec logs config4g-0 | grep "Successfully"
350
351You should see that a device group and slice has been pushed::
352
353 [INFO][WebUI][CONFIG] Successfully posted message for device group 4g-oaisim-user to main config thread
354 [INFO][WebUI][CONFIG] Successfully posted message for slice default to main config thread
355
356Then tail the *config4g-0* log and make sure that the configuration has been successfully pushed to all
357SD-CORE components.
Andy Bavier2e20f972022-04-21 11:09:02 -0700358
3595G Test Fails
360^^^^^^^^^^^^^
361
362If the 5G test fails (*make 5g-test*) then you will see output like this::
363
364 2022-04-21T17:59:12Z [INFO][GNBSIM][Summary] Profile Name: profile2 , Profile Type: pdusessest
365 2022-04-21T17:59:12Z [INFO][GNBSIM][Summary] Ue's Passed: 2 , Ue's Failed: 3
366 2022-04-21T17:59:12Z [INFO][GNBSIM][Summary] Profile Errors:
367 2022-04-21T17:59:12Z [ERRO][GNBSIM][Summary] imsi:imsi-208930100007492, procedure:REGISTRATION-PROCEDURE, error:triggering event:REGESTRATION-REQUEST-EVENT, expected event:AUTHENTICATION-REQUEST-EVENT, received event:REGESTRATION-REJECT-EVENT
368 2022-04-21T17:59:12Z [ERRO][GNBSIM][Summary] imsi:imsi-208930100007493, procedure:REGISTRATION-PROCEDURE, error:triggering event:REGESTRATION-REQUEST-EVENT, expected event:AUTHENTICATION-REQUEST-EVENT, received event:REGESTRATION-REJECT-EVENT
369 2022-04-21T17:59:12Z [ERRO][GNBSIM][Summary] imsi:imsi-208930100007494, procedure:REGISTRATION-PROCEDURE, error:triggering event:REGESTRATION-REQUEST-EVENT, expected event:AUTHENTICATION-REQUEST-EVENT, received event:REGESTRATION-REJECT-EVENT
370 2022-04-21T17:59:12Z [INFO][GNBSIM][Summary] Simulation Result: FAIL
371
372In this case check whether the *webui* pod has restarted... this can happen if it times out waiting
373for the database to come up::
374
375 $ kubectl -n omec get pod -l app=webui
376 NAME READY STATUS RESTARTS AGE
377 webui-6b9c957565-zjqls 1/1 Running 1 (6m55s ago) 7m56s
378
379If the output shows any restarts, then restart the *simapp* pod to cause it to re-push its subscriber state::
380
381 $ kubectl -n omec delete pod -l app=simapp
382 pod "simapp-6c49b87c96-hpf82" deleted
383
384Re-run the 5G test, it should now pass.