free5GCとUERANSIMによるワンコール試験の実施

はじめに

free5GCとUERANSIMによるワンコール試験の実施する ワンコール試験で、UEの認証・登録・セッション確立・・経路確立・パケット送信(ping疎通)まで確認する。 free5GCとUERANSIMはHelm chartを用いて構築する。

環境

ネットワーク構成

free5GCとUERANSIMの構築

github.com 上記を参考に構築を行う。

free5GCの構築

gtp5g カーネルモジュールのインストール

Kubernetes worker nodesで動作するLinux kernel version が5.0.0-23-generic or 5.4.xであることを確認する。

$ uname -r
5.4.0-64-generic

gtp5g kernel moduleをインストールする

# 必要なライブラリのインストール
$ sudo apt install -y make gcc
    
# インストール
$ git clone -b v0.8.3 https://github.com/free5gc/gtp5g.git
$ cd gtp5g
$ make
make -C /usr/src/linux-headers-5.4.0-64-generic/ M=/home/ubuntu/gtp5g  modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-64-generic'
  CC [M]  /home/ubuntu/gtp5g/gtp5g.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/ubuntu/gtp5g/gtp5g.mod.o
  LD [M]  /home/ubuntu/gtp5g/gtp5g.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-64-generic'

$ sudo make install
modprobe udp_tunnel
cp gtp5g.ko /lib/modules/`uname -r`/kernel/drivers/net
depmod -a
modprobe gtp5g
echo "gtp5g" >> /etc/modules

# 確認
$ lsmod|grep -i gtp
gtp5g                 126976  0
udp_tunnel             16384  2 gtp5g,wireguard

Persistent Volumeの作成

free5GCで使用するMongoDBのデータを保存するためのPersistent Volume(PV)を作成する pvのデプロイ先はnodeAffinityで指定し、今回はmasterにデプロイする

$ cd ~
$ PVNAME=kubedata
$ mkdir $PVNAME

$ cat > pv.yaml << EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-local-pv1
  labels:
    project: free5gc
spec:
  capacity:
    storage: 8Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  local:
    path: /home/$(whoami)/$PVNAME
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - $(hostname)
EOF
$ kubectl apply -f pv.yaml

# 確認
$ kubectl get pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
example-local-pv1   8Gi        RWO            Retain           Available                                   5s

Helm repositoryの準備

$ helm repo add towards5gs 'https://raw.githubusercontent.com/Orange-OpenSource/towards5gs-helm/main/repo/'
$ helm repo update

# 確認
$ helm search repo |grep towards5gs
NAME                                            CHART VERSION   APP VERSION     DESCRIPTION
towards5gs/free5gc                              1.1.7           v3.3.0          A Helm chart to deploy Free5gc
towards5gs/free5gc-amf                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC AMF
towards5gs/free5gc-ausf                         0.2.7           v3.3.0          A Helm chart to deploy the Free5GC AUSF
towards5gs/free5gc-dbpython                     0.1.0           v3.3.0          A Helm chart to deploy the free5GC dbpython
towards5gs/free5gc-n3iwf                        0.2.5           v3.3.0          A Helm chart to deploy the Free5GC N3IWF
towards5gs/free5gc-nrf                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC NRF
towards5gs/free5gc-nssf                         0.2.7           v3.3.0          A Helm chart to deploy the Free5GC NSSF
towards5gs/free5gc-pcf                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC PCF
towards5gs/free5gc-smf                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC SMF
towards5gs/free5gc-udm                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC UDM
towards5gs/free5gc-udr                          0.2.7           v3.3.0          A Helm chart to deploy the Free5GC UDR
towards5gs/free5gc-upf                          0.2.6           v3.3.0          A Helm chart to deploy the Free5GC User Plane
towards5gs/free5gc-webui                        0.1.5           v3.3.0          A Helm chart to deploy the Free5GC WEBUI
towards5gs/free5gcControlPlane                  0.1.2           v3.0.5          DEPRECATED - A Helm chart to deploy the control...
towards5gs/free5gcN3iwf                         0.1.2           v3.0.5          DEPRECATED - A Helm chart to deploy the n3iwf f...
towards5gs/free5gcUserPlane                     0.1.2           v3.0.5          DEPRECATED - Helm chart to deploy the user plan...
towards5gs/networks5g                           0.1.2           0.1.2           DEPRECATED - A Helm chart to deploy the user pl...
towards5gs/ueransim                             2.0.17          v3.2.6          A Helm chart to deploy UERANSIM

Multusのインストール

最新バージョンはv4.0.2だが動作確認ができなかったため、動作確認ができたv3.9.3のバージョンのMultusをインストールする。

# ダウンロード
$ cd
$ MULTUSVERSION=v3.9.3
$ git clone -b $MULTUSVERSION https://github.com/k8snetworkplumbingwg/multus-cni.git

$ cd multus-cni

# デプロイ
$ kubectl apply -f ~/multus-cni/deployments/multus-daemonset-thick-plugin.yml

# 確認
$ kubectl get pods --all-namespaces | grep -i multus
kube-system   kube-multus-ds-h2f7c                       1/1     Running   0          23s

次に、使用するCNIのpluginをインストール 任意のディレクトリにソースをクローンする。versionは2024/01/22現在の最新のv1.4.0とする

$ cd ~
$ git clone -b v1.4.0 https://github.com/containernetworking/plugins
$ cd plugins

# Goをインストール 
$ wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.*.linux-amd64.tar.gz
$ echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bash_profile
$ source ~/.bash_profile

# 確認
$ go version
go version go1.21.6 linux/amd64

ビルド
$ ./build_linux.sh
Building plugins
bandwidth
firewall
flannel
portmap
sbr
tuning
bridge
host-device
ipvlan
loopback
macvlan
ptp
vlan
dhcp
host-local
static

# 必要なCNI pluginを/opt/cni/binにコピー
$ cd bin
$ sudo install -m 755 static /opt/cni/bin/static
$ sudo install -m 755 ipvlan /opt/cni/bin/ipvlan

free5GCのデプロイ

インターフェース名の変更

デフォルトのインターフェース名がeth0となっており、適宜に存在するインターフェースを指定する。 今回はenp2s0を指定する。

# インターフェースの確認
$ ip a show enp2s0
3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:91:a2:34 brd ff:ff:ff:ff:ff:ff

# enp2s0 を使って設定する例を記載
$ IFNAME=enp2s0
$ cd ~
$ helm pull towards5gs/free5gc --version 1.1.7
$ tar -zxvf  free5gc-1.*.tgz
$ sed -i s/eth0/$IFNAME/g free5gc/values.yaml
$ sed -i s/eth1/$IFNAME/g free5gc/values.yaml

# 確認
$ cat free5gc/values.yaml
(省略)
    masterIf: enp2s0
(合計5箇所を置換)

カーネルパラメータ変更

ネットワークの通信を行うためのカーネルパラメータを変更する。 起動前、その変更ができるようにPodに権限を付与する。 以下を参考に記載する。 github.com

$ vim free5gc/charts/free5gc-upf/values.yaml
upf:
(省略)
  securityContext:
    privileged: true
    #capabilities:
    #  add: ["NET_ADMIN"]

カーネルパラメータの変更方法はPodの起動後に実施する。

UPFのIPアドレス設定

free5GCのHelm chartのUPFのREADMEを読むと以下の記載がある。

github.com

In this section, we'll suppose that you have only one interface on each Kubernetes node and its name is toto. (中略) In addition, please make sure global.n6network.subnetIP, global.n6network.gatewayIP and upf.n6if.ipAddress parameters will match the IP address of the toto interface in order to make the UPF able to reach the Data Network via its N6 interface.

そのため、この設定を行う。 Kubernetes nodeのネットワークで使用するmultusは以下のenp2s0のIPアドレスを使用している。

$ ip a show enp2s0
3: enp2s0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:91:a2:34 brd ff:ff:ff:ff:ff:ff
    inet 172.31.16.65/24 brd 172.31.16.255 scope global enp2s0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe91:a234/64 scope link
       valid_lft forever preferred_lft forever

# 値を設定
$ vim free5gc/values.yaml
(以下の場所を変更)
global:
(中略)
  n6network:
(中略)
    subnetIP: 172.31.16.0
    cidr: 24
    gatewayIP: 172.31.16.1
    excludeIP: 172.31.16.254

$ vim free5gc/charts/free5gc-upf/values.yaml
(中略)
upf:
(中略)
  n6if:  # DN
    ipAddress: 172.31.16.65

デプロイ

$ helm install free5gc-v1 ./free5gc
NAME: free5gc-v1
LAST DEPLOYED: Tue Jan 16 02:28:04 2024
NAMESPACE: free5gc
STATUS: deployed
REVISION: 1
NOTES:
#
# Software Name : towards5gs-helm
# SPDX-FileCopyrightText: Copyright (c) 2021 Orange
# SPDX-License-Identifier: Apache-2.0
#
# This software is distributed under the Apache License 2.0,
# the text of which is available at https://github.com/Orange-OpenSource/towards5gs-helm/blob/main/LICENSE
# or see the "LICENSE" file for more details.
#
# Author: Abderaouf KHICHANE, Ilhem FAJJARI
# Software description: An open-source project providing Helm charts to deploy 5G components (Core + RAN) on top of Kubernetes
#
#
# Visit the project at https://github.com/Orange-OpenSource/towards5gs-helm
#

1. Get the list of created Pods by running:
  kubectl get pods --namespace free5gc -l "project="

Release notes (What's changed in this version):
- Fix TLS configuration for SBI communications

# podの起動状態確認
$ kubectl get po
NAME                                                    READY   STATUS    RESTARTS   AGE
free5gc-v1-free5gc-amf-amf-69c476d9cb-k47kz             1/1     Running   0          52s
free5gc-v1-free5gc-ausf-ausf-7675996f67-ch2bt           1/1     Running   0          51s
free5gc-v1-free5gc-dbpython-dbpython-7d4c7fd7f8-zc254   1/1     Running   0          52s
free5gc-v1-free5gc-nrf-nrf-55cffd6c79-ft4w2             1/1     Running   0          51s
free5gc-v1-free5gc-nssf-nssf-795f9f5577-79rdz           1/1     Running   0          51s
free5gc-v1-free5gc-pcf-pcf-797f677cfc-kzwk4             1/1     Running   0          51s
free5gc-v1-free5gc-smf-smf-766cddcd99-skk95             1/1     Running   0          51s
free5gc-v1-free5gc-udm-udm-684f7b8688-p4drb             1/1     Running   0          52s
free5gc-v1-free5gc-udr-udr-65cdb74d7d-tv7ch             1/1     Running   0          50s
free5gc-v1-free5gc-upf-upf-57c6c59d8b-9qw8f             1/1     Running   0          51s
free5gc-v1-free5gc-webui-webui-5b9b94bb95-x2q4n         1/1     Running   0          52s
mongodb-0                                               1/1     Running   0          51s

カーネルパラメータの変更:続き

UPFのPodのnet.ipv4.ip_forwardのカーネルパラメータを変更する

# kernel設定
$ export UPF_POD_NAME=$(kubectl get pods  -l "app.kubernetes.io/name=free5gc-upf" -o jsonpath="{.items[0].metadata.name}")
$ kubectl exec -it $UPF_POD_NAME -- /bin/sh

# pod内で処理の実行
# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# sysctl -p

# 確認
$ cat /proc/sys/net/ipv4/ip_forward
1
# podから抜ける
# exit

UEの登録

WebUIを使用して、UE登録を実施する。 まず、WebUIのserviceのポートを確認する

$ kubectl get svc
NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
free5gc-v1-free5gc-amf-service    ClusterIP   10.100.176.170   <none>        80/TCP           3m25s
free5gc-v1-free5gc-ausf-service   ClusterIP   10.109.108.66    <none>        80/TCP           3m25s
free5gc-v1-free5gc-nssf-service   ClusterIP   10.110.132.212   <none>        80/TCP           3m25s
free5gc-v1-free5gc-pcf-service    ClusterIP   10.97.213.17     <none>        80/TCP           3m25s
free5gc-v1-free5gc-smf-service    ClusterIP   10.106.40.61     <none>        80/TCP           3m25s
free5gc-v1-free5gc-udm-service    ClusterIP   10.111.214.98    <none>        80/TCP           3m25s
free5gc-v1-free5gc-udr-service    ClusterIP   10.107.9.106     <none>        80/TCP           3m25s
kubernetes                        ClusterIP   10.96.0.1        <none>        443/TCP          111m
mongodb                           ClusterIP   10.102.144.197   <none>        27017/TCP        3m25s
nrf-nnrf                          ClusterIP   10.102.196.165   <none>        8000/TCP         3m25s
webui-service                     NodePort    10.106.5.78      <none>        5000:30500/TCP   3m25s

# サービスは起動していそう
$ curl localhost:30500
<!doctype html><html lang="en" class="perfect-scrollbar-off"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>free5GC Web Console</title><link href="/static/css/main.e1d396c1.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><div class="clearfix"></div><div style="margin:14px;font-size:18px;float:left">Loading...</div><script type="text/javascript" src="/static/js/main.5cd6c424.js"></script></body></html>

この30500のポートにブラウザでアクセスする。 IDはadmin, PWはfree5GCでログインする。

[SUBSCRIBER]を押下する。次に[New Subscriber]を押下する

デフォルトの値で登録する。 以下の画面で登録されたことを確認する。

UERANSIMの構築

インターフェース名の変更

デフォルトのインターフェース名がeth0となっており、適宜に存在するインターフェースを指定する。

# インターフェースの確認
$ ip a show enp2s0
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000

# enp2s0 を使って設定する例を記載
$ IFNAME=enp2s0
$ cd ~
$ helm pull towards5gs/ueransim --version 2.0.17
$ tar -zxvf  ueransim-2.*.tgz
$ sed -i s/eth0/$IFNAME/g ueransim/values.yaml

# 確認
$ cat free5gc/values.yaml
(省略)
    masterIf: enp2s0
(合計2箇所を置換)

設定変更

デフォルトの設定では、ueが使用するinterfaceをホストに作成するが権限の都合で失敗する。 そのため、以下の追記で特権( privileged: true)を付与することを実施する

$ vim ueransim/values.yaml
ue:
(省略)
  podSecurityContext: {}
  securityContext:
    privileged: true
    #    capabilities:

デプロイ

$ helm install ueransim-v1 ./ueransim/
NAME: ueransim-v1
LAST DEPLOYED: Mon Jan 22 11:02:03 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
#
# Software Name : towards5gs-helm
# SPDX-FileCopyrightText: Copyright (c) 2021 Orange
# SPDX-License-Identifier: Apache-2.0
#
# This software is distributed under the Apache License 2.0,
# the text of which is available at https://github.com/Orange-OpenSource/towards5gs-helm/blob/main/LICENSE
# or see the "LICENSE" file for more details.
#
# Author: Abderaouf KHICHANE, Ilhem FAJJARI
# Software description: An open-source project providing Helm charts to deploy 5G components (Core + RAN) on top of Kubernetes
#
#
# Visit the project at https://github.com/Orange-OpenSource/towards5gs-helm
#

1. Run UE connectivity test by running these commands:
  helm --namespace default test ueransim-v1

If you want to run connectivity tests manually, follow:

1. Get the UE Pod name by running:
  export POD_NAME=$(kubectl get pods --namespace default -l "component=ue" -o jsonpath="{.items[0].metadata.name}")

2. Check that uesimtun0 interface has been created by running these commands:
  kubectl --namespace default logs $POD_NAME
  kubectl --namespace default exec -it $POD_NAME -- ip address

3. Try to access internet from the UE by running:
  kubectl --namespace default exec -it $POD_NAME -- ping -I uesimtun0 www.google.com
  kubectl --namespace default exec -it $POD_NAME -- curl --interface uesimtun0 www.google.com
  kubectl --namespace default exec -it $POD_NAME -- traceroute -i uesimtun0 www.google.com

Release notes (What's changed in this version):
- add the release notes
- add an initContainer to wait for the AMF to be ready
- enhance the handling of k8s NGAP service and network parameters

# 確認
$ kubectl get pods |grep ueransim
ueransim-v1-gnb-78b7d5dc89-8r5pw                        1/1     Running   0          100s
ueransim-v1-ue-54c6f9f67d-vkh2z                         1/1     Running   0          100s

ワンコール試験

UERANSIMのデプロイ時に出力されたログの手順を通して確認する。

$ export POD_NAME=$(kubectl get pods --namespace default -l "component=ue" -o jsonpath="{.items[0].metadata.name}")

$ kubectl --namespace default logs $POD_NAME
UERANSIM v3.2.6
[2024-01-22 04:15:07.044] [nas] [info] UE switches to state [MM-DEREGISTERED/PLMN-SEARCH]
[2024-01-22 04:15:09.248] [nas] [error] PLMN selection failure, no cells in coverage
[2024-01-22 04:15:11.450] [nas] [error] PLMN selection failure, no cells in coverage
[2024-01-22 04:15:12.046] [rrc] [warning] Acceptable cell selection failed, no cell is in coverage
[2024-01-22 04:15:12.046] [rrc] [error] Cell selection failure, no suitable or acceptable cell found
[2024-01-22 04:15:12.055] [rrc] [debug] New signal detected for cell[1], total [1] cells in coverage
[2024-01-22 04:15:12.055] [nas] [info] UE switches to state [MM-DEREGISTERED/NO-CELL-AVAILABLE]
[2024-01-22 04:15:19.902] [nas] [info] Selected plmn[208/93]
[2024-01-22 04:15:19.903] [rrc] [info] Selected cell plmn[208/93] tac[1] category[SUITABLE]
[2024-01-22 04:15:19.903] [nas] [info] UE switches to state [MM-DEREGISTERED/PS]
[2024-01-22 04:15:19.903] [nas] [info] UE switches to state [MM-DEREGISTERED/NORMAL-SERVICE]
[2024-01-22 04:15:19.903] [nas] [debug] Initial registration required due to [MM-DEREG-NORMAL-SERVICE]
[2024-01-22 04:15:19.904] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-01-22 04:15:19.904] [nas] [debug] Sending Initial Registration
[2024-01-22 04:15:19.904] [nas] [info] UE switches to state [MM-REGISTER-INITIATED]
[2024-01-22 04:15:19.905] [rrc] [debug] Sending RRC Setup Request
[2024-01-22 04:15:19.906] [rrc] [info] RRC connection established
[2024-01-22 04:15:19.906] [rrc] [info] UE switches to state [RRC-CONNECTED]
[2024-01-22 04:15:19.906] [nas] [info] UE switches to state [CM-CONNECTED]
[2024-01-22 04:15:19.941] [nas] [debug] Authentication Request received
[2024-01-22 04:15:19.954] [nas] [debug] Security Mode Command received
[2024-01-22 04:15:19.954] [nas] [debug] Selected integrity[2] ciphering[0]
[2024-01-22 04:15:19.971] [nas] [debug] Registration accept received
[2024-01-22 04:15:19.971] [nas] [info] UE switches to state [MM-REGISTERED/NORMAL-SERVICE]
[2024-01-22 04:15:19.971] [nas] [debug] Sending Registration Complete
[2024-01-22 04:15:19.971] [nas] [info] Initial Registration is successful
[2024-01-22 04:15:19.971] [nas] [debug] Sending PDU Session Establishment Request
[2024-01-22 04:15:19.972] [nas] [debug] UAC access attempt is allowed for identity[0], category[MO_sig]
[2024-01-22 04:15:20.256] [nas] [debug] PDU Session Establishment Accept received
[2024-01-22 04:15:20.256] [nas] [info] PDU Session establishment is successful PSI[1]
[2024-01-22 04:15:20.311] [app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.1.0.3] is up.

# uesimtun0が作成されていることを確認
$ kubectl --namespace default exec -it $POD_NAME -- ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if360: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default
    link/ether be:a5:cf:86:85:ba brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.10.39/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::bca5:cfff:fe86:85ba/64 scope link
       valid_lft forever preferred_lft forever
5: uesimtun0: <POINTOPOINT,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1400 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 10.1.0.3/32 scope global uesimtun0
       valid_lft forever preferred_lft forever
    inet6 fe80::2934:512f:8a10:4d0a/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

# ping疎通を確認
$ kubectl --namespace default exec -it $POD_NAME -- ping -I uesimtun0 www.google.com
PING www.google.com (142.251.42.164) from 10.1.0.1 uesimtun0: 56(84) bytes of data.
64 bytes from nrt12s46-in-f4.1e100.net (142.251.42.164): icmp_seq=1 ttl=115 time=10.1 ms
64 bytes from nrt12s46-in-f4.1e100.net (142.251.42.164): icmp_seq=2 ttl=115 time=7.40 ms
64 bytes from nrt12s46-in-f4.1e100.net (142.251.42.164): icmp_seq=3 ttl=115 time=7.08 ms

#総括 free5GCとUERANSIMによるワンコール試験を実施した。 free5GCの各podの機能やシーケンスをしっかりと理解したいと思う。

参考

github.com

qiita.com