Metonymical Deflection

ゆるく日々のコト・たまにITインフラ

CentOS8 小ネタ集その6:ディスクの拡張方法

CentOS8におけるLVMディスクの拡張方法を記載します。

基本手順はCentOS7と同一なのですが、xfs_growfsをする際、
CentOS7の場合

xfs_growfs /dev/cl/root

CentOS8 の場合

xfs_growfs /

の違いにより、とてもハマったのでその辺のポイントを記載したいと思います。

ちなみに、CentOS8で以下のコマンドを実行すると、
以下のようにエラーが出力されて拡張領域が反映されません。

[root@c80g167 ~]# xfs_growfs /dev/cl/root
xfs_growfs: /dev/cl/root is not a mounted XFS filesystem

以下、fdiskやLVMなど細かい説明は書きませんが、赤文字箇所だけ見てもらえればポイントは掴めると思います。

1.デバイスの拡張

今回はVMWareで以下のように拡張しますが、KVMではqemu-img resizeコマンドにより拡張してください。
f:id:metonymical:20200223001059p:plain
ここでは例として、200GB→250GBに拡張する場合とします。

2.現状確認とfdisk

[root@c80g167 ~]# df -hT
Filesystem          Type      Size  Used Avail Use% Mounted on
devtmpfs            devtmpfs  888M     0  888M   0% /dev
tmpfs               tmpfs     904M     0  904M   0% /dev/shm
tmpfs               tmpfs     904M  9.4M  894M   2% /run
tmpfs               tmpfs     904M     0  904M   0% /sys/fs/cgroup
/dev/mapper/cl-root xfs       197G  6.6G  191G   4% /
/dev/sda1           ext4      976M  134M  776M  15% /boot
tmpfs               tmpfs     181M   20K  181M   1% /run/user/0


[root@c80g167 ~]# fdisk -l
Disk /dev/sda: 250 GiB, 268435456000 bytes, 524288000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x47600f97

Device     Boot   Start       End   Sectors  Size Id Type
/dev/sda1  *       2048   2099199   2097152    1G 83 Linux
/dev/sda2       2099200 419430399 417331200  199G 8e Linux LVM

Disk /dev/mapper/cl-root: 197 GiB, 211472613376 bytes, 413032448 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/cl-swap: 2 GiB, 2197815296 bytes, 4292608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


[root@c80g167 ~]# fdisk /dev/sda

Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p
Disk /dev/sda: 250 GiB, 268435456000 bytes, 524288000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x47600f97

Device     Boot   Start       End   Sectors  Size Id Type
/dev/sda1  *       2048   2099199   2097152    1G 83 Linux
/dev/sda2       2099200 419430399 417331200  199G 8e Linux LVM

Command (m for help): n
Partition type
   p   primary (2 primary, 0 extended, 2 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (3,4, default 3): 空Enter
First sector (419430400-524287999, default 419430400): 空Enter
Last sector, +sectors or +size{K,M,G,T,P} (419430400-524287999, default 524287999): 空Enter

Created a new partition 3 of type 'Linux' and of size 50 GiB.

Command (m for help): t
Partition number (1-3, default 3): 3
Hex code (type L to list all codes): 8e

Changed type of partition 'Linux' to 'Linux LVM'.

Command (m for help): p
Disk /dev/sda: 250 GiB, 268435456000 bytes, 524288000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x47600f97

Device     Boot     Start       End   Sectors  Size Id Type
/dev/sda1  *         2048   2099199   2097152    1G 83 Linux
/dev/sda2         2099200 419430399 417331200  199G 8e Linux LVM
/dev/sda3       419430400 524287999 104857600   50G 8e Linux LVM

Command (m for help): w
The partition table has been altered.
Syncing disks.

3.LVM設定

[root@c80g167 ~]# vgextend cl /dev/sda3
  Volume group "cl" successfully extended
[root@c80g167 ~]# lvextend /dev/cl/root /dev/sda3
  Size of logical volume cl/root changed from <196.95 GiB (50419 extents) to <246.95 GiB (63218 extents).
  Logical volume cl/root successfully resized.

4.xfs_growfsとdf確認

[root@c80g167 ~]# xfs_growfs /
meta-data=/dev/mapper/cl-root    isize=512    agcount=4, agsize=12907264 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=51629056, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=25209, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 51629056 to 64735232

[root@c80g167 ~]# df -hT
Filesystem          Type      Size  Used Avail Use% Mounted on
devtmpfs            devtmpfs  888M     0  888M   0% /dev
tmpfs               tmpfs     904M     0  904M   0% /dev/shm
tmpfs               tmpfs     904M  9.4M  894M   2% /run
tmpfs               tmpfs     904M     0  904M   0% /sys/fs/cgroup
/dev/mapper/cl-root xfs       247G  7.0G  240G   3% /
/dev/sda1           ext4      976M  134M  776M  15% /boot
tmpfs               tmpfs     181M   16K  181M   1% /run/user/0

以上です。

5.最後に

以下のサイトを参考にさせて頂きました。
Extending Centos 8 root size - CentOS

冒頭にも書きましたが、最初は

xfs_growfs /

に気付かず、
resize2fsを試したりと、時間を浪費してしまったので、今回の記事を書きました。

OAI L2 nFAPI + Free5GCによるNSA 5GC構築方法

OAI(Open Air Interface)のL2 nFAPIシミュレータとFree5GCによる5GCoreの構築方法を記載します。
UEはOAIのLTE-UESoftModem、eNBはOAIのLTE-SoftModem、残り*1はFree5GCにて構築します。
構成としては、NSA(Non Stand Alone)型Option5のような構成となります。
以前に紹介した記事NSA型5GC版と考えて頂ければ、とっつきやすいかなと思います。
なお、以前の記事では、S5/S8区間で分離させましたが、今回は最小構成で構築する方法を記載した後、分離に関しては、別な機会に記載したいと考えています。*2

1.環境

1-1.VMWare
筐体                             : 自作PC(Win10pro)
CPU                           : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
VMWare              : VMware(R) Workstation 15 Pro 15.1.0 build-13591040  
OS                               : Ubuntu 18.04.3 LTS
Kernel                           : 4.15.0-72-generic
1-2.全体構成

f:id:metonymical:20200103094645p:plain
f:id:metonymical:20200103094710p:plain

1-3 .全体の流れ ~概要~
  1. 事前準備
  2. Free5GC設定
  3. OAI L2nFAPI設定
  4. 起動と動作確認

2.事前準備

ntp時刻同期、ホスト名設定などは省略します。

2-1.u18c131:L2nFAPIの事前設定

ens33は、マネジメントNW(aptやgitで使う)なのでインターネットに出られればOKです。

vi /etc/systemd/network/01-ens33.network

[Match]
Name=ens33

[Network]
Address=192.168.11.131/24
Gateway=192.168.11.1
DNS=192.168.11.1


vi /etc/systemd/network/03-ens35.network

[Match]
Name=ens35

[Network]
Address=10.20.0.131/24


vi /etc/hosts

127.0.0.1       localhost.localdomain   localhost u18c131
127.0.0.2       u18c131
2-2.u18c132:Free5GCの事前設定

こちらもens33は、同様です。

vi /etc/systemd/network/01-ens33.network

[Match]
Name=ens33

[Network]
Address=192.168.11.132/24
Gateway=192.168.11.1
DNS=192.168.11.1


vi /etc/systemd/network/02-ens34.network

[Match]
Name=ens34

[Network]
Address=10.10.0.136/24


vi /etc/systemd/network/03-ens35.network

[Match]
Name=ens35

[Network]
Address=10.20.0.132/24
Address=10.20.0.133/24
Address=10.20.0.134/24
Address=10.20.0.135/24
Address=10.20.0.136/24

3.Free5GC設定

3-1.MongoDBのインストール
apt-get update && \
apt-get -y install mongodb wget git && \
systemctl start mongodb && \
systemctl enable mongodb

systemctl status mongodb
3-2.Golangと各種パッケージのインストール
wget -q https://storage.googleapis.com/golang/getgo/installer_linux && \
chmod +x installer_linux && \
./installer_linux && \
source ~/.bash_profile

go get -u -v "github.com/gorilla/mux" && \
go get -u -v "golang.org/x/net/http2" && \
go get -u -v "golang.org/x/sys/unix"
3-3.uptunの設定

GTP終端インターフェースを作成します。*3

sh -c "cat << EOF > /etc/systemd/network/99-free5gc.netdev
[NetDev]
Name=uptun
Kind=tun
EOF"

systemctl enable systemd-networkd && \
systemctl restart systemd-networkd


vi /etc/network/interfaces

auto uptun
iface uptun inet static
	address 25.0.0.1
	netmask 255.255.0.0

ifup/downコマンドなどが必要であれば、事前にインストールしてください。*4

apt -y install ifupdown2
3-3.依存関係パッケージのインストール
apt-get -y install autoconf libtool gcc pkg-config git flex bison libsctp-dev \
libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev
3-4.Free5GCのビルド
cd ~/ && \
git clone https://bitbucket.org/nctu_5g/free5gc-stage-1.git && \
cd free5gc-stage-1 && \
autoreconf -iv && \
./configure --prefix=`pwd`/install && \
make -j `nproc` && \
make install
3-5.IP forwarding設定
sh -c "cat << EOF > /etc/init.d/ngc-network-setup
#!/bin/sh
### BEGIN INIT INFO 
# Provides:          ngc-network-setup 
# Required-Start:    networkd 
# Required-Stop:     networkd 
# Default-Start:     networkd 
# Default-Stop:      networkd 
# Short-Description: 
# Description:       
# 
### END INIT INFO

sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
iptables -I INPUT -i uptun -j ACCEPT
EOF"


chmod 755 /etc/init.d/ngc-network-setup && \
/etc/init.d/ngc-network-setup

ln -s /etc/init.d/ngc-network-setup /etc/rc3.d/S99ngc-network-setup && \
ln -s /etc/init.d/ngc-network-setup /etc/rc4.d/S99ngc-network-setup && \
ln -s /etc/init.d/ngc-network-setup /etc/rc5.d/S99ngc-network-setup

<補足>
公式手順ではMasqueradeの設定も入っていますが、私の経験上、N6(SGi)区間にはNATやDPI装置などが配置されており、UPF(PGW)でPATすることは皆無だったので削除しています。
これに伴い、L3SW上では以下のような戻りのルートを忘れずに設定しておいてください。

ip route 25.0.0.0 255.255.0.0 10.10.0.136
3-6.WebUIのインストール
apt-get -y install curl
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
apt-get -y install nodejs

cd /root/free5gc-stage-1/webui && \
npm install

#サービス起動
npm run dev

#アクセス先URL
http://192.168.11.132:3000/

インストール完了後、以下のページが表示されればOKです。
Username/Passwdは以下の通り。
admin/1423
f:id:metonymical:20200103103443p:plain

3-6.SIM情報の登録

上記のアクセス先URLから以下のSIM情報を登録します。*5

IMSI 208930100001111
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN internet
MSISDN 33611123456
IMSI 208930100001112
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN internet
MSISDN 33611123457

f:id:metonymical:20200103104030p:plain
IMSI, Subscriber Key(Ki), Operator Key(OPc), USIM Typeが必須項目となります。
APNは任意で構いませんが、この後のfree5gc.conf設定で使用します。
MSISDNは、ここでは設定不要ですが、OAISIMのビルド前に必要となりますので、念のため記載しています。

3-7.nextepc.conf設定

元からコメントされていた箇所は全て削除しています。
ens34, ens35のIP設定が同一環境であれば以下のconfをそのまま貼り付けでOKです。

vi /root/free5gc-stage-1/install/etc/free5gc/free5gc.conf

db_uri: mongodb://localhost/free5gc

logger:
    file: /root/free5gc-stage-1/install/var/log/free5gc/free5gc.log
    trace:
        app: 1
        s1ap: 1
        nas: 1
        diameter: 1
        gtp: 1
        pfcp: 1
        sbi: 1

parameter:
    no_ipv6: true

amf:
    freeDiameter: amf.conf

    s1ap:
      addr: 10.20.0.132

    gummei:
      plmn_id:
        mcc: 208
        mnc: 93
      mme_gid: 1
      mme_code: 1

    tai:
      plmn_id:
        mcc: 208
        mnc: 93
      tac: 1

    security:
        integrity_order : [ EIA1, EIA2, EIA0 ]
        ciphering_order : [ EEA0, EEA1, EEA2 ]

    network_name:
        full: free5GC

hss:
    freeDiameter: hss.conf

pcrf:
    freeDiameter: pcrf.conf

smf:
    freeDiameter: smf.conf

    pfcp:
      - addr: 10.20.0.134
#      - addr: ::1

    upf:
      - addr: 10.20.0.136

    http:
      addr: 10.20.0.134
      port: 8080

    ue_pool:
      - addr: 25.0.0.1/16
        apn: internet
#      - addr: cafe::1/64

    dns:
      - 8.8.8.8
#      - 8.8.4.4
#      - 2001:4860:4860::8888
#      - 2001:4860:4860::8844

upf:
    pfcp:
      addr:
        - 10.20.0.136
#        - ::1

    gtpu:
      - addr: 10.20.0.132
#      - addr: ::1

    ue_pool:
      - addr: 25.0.0.1/16
#      - addr: cafe::1/64

    dns:
      - 8.8.8.8
#      - 8.8.4.4
#      - 2001:4860:4860::8888
#      - 2001:4860:4860::8844
3-8.freeDiameter関連confの設定

各種設定ファイルは以下となります。

vi /root/free5gc-stage-1/install/etc/free5gc/freeDiameter/amf.conf
vi /root/free5gc-stage-1/install/etc/free5gc/freeDiameter/hss.conf
vi /root/free5gc-stage-1/install/etc/free5gc/freeDiameter/smf.conf
vi /root/free5gc-stage-1/install/etc/free5gc/freeDiameter/pcrf.conf

AMF→MME、SMF→SGWと読み換えれば基本的にNextEPCと変わりませんので、変更箇所がさほど気にならなければ以下の通り流し込んでください。

#AMFの設定
sed -i -e /^ListenOn/s/127.0.0.2/10.20.0.132/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/amf.conf
sed -i -e /^ConnectPeer/s/127.0.0.4/10.20.0.133/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/amf.conf

#HSSの設定
sed -i -e /^ListenOn/s/127.0.0.4/10.20.0.133/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/hss.conf
sed -i -e /^ConnectPeer/s/127.0.0.2/10.20.0.132/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/hss.conf

#SMFの設定
sed -i -e /^ListenOn/s/127.0.0.3/10.20.0.134/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/smf.conf
sed -i -e /^ConnectPeer/s/127.0.0.5/10.20.0.135/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/smf.conf

#PCRFの設定
sed -i -e /^ListenOn/s/127.0.0.5/10.20.0.135/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/pcrf.conf
sed -i -e /^ConnectPeer/s/127.0.0.3/10.20.0.134/g \
/root/free5gc-stage-1/install/etc/free5gc/freeDiameter/pcrf.conf
3-9.Free5GCの起動

「-d」オプションはDaemonとして起動させます。

cd ~/free5gc-stage-1 && \
./free5gc-ngcd -d

出力例
以下のようにDaemonが起動していればOKです。

root@u18c132:~/free5gc-stage-1# ./free5gc-ngcd -d
free5GC daemon v1.0.0 - Jan  3 2020 05:14:03

  PID[1803] : '/root/free5gc-stage-1/install/var/run/free5gc-ngcd/pid'
  File Logging : '/root/free5gc-stage-1/install/var/log/free5gc/free5gc.log'
  MongoDB URI : 'mongodb://localhost/free5gc'
  Configuration : '/root/free5gc-stage-1/install/etc/free5gc/free5gc.conf'
[01/03 10:56:58.093] PCRF try to initialize
root@u18c132:~/free5gc-stage-1# [01/03 10:56:58.140] PCRF initialize...done
[01/03 10:56:58.140] UPF try to initialize
[01/03 10:56:58.159] UPF initialize...done
[01/03 10:56:58.161] SMF try to initialize
[01/03 10:56:58.199] SMF initialize...done
[01/03 10:56:58.200] pfcp_server() [10.20.0.134]:8805
[01/03 10:56:58.200] pfcp_connect() [10.20.0.136]:8805
[01/03 10:56:58.200]  pfcp_xact_local_create 1 not freed in pfcp_xact_pool[64] of PFCP Transaction
[01/03 10:56:58.202] HSS try to initialize
[01/03 10:56:58.214] INFO: CONNECTED TO 'smf.localdomain' (TCP,soc#10): (fd_logger.c:93)
[01/03 10:56:58.215] INFO: CONNECTED TO 'pcrf.localdomain' (TCP,soc#16): (fd_logger.c:93)
[01/03 10:56:58.220] HSS initialize...done
[01/03 10:56:58.220] AMF try to initialize
[01/03 10:56:58.369] AMF initialize...done


[01/03 10:56:58.369] INFO: free5GC daemon start (main.c:157)
[01/03 10:56:58.371] INFO: CONNECTED TO 'amf.localdomain' (TCP,soc#8): (fd_logger.c:93)
[01/03 10:56:58.371] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#11): (fd_logger.c:93)
[01/03 10:56:58.376] s1ap_server() [10.20.0.132]:36412

終了させるときは、ps -auxなどで確認の上*6、kill -9などで停止させてください。

個別に起動させたい場合は以下の通りです。

cd ~/free5gc-stage-1
./free5gc-upfd -d
./nextepc-pcrfd -d
./free5gc-smfd -d
./free5gc-amfd -d
./nextepc-hssd -d

4.OAI L2nFAPI設定

4-1.git リポジトリの取得

UE用とeNB用でディレクトリを別けます。

git clone https://gitlab.eurecom.fr/oai/openairinterface5g/ enb_folder && \
cd enb_folder && \
git checkout -f v1.0.3 && \
cd .. && \
cp -Rf enb_folder ue_folder

<補足>
v1.1.x以降のブランチに格納されているbuild_oai では、-t ETHERNET オプションに対応していないため、v1.0系の最新版としています。

4-2.SIM情報の設定

変更箇所のみ抜粋。UEを2台アタッチさせられるように1台追加しています。

cd ~/ue_folder
vi openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf

#画面下の方にスクロール

UE0:
{
    USER: {
        IMEI="356113022094149";
        MANUFACTURER="EURECOM";
        MODEL="LTE Android PC";
        PIN="0000";
    };

    SIM: {
        MSIN="0100001111";
        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
        OPC="e734f8734007d6c5ce7a0508809e7e9c";
        MSISDN="33611123456";
    };

    # Home PLMN Selector with Access Technology
    HPLMN= "20893";

    # User controlled PLMN Selector with Access Technology
    UCPLMN_LIST = ();

    # Operator PLMN List
    OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028");

    # Operator controlled PLMN Selector with Access Technology
    OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204");

    # Forbidden plmns
    FPLMN_LIST = ();

    # List of Equivalent HPLMNs
#TODO: UE does not connect if set, to be fixed in the UE
#    EHPLMN_LIST= ("20811", "20813");
    EHPLMN_LIST= ();
};

#以下を追加
UE1:
{
    USER: {
        IMEI="356113022094150";
        MANUFACTURER="EURECOM";
        MODEL="LTE Android PC";
        PIN="0000";
    };

    SIM: {
        MSIN="0100001112";
        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
        OPC="e734f8734007d6c5ce7a0508809e7e9c";
        MSISDN="33611123457";
    };

    # Home PLMN Selector with Access Technology
    HPLMN= "20893";

    # User controlled PLMN Selector with Access Technology
    UCPLMN_LIST = ();

    # Operator PLMN List
    OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028");

    # Operator controlled PLMN Selector with Access Technology
    OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204");

    # Forbidden plmns
    FPLMN_LIST = ();

    # List of Equivalent HPLMNs
#TODO: UE does not connect if set, to be fixed in the UE
#    EHPLMN_LIST= ("20811", "20813");
    EHPLMN_LIST= ();
};
4-3.eNBの設定
cd ~/enb_folder
vi ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf

#画面下の方までスクロール

    ////////// MME parameters:
    mme_ip_address      = ( { ipv4       = "10.20.0.132";
                              ipv6       = "192:168:30::17";
                              active     = "yes";
                              preference = "ipv4";
                            }
                          );

    enable_measurement_reports = "no";

    ///X2
    enable_x2 = "no";
    t_reloc_prep      = 1000;      /* unit: millisecond */
    tx2_reloc_overall = 2000;      /* unit: millisecond */

    NETWORK_INTERFACES :
    {
        ENB_INTERFACE_NAME_FOR_S1_MME            = "ens35";
        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.20.0.131/24";
        ENB_INTERFACE_NAME_FOR_S1U               = "ens35";
        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.20.0.131/24";
        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
        ENB_IPV4_ADDRESS_FOR_X2C                 = "10.20.0.131/24";
        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422

    };
  }
);

MACRLCs = (
        {
        num_cc = 1;
        local_s_if_name  = "lo";
        remote_s_address = "127.0.0.2";
        local_s_address  = "127.0.0.1";
        local_s_portc    = 50001;
        remote_s_portc   = 50000;
        local_s_portd    = 50011;
        remote_s_portd   = 50010;
        tr_s_preference = "nfapi";
        tr_n_preference = "local_RRC";
        }
);
4-4.UEの設定
cd ~/ue_folder
vi ci-scripts/conf_files/ue.nfapi.conf

L1s = (
        {
        num_cc = 1;
        tr_n_preference = "nfapi";
        local_n_if_name  = "lo";
        remote_n_address = "127.0.0.1";
        local_n_address  = "127.0.0.2";
        local_n_portc    = 50000;
        remote_n_portc   = 50001;
        local_n_portd    = 50010;
        remote_n_portd   = 50011;
        }
);

<補足>
Loアドレスを使用している箇所は同一仮想マシンのためデフォルトのconfファイルから変更不要ですが、公式手順の図に合わせて、eNB:127.0.0.1、UE:127.0.0.2としています。*7
なお、eNBとUEを別筐体で稼働させる場合には、例として以下のように設定します。

#eNB:10.20.0.131 ens35
#UE :10.20.0.130 ens35

#eNBの設定
MACRLCs = (
        {
        num_cc = 1;
        local_s_if_name  = "ens35";
        remote_s_address = "10.20.0.130";
        local_s_address  = "10.20.0.131";
        local_s_portc    = 50001;
        remote_s_portc   = 50000;
        local_s_portd    = 50011;
        remote_s_portd   = 50010;
        tr_s_preference = "nfapi";
        tr_n_preference = "local_RRC";
        }
);

#UEの設定
L1s = (
        {
        num_cc = 1;
        tr_n_preference = "nfapi";
        local_n_if_name  = "ens35";
        remote_n_address = "10.20.0.131";
        local_n_address  = "10.20.0.130";
        local_n_portc    = 50000;
        remote_n_portc   = 50001;
        local_n_portd    = 50010;
        remote_n_portd   = 50011;
        }
);
4-5.eNBのビルド

初回は依存関係を解決するため、-I オプションを追加しています。
なお、-h にて全てのオプションが確認できます。

cd ~/enb_folder && \
source oaienv && \
cd cmake_targets && \
./build_oai --eNB -t ETHERNET -c -I

出力例
いくつかWarningが出力されますが、以下のような出力であれば正常にビルドが完了しています。

~~~一部省略~~~
WARNING: Parameterized type X2AP-PROTOCOL-IES expected for X2AP-PROTOCOL-IES at line 4997 in /root/enb_folder/openair2/X2AP/MESSAGES/ASN1/R14/x2ap-14.6.0.asn1
DEADLINE_SCHEDULER flag  is False
CPU_Affinity flag is False
flexran.proto: warning: Import control_delegation.proto but not used.
-- Found Yaml: /usr/lib/x86_64-linux-gnu/libyaml.so
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for one of the modules 'libxml-2.0'
-- Checking for one of the modules 'libxslt'
-- Checking for one of the modules 'openssl'
-- Checking for one of the modules 'libconfig'
-- Checking for one of the modules 'libcrypto'
-- Checking for one of the modules 'openpgm-5.1;openpgm-5.2'
-- Checking for one of the modules 'nettle'
NETTLE VERSION_INSTALLED  = 3.4
NETTLE_VERSION_MAJOR = 3
NETTLE_VERSION_MINOR = 4
-- Checking for one of the modules 'xpm'
-- Configuring done
-- Generating done
-- Build files have been written to: /root/enb_folder/cmake_targets/lte_build_oai/build
Compiling lte-softmodem
Log file for compilation has been written to: /root/enb_folder/cmake_targets/log/lte-softmodem.Rel14.txt
lte-softmodem compiled
WARNING: 9 warnings. See /root/enb_folder/cmake_targets/log/lte-softmodem.Rel14.txt
Log file for compilation has been written to: /root/enb_folder/cmake_targets/log/params_libconfig.Rel14.txt
params_libconfig compiled
Log file for compilation has been written to: /root/enb_folder/cmake_targets/log/coding.Rel14.txt
coding compiled
Log file for compilation has been written to: /root/enb_folder/cmake_targets/log/oai_eth_transpro.Rel14.txt
oai_eth_transpro compiled
WARNING: 1 warnings. See /root/enb_folder/cmake_targets/log/oai_eth_transpro.Rel14.txt
liboai_transpro.so is linked with ETHERNET library
10. Bypassing the Tests ...
4-6.UEのビルド

同一筐体でのビルドとなるため、-I オプションは不要です。

cd ~/ue_folder && \
source oaienv && \
cd cmake_targets && \
./build_oai --UE -t ETHERNET -c

#文字化けするため一旦ログアウト
exit

<補足>
ビルドの最後の方で、以下のように文字化けしますが、ビルドは正常に完了している(ハズなので)ので、exitで抜けて、再度ログインし直してください。

出力例
文字化けしますが、4-2で追加したSIM情報(赤文字箇所)が反映されていればOKです。

~~~一部省略~~~
WARNING: Parameterized type X2AP-PROTOCOL-IES expected for X2AP-PROTOCOL-IES at line 4997 in /root/ue_folder/openair2/X2AP/MESSAGES/ASN1/R14/x2ap-14.6.0.asn1
DEADLINE_SCHEDULER flag  is False
CPU_Affinity flag is False
flexran.proto: warning: Import control_delegation.proto but not used.
-- Found Yaml: /usr/lib/x86_64-linux-gnu/libyaml.so
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for one of the modules 'libxml-2.0'
-- Checking for one of the modules 'libxslt'
-- Checking for one of the modules 'openssl'
-- Checking for one of the modules 'libconfig'
-- Checking for one of the modules 'libcrypto'
-- Checking for one of the modules 'openpgm-5.1;openpgm-5.2'
-- Checking for one of the modules 'nettle'
NETTLE VERSION_INSTALLED  = 3.4
NETTLE_VERSION_MAJOR = 3
NETTLE_VERSION_MINOR = 4
-- Checking for one of the modules 'xpm'
-- Configuring done
-- Generating done
-- Build files have been written to: /root/ue_folder/cmake_targets/lte_build_oai/build
Compiling lte-uesoftmodem
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/lte-uesoftmodem.Rel14.txt
lte-uesoftmodem compiled
WARNING: 10 warnings. See /root/ue_folder/cmake_targets/log/lte-uesoftmodem.Rel14.txt
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/params_libconfig.Rel14.txt
params_libconfig compiled
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/coding.Rel14.txt
coding compiled
Compiling UE specific part
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/ue_ip.Rel14.txt
ue_ip compiled
WARNING: 1 warnings. See /root/ue_folder/cmake_targets/log/ue_ip.Rel14.txt
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for one of the modules 'libconfig'
-- Configuring done
-- Generating done
-- Build files have been written to: /root/ue_folder/cmake_targets/nas_sim_tools/build
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/usim.Rel14.txt
usim compiled
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/nvram.Rel14.txt
nvram compiled
Log file for compilation has been written to: /root/ue_folder/cmake_targets/log/conf2uedata.Rel14.txt
conf2uedata compiled
generate .ue_emm.nvram .ue.nvram

UE's non-volatile data:

IMEI            = 356113022094149
manufacturer    = EURECOM
model           = LTE Android PC
PIN             = 0000
UE identity data file: /root/ue_folder/targets/bin/.ue.nvram0

EMM non-volatile data:

IMSI            = 208.930.100001111
RPLMN           = 20893
EPS Mobility Management data file: /root/ue_folder/targets/bin/.ue_emm.nvram0

UE's non-volatile data:

IMEI            = 356113022094150
manufacturer    = EURECOM
model           = LTE Android PC
PIN             = 0000
UE identity data file: /root/ue_folder/targets/bin/.ue.nvram1

EMM non-volatile data:

IMSI            = 208.930.100001112
RPLMN           = 20893
EPS Mobility Management data file: /root/ue_folder/targets/bin/.ue_emm.nvram1
generate .usim.nvram

~~~一部省略~~~

        ヤ鳫褪゚ヤウイエオ゚ツ裴磋鴆           コ ーー
ユモノヘ 蓊 跌・コ ッ・ッ゚跣・褪ッ襁粳鉧ョ鳫ョⅷ敎
テ・鰀 ユナ 裙鱶鱚   ッ・ッ゚跣・褪ッ肬硴裃襁・裃糢鴈葹・魃糢鴈・
ァッ・ッ゚跣・褪ッ襁粳鉧ョ゚褊摠ⅷ擎ァ ュセ ァッ・ッ゚跣・褪ッ肬硴裃襁・裃糢鴈葹・魃糢鴈莟ョ゚褊摠ⅷ擎ァ
ァッ・ッ゚跣・褪ッ襁粳鉧ョョⅷ擎ァ ュセ ァッ・ッ゚跣・褪ッ肬硴裃襁・裃糢鴈葹・魃糢鴈莟ョョⅷ擎ァ
ァッ・ッ゚跣・褪ッ襁粳鉧ョ鳫ョⅷ擎ァ ュセ ァッ・ッ゚跣・褪ッ肬硴裃襁・裃糢鴈葹・魃糢鴈莟ョ鳫ョⅷ擎ァ
フ・ 跌・ 跣・胥瀇鴈磑鴆・鞦・粢褓 鴟・コ ッ・ッ゚跣・褪ッ肬硴裃襁・遽・鱇襁鞜碚ョメ褌アエョ・
・鱇襁鞜碚 胥瀇鴈裝
ラチメホノホヌコ ア 鴃銛ョ モ裹 ッ・ッ゚跣・褪ッ肬硴裃襁・遽・鱇襁鞜碚ョメ褌アエョ・
・糀硅゚碚ョ 鴣 ・鸙裝  ナヤネナメホナヤ ・糘碪・
アーョ ツ碯鰀 ・ヤ褫 ョョョ
・タク羈ウアコッ゚跣・褪ッ肬硴裃襁
・タク羈ウアコッ゚跣・褪ッ肬硴裃襁 褸鴟
・鉐

#文字化けしたままの状態となるため、exit と入力して*8ターミナル画面からログアウトしてください。

再度ログインした後、SIM関連ファイルをコピーします。

#SIM関連ファイルのコピー

cd ~/ue_folder/targets/bin/ && \
cp .u* ../../cmake_targets/ && \
cp usim ../../cmake_targets/ && \
cp nvram ../../cmake_targets/

5.起動と動作確認

起動の流れとしては以下の通りです。

  1. Free5GCの起動
  2. NAS UEレイヤーの初期化
  3. eNBの起動
  4. UEの起動
  5. 経路設定とPing疎通確認

ターミナル画面を複数起動した方が良いので以下に定義しておきます。

項番 工程 ターミナル ホスト名
1 Free5GCの起動 A u18c132
2 NAS UEレイヤーの初期化 B u18c131
3 eNBの起動 C u18c131
4 UEの起動 D u18c131
5 経路設定とPing疎通確認 B u18c131
5-1.Free5GCの起動
cd ~/free5gc-stage-1
./free5gc-ngcd -d

出力例
3-9に記載した出力例と同様です。
以下の状態は、eNBからのアクセスを待機しています。

♯ターミナルA:u18c132の出力
~~~3-9に記載した出力例と同様 一部省略~~~

[01/03 10:56:58.220] AMF try to initialize
[01/03 10:56:58.369] AMF initialize...done


[01/03 10:56:58.369] INFO: free5GC daemon start (main.c:157)
[01/03 10:56:58.371] INFO: CONNECTED TO 'amf.localdomain' (TCP,soc#8): (fd_logger.c:93)
[01/03 10:56:58.371] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#11): (fd_logger.c:93)
[01/03 10:56:58.376] s1ap_server() [10.20.0.132]:36412
5-2.NAS UEレイヤーの初期化

loアドレスの追加とoipインターフェース*9の追加を行います。

ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up && \
cd ~/ue_folder/cmake_targets/tools && \
source init_nas_s1 UE

出力例

♯ターミナルB:u18c131の出力
root@u18c131:~# ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up && \
> cd ~/ue_folder/cmake_targets/tools && \
> source init_nas_s1 UE
loading ue_ip
bring up oip1 interface for UE
net.ipv4.conf.all.log_martians = 1
Disabling reverse path filtering
net.ipv4.conf.all.rp_filter = 0
root@u18c131:~#
root@u18c131:~/ue_folder/cmake_targets/tools# ip add show
1: lo:  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
    inet 127.0.0.2/8 scope host secondary lo:
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:1a:a7:0b brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.131/24 brd 192.168.11.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe1a:a70b/64 scope link
       valid_lft forever preferred_lft forever
3: ens34:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:1a:a7:15 brd ff:ff:ff:ff:ff:ff
    inet 100.64.0.132/24 brd 100.64.0.255 scope global ens34
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe1a:a715/64 scope link
       valid_lft forever preferred_lft forever
4: ens35:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:1a:a7:1f brd ff:ff:ff:ff:ff:ff
    inet 10.20.0.131/24 brd 10.20.0.255 scope global ens35
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe1a:a71f/64 scope link
       valid_lft forever preferred_lft forever
5: oip1:  mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
6: oip2:  mtu 1500 qdisc noop state DOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00

~~~一部省略~~~

20: oip16:  mtu 1500 qdisc noop state DOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
5-3.eNBの起動

以下のコマンドでeNBを起動させます。
初回はログ出力ありの方がエラーを見つけやすいと思います。
しかし、大量にログが出力される=CPU負荷が増大するため、慣れてきたらログ出力なしにしてください。

♯ログ出力あり
cd ~/enb_folder/cmake_targets
sudo -E ./lte_build_oai/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf

♯ログ出力なし
cd ~/enb_folder/cmake_targets
sudo -E ./lte_build_oai/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1

出力例

♯ターミナルC:u18c131の出力
root@u18c131:~# cd ~/enb_folder/cmake_targets
root@u18c131:~/enb_folder/cmake_targets# sudo -E ./lte_build_oai/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf

[CONFIG] get parameters from libconfig ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf , debug flags: 0x00000000
[CONFIG] function config_libconfig_init returned 0
[CONFIG] config module libconfig loaded
[LIBCONFIG] config: 1/1 parameters successfully set, (1 to default value)
# /dev/cpu_dma_latency set to 0us
[LIBCONFIG] log_config: 3/3 parameters successfully set, (1 to default value)
[LIBCONFIG] log_config: 38/38 parameters successfully set, (32 to default value)
[LIBCONFIG] log_config: 38/38 parameters successfully set, (38 to default value)
[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value)
[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value)
log init done
Reading in command-line options
[LIBCONFIG] (root): 19/19 parameters successfully set, (16 to default value)
[LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value)
Getting ENBSParams
[LIBCONFIG] (root): 3/3 parameters successfully set, (1 to default value)
[LIBCONFIG] list L1s not found in config file ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf
[LIBCONFIG] list RUs not found in config file ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf
[LIBCONFIG] THREAD_STRUCT.[0]: 2/2 parameters successfully set, (0 to default value)
[LIBCONFIG] THREAD_STRUCT.[0]: 2/2 parameters successfully set, (0 to default value)
Configuration: nb_rrc_inst 1, nb_L1_inst 0, nb_ru 0
[LIBCONFIG] loader: 2/2 parameters successfully set, (2 to default value)
[LIBCONFIG] loader.NB_IoT: 2/2 parameters successfully set, (1 to default value)
[LOADER] library libNB_IoT.so is not loaded: libNB_IoT.so: cannot open shared object file: No such file or directory
               nb_nbiot_rrc_inst 0, nb_nbiot_L1_inst 0, nb_nbiot_macrlc_inst 0
[LIBCONFIG] TTracer: 4/4 parameters successfully set, (4 to default value)
configuring for RAU/RRU
CPU Freq is 3.605184
ITTI init, useMME: 1

~~~一部省略~~~

Waiting for PHY_config_req
Waiting for PHY_config_req
Waiting for PHY_config_req

♯UEがアタッチしてくるまで、Waiting for~のメッセージが出力され続けます。

♯ターミナルA:u18c132の出力
♯以下の出力が追加で表示されます
[01/03 12:27:38.048] eNB-S1 accepted[10.20.0.131]:36412 in s1_path module
[01/03 12:27:38.048] eNB-S1 accepted[10.20.0.131] in master_sm module
5-4.UEの起動

以下のコマンドでUEを起動させます。
eNBと同様に初回はログ出力あり慣れてきたらログ出力なしにしてください。
eNBよりも遥かに多くのログが出力されます。

♯ログ出力あり
cd ~/ue_folder/cmake_targets
sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3

♯ログ出力なし
sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 > ue.log 2>&1

♯ログ出力なし+複数UEを起動する場合
sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3  --num-ues 2 --nums_ue_thread 2 > ue.log 2>&1

<補足>
複数UEを起動する場合、スレッド数がUE数を超えないようにしてください。

UE数   :  --num-ues 2 
スレッド数:  --nums_ue_thread 2

出力例

♯ターミナルD:u18c131の出力
root@u18c131:~# cd ~/ue_folder/cmake_targets
root@u18c131:~/ue_folder/cmake_targets# sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3

[CONFIG] get parameters from libconfig ../ci-scripts/conf_files/ue.nfapi.conf , debug flags: 0x00000000
[CONFIG] function config_libconfig_init returned 0
[CONFIG] config module libconfig loaded
[LIBCONFIG] config: 1/1 parameters successfully set, (1 to default value)
# /dev/cpu_dma_latency set to 0us
[LIBCONFIG] log_config: 3/3 parameters successfully set, (1 to default value)
[LIBCONFIG] log_config: 38/38 parameters successfully set, (32 to default value)
[LIBCONFIG] log_config: 38/38 parameters successfully set, (38 to default value)
[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value)
[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value)
log init done
Reading in command-line options
[LIBCONFIG] (root): 19/19 parameters successfully set, (16 to default value)
[LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value)
Running with 1 UE instances
NFAPI_MODE value: 3
[LIBCONFIG] TTracer: 4/4 parameters successfully set, (4 to default value)
CPU Freq is 3.602254
ITTI init

~~~一部省略~~~

(null)(null)(null)[PHY]   () 94087899677169.4294967296 POPULATE UL_CONFIG_REQ sfn_sf:-1947431856 buffer_index:16
(null)[PHY]   Warning pack_tlv tag 0x8e7fb9a0 does not match expected 0x8bd681f1
(null)(null)[PHY]   () 94087899677169.139871851118624 POPULATE TX_REQ sfn_sf:-1947431560 buffer_index:16
(null)(null)(null)[PHY]   () 94087899677169.6241124384 POPULATE DL_CONFIG_REQ sfn_sf:-1947432120 buffer_index:16
(null)(null)(null)[PHY]   () 94087899677169.139871851118624 POPULATE TX_REQ sfn_sf:-1947431560 buffer_index:16
(null)(null)(null)[PHY]   () 94087899677169.6241124384 POPULATE DL_CONFIG_REQ sfn_sf:-1947432120 buffer_index:16
(null)[MAC]   dl_config_req_UE_MAC 2 Received data: sfn/sf:5747 PDU[0] size:39, TX_PDU index: 0, tx_req_num_elems: 1
♯上記のログが大量に出力され続けます。


♯ターミナルC:u18c131の出力
Waiting for PHY_config_req
Waiting for PHY_config_req
(null)(null)[PHY]   Accepting connection from PNF...
=椒:979172368 ull)[PHY]   PNF connection (fd:979172368) accepted from 貳
(null)(null)(null)[PHY]   MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:0x7fca3a5cfc10
(null)[VNF] pnf connection indication idx:0
[VNF] RC.eNB[0][0]. Mod_id:0 CC_id:0 nb_CC[0]:1 abstraction_flag:0 single_thread_flag:0 if_inst:(nil)
RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it
oai_create_enb() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values
oai_create_enb() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values
Waiting for PHY_config_req
[PHY]   Configuring MIB for instance 0, CCid 0 : (band 7,N_RB_DL 50, N_RB_UL 50, Nid_cell 0,eNB_tx_antenna_ports 1,Ncp 0,DL freq 3400,phich_config.resource 0, phich_config.duration 0)
[PHY]   Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY]   lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[LIBCONFIG] loader.coding: 2/2 parameters successfully set, (1 to default value)
[LOADER] library libcoding.so successfully loaded
oai_create_enb() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values
oai_create_enb() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values

~~~一部省略~~~

[S1AP]   [eNB 0] Chose MME '(null)' (assoc_id 1) through selected PLMN Identity index 0 MCC 208 MNC 93
[S1AP]   Found usable eNB_ue_s1ap_id: 0x06692d 420141(10)
[SCTP]   Successfully sent 96 bytes on stream 1 for assoc_id 1
[SCTP]   Found data for descriptor 59
[SCTP]   Received notification for sd 59, type 32777
[SCTP]   Found data for descriptor 59

(null)[PHY]   [eNB] sfn/sf:7000 old_sfn/sf:7000 proc[rx:6999]
(null)(null)[PHY]   (962386544/1185663553) 1006643512.1187473240 PNF to VNF phy_id:16 (t1/2/3/4:962386768, 962386576, 2720839680,       80) txrx:335546600 procT:713 latency(us):   8(avg:1138) offset(us):354025839 filtered(us):       0 wrap[t1:962386944 t2:0]
(null)(null)(null)[PHY]   PNF to VNF phy_id:962386640 adjustment1185663553 phy->previous_sf_offset_filtered:0 phy->previous_sf_offset_filtered:1187473480 phy->sf_offset_trend:16
(null)(null)(null)[PHY]   () LARGE SFN/SF DELTA between PNF and VNF delta:1185663553 VNF:962386912 PNF:1187474184

(null)(null)(null)[PHY]   (962386544/1185663553) 1006643512.1187473240 PNF to VNF phy_id:16 (t1/2/3/4:962386768, 962386576, 2720839680,       80) txrx:335546600 procT:765 latency(us):   0(avg:1138) offset(us):867330225 filtered(us):       0 wrap[t1:962386944 t2:0]
(null)[MAC]   UE  rnti 14e2 : in synch, PHR 21 dB DL CQI 0 PUSCH SNR 63 PUCCH SNR 63
(null)(null)[PHY]   () LARGE SFN/SF DELTA between PNF and VNF delta:1185663553 VNF:962386912 PNF:1187474184

(null)[PHY]   [eNB] sfn/sf:8000 old_sfn/sf:8000 proc[rx:7999]
(null)(null)[PHY]   () LARGE SFN/SF DELTA between PNF and VNF delta:1185663553 VNF:962386912 PNF:1187474184
♯上記のログが散発的に出力され続けます。


♯ターミナルA:u18c132の出力
♯以下の出力が追加で表示されます*10
[01/03 12:31:20.916] INFO: N11 message enter (smf_sm.c:210)
[01/03 12:31:20.916] INFO: APN_type: 2 (smf_context.c:1466)
[01/03 12:31:20.918]  pfcp_xact_local_create 1 not freed in pfcp_xact_pool[64] of PFCP Transaction
[01/03 12:31:20.920] INFO: PAA dst addr: 33554457 (amf_n11_handler.c:47)
[01/03 12:31:20.920] INFO: ipv4: 1, ipv6: 0 (amf_n11_handler.c:64)
[01/03 12:31:20.920] INFO: ipv4: 1, ipv6: 0 (amf_n11_handler.c:65)
[01/03 12:31:20.920] INFO: create Session (amf_n11_handler.c:71)
[01/03 12:31:20.919] PDN type: 0[01/03 12:31:20.919] PDN PAA PDn Type: 1[01/03 12:31:21.157] INFO: SMF Recieve Sm Context Update (smf_sbi_path.c:57)
[01/03 12:31:21.157] INFO: N11 message enter (smf_sm.c:210)
[01/03 12:31:21.157] smf_n4_seid : 1[01/03 12:31:21.157]  pfcp_xact_local_create 1 not freed in pfcp_xact_pool[64] of PFCP Transaction
[01/03 12:31:21.157] smf_n11_build_update_session_response SM 1
[01/03 12:31:21.157] smf_n11_build_update_session_response SM addr -1337395080
[01/03 12:31:21.157] INFO: smf_sbi_send_sm_context_update (smf_sbi_path.c:234)
[01/03 12:31:21.157] INFO: smf_sbi_send_sm_context_update end (smf_sbi_path.c:237)
[01/03 12:31:21.158] INFO: AMF Update Session Done (amf4g_sm.c:830)
5-5.経路設定とPing疎通確認

複数UEを起動する場合、明示的にインターフェース名を指定した方が無難です。*11

route add default gw 25.0.0.1 dev oip1
ping 10.10.0.254 -I oip1

出力例

♯ターミナルB:u18c131の出力
root@u18c131:~# route add default gw 25.0.0.1 dev oip1
root@u18c131:~# ping 10.10.0.254 -I oip1
PING 10.10.0.254 (10.10.0.254) from 25.0.0.3 oip1: 56(84) bytes of data.
64 bytes from 10.10.0.254: icmp_seq=1 ttl=63 time=35.6 ms
64 bytes from 10.10.0.254: icmp_seq=2 ttl=63 time=26.1 ms
64 bytes from 10.10.0.254: icmp_seq=3 ttl=63 time=21.4 ms
64 bytes from 10.10.0.254: icmp_seq=4 ttl=63 time=24.0 ms
64 bytes from 10.10.0.254: icmp_seq=5 ttl=63 time=23.1 ms
64 bytes from 10.10.0.254: icmp_seq=6 ttl=63 time=22.8 ms
64 bytes from 10.10.0.254: icmp_seq=7 ttl=63 time=28.3 ms

♯アドレスや経路情報の確認
root@u18c131:~# ip add show
5: oip1:  mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
    inet 25.0.0.4/8 brd 25.255.255.255 scope global oip1
       valid_lft forever preferred_lft forever
6: oip2:  mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
    inet 25.0.0.5/8 brd 25.255.255.255 scope global oip2
       valid_lft forever preferred_lft forever

root@u18c131:~# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    0      0        0 oip1
default         nvr500.md.jp    0.0.0.0         UG    0      0        0 ens33
10.20.0.0       0.0.0.0         255.255.255.0   U     0      0        0 ens35
25.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 oip1
25.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 oip2
100.64.0.0      0.0.0.0         255.255.255.0   U     0      0        0 ens34
192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 ens33

アタッチまでのシーケンスをPcapしたファイルはこちらにアップしました。

6.補足1

PingのRTTについて補足します。
上記結果のように20~40msくらいで安定しているときもあれば、以下のように1秒を超えるときもあります。
このため、RTTが多少遅くてもよい場合は、以前の記事で紹介したOAISIMのUE&eNBを使用した方がよいかと思います。*12
なお、稼働時間については、L2 nFAPI環境でも1時間近く動作した実績はあります。

64 bytes from 10.10.0.254: icmp_seq=285 ttl=63 time=46.0 ms
64 bytes from 10.10.0.254: icmp_seq=286 ttl=63 time=39.8 ms
64 bytes from 10.10.0.254: icmp_seq=287 ttl=63 time=2590 ms
64 bytes from 10.10.0.254: icmp_seq=288 ttl=63 time=4147 ms
64 bytes from 10.10.0.254: icmp_seq=289 ttl=63 time=3130 ms
64 bytes from 10.10.0.254: icmp_seq=290 ttl=63 time=2154 ms
64 bytes from 10.10.0.254: icmp_seq=291 ttl=63 time=1195 ms
64 bytes from 10.10.0.254: icmp_seq=292 ttl=63 time=199 ms
64 bytes from 10.10.0.254: icmp_seq=293 ttl=63 time=13.0 ms
64 bytes from 10.10.0.254: icmp_seq=294 ttl=63 time=2592 ms
64 bytes from 10.10.0.254: icmp_seq=295 ttl=63 time=4167 ms


以上です。

7.最後に

以下のサイトを参考にさせて頂きました。
https://www.free5gc.org/installation
https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/l2-nfapi-simulator/l2-nfapi-simulator-w-S1-same-machine

今年は5G元年ということなので、年明け最初の記事は、5G関連の技術トピックにフォーカスしてみました。
これからどんどん発展していくと思うと、とてもワクワクします。

3Gや4G/LTEはほぼ完成した状態から勉強を始めたので追いつくのが大変でしたが、5Gは進化の過程に合わせてキャッチアップしていけたらいいなと考えています。

なお、今年の目標ではないですが、前回記事
metonymical.hatenablog.com
で紹介したk8sのPodやvmi上にて、L2 nFAPI や Free5GCを動作させられたら面白そうだなと考えています。
k8s上でモバイルコアNWを構築するにあたり、c-planeの足回りはDPDK*13やXDPで捌きながら、u-planeはSR-IOVで捌けるような構成ができると、さらに面白味が増すかなと思っています。

*1:AMF,SMF,UPF,HSS,PCRF

*2:というのも、仮想マシンでOAIを動作させるのに限界を感じており、COTSサーバで構築した方が良さそうなので。加えて、Lowlatency Kernelなども使いたいので。

*3:公式の手順通りだと、.networkの設定を行ってもIPアドレスがうまくアサインされなかったため、/etc/network/interfacesに直書きしています。

*4:/etc/network/interfacesに直書きしても、IPアドレスアサインされなかった場合に備えてインストールしておいても良いと思います。

*5:Free5GCはNextEPCがベースとなっているため、画面はほぼ一緒です。

*6:5つのプロセスが起動していると思います。

*7:公式サイトでは逆になっているように見受けられたので。

*8:実際は・・・と表示されます

*9:UEのアドレスがアサインされるインターフェース

*10:出力されるまでに10秒くらい掛かる場合がありました。

*11:非対称になるとPingが返って来ないと勘違いするため

*12:OAISIMの場合、概ね80~90msくらいで推移します。

*13:年末にk8s上でのDPDK動作検証を実施したのですが挫折しました。。。正確に言うと、OvSでもVPPでもDPDK自体は動作したのですが、外部NWにトラフィックを流すことができませんでした。

CentOS8 KubernetesのSR-IOV設定方法

Kubernetes(以下、k8s)のSR-IOV設定方法を記載します。
PodとVMI(Virtual Machine Instance)の両方でそれぞれSR-IOVを設定していきます。

1.構成

1-1.環境
1.Master
VMWare              : VMware(R) Workstation 15 Pro 15.5.1 build-15018445 

2.Worker
筐体                             : ProLiant DL360p Gen8
System ROM                       : P71 05/24/2019
NIC                              : Intel X520-SR2(82599ES), X540-AT2

3.Master&Worker共通
OS                               : CentOS8.0(1905)
Kernel                           : 4.18.0-80.el8.x86_64
Installed Environment Groups     : 
  @^graphical-server-environment
  @container-management
  @development
  @virtualization-client
  @virtualization-hypervisor
  @virtualization-tools 

Kubernetes                       : 1.17.0
Docker                           : 19.03.5
flannel                          : latest
KubeVirt                         : 0.24.0
Multus                           : latest
sriov-cni                        : latest
sriov-network-device-plugin      : latest
1-2.全体の構成

f:id:metonymical:20191215102800p:plain

1-3.全体の流れ
  1. 事前準備
  2. k8s Cluster & flannelの構築
  3. KubeVirtの構築
  4. SR-IOV関連のビルド
  5. SR-IOV関連の設定
  6. VMIとPodのデプロイ

1~3までは比較的多くのドキュメントが存在しますので、重要な箇所以外はある程度割愛します。*1

2.事前準備

2-1.諸々の準備
SELinuxの無効化 : Master&Worker*2
sed -i -e "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

FW無効化 : Master&Worker
systemctl stop firewalld
systemctl disable firewalld

パススルー設定 : Master&Worker*3
sed -i -e "s/#options kvm_intel nested=1/options kvm_intel nested=1/g" /etc/modprobe.d/kvm.conf

swap無効化 : Master&Worker
vi /etc/fstab

#/dev/mapper/cl-swap     swap                    swap    defaults        0 0

hostsファイル設定 : Master&Worker*4
vi /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 c80g105.md.jp c80g105
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.11.105 c80g105 c80g105.md.jp
192.168.11.106 c80g106 c80g106.md.jp
2-2.HugePageとIOMMUの有効化 : Worker
sed -i -e "/GRUB_CMDLINE_LINUX=/s/\"$/ default_hugepagesz=1G hugepagesz=1G hugepages=16\"/g" /etc/default/grub
sed -i -e "/GRUB_CMDLINE_LINUX=/s/\"$/ intel_iommu=on iommu=pt pci=realloc\"/g" /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg

vi /etc/fstab

最終行に以下を追記
nodev  /mnt/huge_1GB hugetlbfs pagesize=1GB    0 0

hugepageの有効化
iommuの有効化
grubに設定反映
マウント

2-3.SR-IOVのVF設定 : Worker
vi /etc/rc.local

echo 8 > /sys/class/net/ens1f0/device/sriov_numvfs
echo 8 > /sys/class/net/ens1f1/device/sriov_numvfs
echo 8 > /sys/class/net/ens2f0/device/sriov_numvfs
echo 8 > /sys/class/net/ens2f1/device/sriov_numvfs
sleep 1
exit 0

chmod +x /etc/rc.d/rc.local

2枚のNICの各ポートにVFをそれぞれ8つづつ設定
実行権限付与

<補足>
過去記事では、Blacklistに追加していますが、今回は不要です。

2-4.vfio-pciの設定 : Worker
vi /etc/modprobe.d/vfio_pci.conf

options vfio_pci ids=8086:10ed

echo "vfio-pci" > /etc/modules-load.d/vfio-pci.conf
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modules-load.d/iommu.conf

vfio-pciを有効化するデバイス(NIC)のDeviceID設定
vfio-pciの永続化設定
vfio-pciのiommu利用の永続化

<補足(重要)>
DeviceIDはそれぞれ以下の通りとなります。

8086:10ed X520 VMI用 vfio-pci
8086:1515 X540 Pod用 ixgbevf

今回は2枚のNICでそれぞれVMI用とPod用として分けているため、vfio-pciを有効化するのは、X520のみとしています。*5
というのも、以下2点を確認したからです。*6

  • VMIでixgbevfを使用すると、kubectl get vmi上ではscheduledのまま固まります。flannelのIPはアサインされますがPingは通りません。*7
  • Podでvfio-pciNICを掴むことができませんでした。ip link showなどで確認しても追加されていません。

ここまでの準備が整ったらMaster&Workerを一旦再起動してください。

3.k8s Cluster & flannelの構築

3-1.Dockerのインストール : Master&Worker
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \
dnf -y install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.10-3.2.el7.x86_64.rpm && \
dnf -y install docker-ce && \
systemctl start docker && \
systemctl enable docker
3-3.k8sのインストール : Master&Worker
Master
dnf -y install kubeadm kubectl

Worker
dnf -y install kubeadm

Master&Worker
systemctl start kubelet.service && \
systemctl enable kubelet.service
3-4.Dockerの設定 : Master&Worker
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d

systemctl daemon-reload && \
systemctl restart docker
3-5.k8sClusterの構築 : Master
kubeadm init --apiserver-advertise-address=192.168.11.105 --pod-network-cidr=10.244.0.0/16

<出力例>
最後に以下の出力が表示されますので、赤文字部分をコピーしておいてください。
WorkerがMasterへJoinする際に使用します。

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.11.105:6443 --token 0gfh5j.vgu76alcycb2tc2e \
    --discovery-token-ca-cert-hash sha256:edcb1a3856838586a6ea7c99200daafa4fbb639e822838f4df81ce09d2faaac3 
3-6.k8s Cluster構築後の設定 : Master
コンフィグファイルのコピー
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

コマンド補完設定
echo "source <(kubectl completion bash)" >> ~/.bashrc
3-7.flannelのインストール : Master
mkdir /root/tmp && \
cd /root/tmp/ && \
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml && \
kubectl apply -f kube-flannel.yml

kubectl get nodes

<出力例>
以下のようにReadyとなるまで待ってください。

[root@c80g105 ~]# kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
c80g105.md.jp   Ready    master   48m   v1.17.0
3-8.WorkerのJoin : Worker
kubeadm join 192.168.11.105:6443 --token 0gfh5j.vgu76alcycb2tc2e \
    --discovery-token-ca-cert-hash sha256:edcb1a3856838586a6ea7c99200daafa4fbb639e822838f4df81ce09d2faaac3

<出力例>
以下のようにWorkerもReadyとなるまで待ってください。

[root@c80g105 ~]# kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
c80g105.md.jp   Ready    master   48m   v1.17.0
c80g106.md.jp   Ready    <none>   19s   v1.17.0

ここまでの準備が整ったらMaster&Workerをもう一度再起動してください。

4.KubeVirtの構築

4-1.KubeVirtインストール : Master
export RELEASE=v0.24.0
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml

<出力例>
Podの状態が以下のようにすべてRunningになるまでには、2分程度掛かります。

kubectl get pods -n kubevirt

[root@c80g116 ~]# kubectl -n kubevirt get pods
NAME                               READY   STATUS    RESTARTS   AGE
virt-api-64f59f44dd-prkj4          1/1     Running   3          70m
virt-api-64f59f44dd-w9984          1/1     Running   3          71m
virt-controller-79cc7fb59d-6bz7d   1/1     Running   3          70m
virt-controller-79cc7fb59d-wt8g4   1/1     Running   3          70m
virt-handler-ljfqg                 1/1     Running   5          88m
virt-operator-54db765c7d-4xkq5     1/1     Running   3          70m
virt-operator-54db765c7d-5bgw4     1/1     Running   3          64m

全てRunningになったら、以下のコマンドを実行

kubectl -n kubevirt wait kv kubevirt --for condition=Available

<出力例>
以下の出力が表示されればOKです。

[root@c80g105 ~]# kubectl -n kubevirt wait kv kubevirt --for condition=Available
kubevirt.kubevirt.io/kubevirt condition met
4-2.virtctlのインストール : Master : オプション

必須ではありませんが、vmiを操作する際に便利です。*8

export RELEASE=v0.24.0
curl -L -o virtctl \
    https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/virtctl-${RELEASE}-linux-amd64

chmod +x virtctl
chown root:root virtctl
mv virtctl /usr/bin
4-3.virtctlのインストール : Master : オプション

必須ではありませんが、virtctlはKrewを使ってもインストールできます。*9

export RELEASE=v0.3.3

set -x; cd "$(mktemp -d)" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/download/v0.3.3/krew.{tar.gz,yaml}" &&
tar zxvf krew.tar.gz &&
KREW=./krew-"$(uname | tr '[:upper:]' '[:lower:]')_amd64" &&
"$KREW" install --manifest=krew.yaml --archive=krew.tar.gz &&
"$KREW" update

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

kubectl krew install virt

echo 'PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc

5.SR-IOV関連のビルド

5-1.Golangのインストール : Master
dnf -y install epel-release golang
5-2.SR-IOV CNIのビルド : Master
git clone https://github.com/intel/sriov-cni.git && \
cd sriov-cni && \
make && \
cp build/sriov /opt/cni/bin

SRIOV CNIの実行ファイルをWorkerへコピー
scp /opt/cni/bin/sriov root@192.168.11.106:/opt/cni/bin/
5-3.SR-IOV Network Deviceのビルド : Master
cd ~/ && \
git clone https://github.com/intel/sriov-network-device-plugin.git && \
cd sriov-network-device-plugin && \
make

docker build -t nfvpe/sriov-device-plugin -f ./images/Dockerfile .

<出力例>

docker images

[root@c80g105 sriov-network-device-plugin]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
nfvpe/sriov-device-plugin            latest              a45310aae832        13 seconds ago      25.3MB
<none>                               <none>              b65d412dee59        19 seconds ago      905MB
k8s.gcr.io/kube-proxy                v1.17.0             7d54289267dc        6 days ago          116MB
k8s.gcr.io/kube-apiserver            v1.17.0             0cae8d5cc64c        6 days ago          171MB
k8s.gcr.io/kube-controller-manager   v1.17.0             5eb3b7486872        6 days ago          161MB
k8s.gcr.io/kube-scheduler            v1.17.0             78c190f736b1        6 days ago          94.4MB
golang                               alpine              69cf534c966a        8 days ago          359MB
k8s.gcr.io/coredns                   1.6.5               70f311871ae1        5 weeks ago         41.6MB
k8s.gcr.io/etcd                      3.4.3-0             303ce5db0e90        7 weeks ago         288MB
alpine                               latest              965ea09ff2eb        7 weeks ago         5.55MB
quay.io/coreos/flannel               v0.11.0-amd64       ff281650a721        10 months ago       52.6MB
k8s.gcr.io/pause                     3.1                 da86e6ba6ca1        24 months ago       742kB
5-4.SR-IOV Network Deviceのビルド : Worker
cd ~/ && \
git clone https://github.com/intel/sriov-network-device-plugin.git && \
cd sriov-network-device-plugin && \
docker build -t nfvpe/sriov-device-plugin -f ./images/Dockerfile .

<出力例>

docker images

[root@c80g106 sriov-network-device-plugin]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
nfvpe/sriov-device-plugin   latest              8c508ab37c1c        28 seconds ago      25.3MB
<none>                      <none>              571b3587b90d        34 seconds ago      855MB
k8s.gcr.io/kube-proxy       v1.17.0             7d54289267dc        6 days ago          116MB
golang                      alpine              69cf534c966a        8 days ago          359MB
alpine                      latest              965ea09ff2eb        7 weeks ago         5.55MB
quay.io/coreos/flannel      v0.11.0-amd64       ff281650a721        10 months ago       52.6MB
k8s.gcr.io/pause            3.1                 da86e6ba6ca1        24 months ago       742kB
kubevirt/virt-api           <none>              1a3697b92f09        49 years ago        293MB
kubevirt/virt-controller    <none>              ab9c8cce9c60        49 years ago        291MB
kubevirt/virt-handler       <none>              c5919b95ca31        49 years ago        313MB
kubevirt/virt-operator      <none>              45c6d543afb1        49 years ago        326MB

<補足>
この後の工程で、sriovdp-daemonset.yaml をデプロイするのですが、元から以下のように書かれているため、WorkerにおいてもDockerイメージをビルドしています。

      containers:
      - name: kube-sriovdp
        image: nfvpe/sriov-device-plugin
        imagePullPolicy: Never

6.SR-IOV関連の設定

以下のQuick Startに記載された順番に従い設定を行っていきます。
GitHub - intel/sriov-network-device-plugin: SRIOV network device plugin for Kubernetes

流れは以下の通りです。*10

  1. configMapの設定&デプロイ
  2. sriovdp-daemonsetのデプロイ
  3. Master:Multusのインストール
  4. sriov-crdの設定&デプロイ
  5. リソースの確認
6-1.ConfigMapの設定 : Master

ポイントは

"resourceName": "intel_sriov_netdevice1",
"resourceName": "intel_sriov_netdevice2",

として別けて記載している点です。
CRDやVMI&Podのyamlファイルにも一連の流れとして記載していくため、に別けて書いておきます。

既存ファイルを以下のように書き換えてください。

vi /root/sriov-network-device-plugin/deployments/configMap.yaml

[root@c80g105 ~]# vi /root/sriov-network-device-plugin/deployments/configMap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: sriovdp-config
  namespace: kube-system
data:
  config.json: |
    {
        "resourceList": [{
apiVersion: v1
kind: ConfigMap
metadata:
  name: sriovdp-config
  namespace: kube-system
data:
  config.json: |
    {
        "resourceList": [
            {
                "resourceName": "intel_sriov_netdevice1",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["154c", "10ed"],
                    "drivers": ["i40evf", "vfio-pci"]
                }
            },
            {
                "resourceName": "intel_sriov_netdevice2",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["154c", "1515"],
                    "drivers": ["i40evf", "ixgbevf"]
                }
            },
            {
                "resourceName": "intel_sriov_dpdk",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["154c", "10ed"],
                    "drivers": ["vfio-pci"],
                    "pfNames": ["enp0s0f0","enp2s2f1"]
                }
            },
            {
                "resourceName": "mlnx_sriov_rdma",
                "isRdma": true,
                "selectors": {
                    "vendors": ["15b3"],
                    "devices": ["1018"],
                    "drivers": ["mlx5_ib"]
                }
            }
        ]
    }

kubectl create -f /root/sriov-network-device-plugin/deployments/configMap.yaml

<出力例>

kubectl get configmaps -n kube-system

[root@c80g105 ~]# kubectl get configmaps -n kube-system
NAME                                 DATA   AGE
coredns                              1      4h32m
extension-apiserver-authentication   6      4h33m
kube-flannel-cfg                     2      4h32m
kube-proxy                           2      4h32m
kubeadm-config                       2      4h32m
kubelet-config-1.17                  1      4h32m
multus-cni-config                    1      3h16m
sriovdp-config                       1      3h16m

<補足>
先ほど記載した表の通りに別けて書いてあることが確認できると思います。

8086:10ed X520 VMI用 vfio-pci
8086:1515 X540 Pod用 ixgbevf
6-2.SRIOVDP DaemonSetのデプロイ : Master

特に修正する箇所はありませんので、yamlファイルの中身を確認せず、以下のコマンドを入力しても構いません。

kubectl create -f /root/sriov-network-device-plugin/deployments/k8s-v1.16/sriovdp-daemonset.yaml
vi /root/sriov-network-device-plugin/deployments/k8s-v1.16/sriovdp-daemonset.yaml

[root@c80g105 ~]# vi /root/sriov-network-device-plugin/deployments/k8s-v1.16/sriovdp-daemonset.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sriov-device-plugin
  namespace: kube-system

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-sriov-device-plugin-amd64
  namespace: kube-system
  labels:
    tier: node
    app: sriovdp
spec:
  selector:
    matchLabels:
      name: sriov-device-plugin
  template:
    metadata:
      labels:
        name: sriov-device-plugin
        tier: node
        app: sriovdp
    spec:
      hostNetwork: true
      hostPID: true
      nodeSelector:
        beta.kubernetes.io/arch: amd64
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      serviceAccountName: sriov-device-plugin
      containers:
      - name: kube-sriovdp
        image: nfvpe/sriov-device-plugin
        imagePullPolicy: Never
        args:
        - --log-dir=sriovdp
        - --log-level=10
        securityContext:
          privileged: true
        volumeMounts:
        - name: devicesock
          mountPath: /var/lib/kubelet/
          readOnly: false
        - name: log
          mountPath: /var/log
        - name: config-volume
          mountPath: /etc/pcidp
      volumes:
        - name: devicesock
          hostPath:
            path: /var/lib/kubelet/
        - name: log
          hostPath:
            path: /var/log
        - name: config-volume
          configMap:
            name: sriovdp-config
            items:
            - key: config.json
              path: config.json

kubectl create -f /root/sriov-network-device-plugin/deployments/k8s-v1.16/sriovdp-daemonset.yaml

<出力例>*11

kubectl get pods -n kube-system

[root@c80g105 ~]# kubectl get pods -n kube-system
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-6955765f44-cn2xp                1/1     Running   1          4h35m
coredns-6955765f44-z9dj6                1/1     Running   1          4h35m
etcd-c80g105.md.jp                      1/1     Running   1          4h35m
kube-apiserver-c80g105.md.jp            1/1     Running   1          4h35m
kube-controller-manager-c80g105.md.jp   1/1     Running   1          4h35m
kube-flannel-ds-amd64-7ltvr             1/1     Running   1          4h35m
kube-flannel-ds-amd64-rfr4f             1/1     Running   1          4h35m
kube-multus-ds-amd64-475wf              1/1     Running   0          3h19m
kube-multus-ds-amd64-9zz5d              1/1     Running   0          3h19m
kube-proxy-dmqvr                        1/1     Running   1          4h35m
kube-proxy-pwmx2                        1/1     Running   0          4h35m
kube-scheduler-c80g105.md.jp            1/1     Running   1          4h35m
kube-sriov-device-plugin-amd64-c2szn    1/1     Running   0          3h19m
kube-sriov-device-plugin-amd64-ttwj5    1/1     Running   0          3h19m
6-3.Multusのインストール : Master

ここも特に設定変更などは不要です。

cd /root && \
git clone https://github.com/intel/multus-cni.git && \
cd multus-cni && \
cat ./images/multus-daemonset.yml | kubectl apply -f -

<出力例>
デプロイ後、以下のような出力が表示されればOKです。

kubectl get pods --all-namespaces | grep -i multus

[root@c80g105 multus-cni]# kubectl get pods --all-namespaces | grep -i multus
kube-system   kube-multus-ds-amd64-7kc44              1/1     Running   0          51s
kube-system   kube-multus-ds-amd64-8ds8r              1/1     Running   0          51s
6-4.SRIOV CRDの設定 : Master
8086:10ed X520 VMI用 vfio-pci

上記VMI用のCRD(Custom Resource Decleration)の設定を行っていきます。
ポイントはannotationsのresourceNameがconfigMap.yamlと一致している点です。
加えて、この後に設定するVMI用yamlにsriov-net1を記載します。

vi /root/sriov-network-device-plugin/deployments/sriov-crd1.yaml

[root@c80g105 ~]# vi /root/sriov-network-device-plugin/deployments/sriov-crd1.yaml

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: sriov-net1
  annotations:
    k8s.v1.cni.cncf.io/resourceName: intel.com/intel_sriov_netdevice1
spec:
  config: '{
  "type": "sriov",
  "cniVersion": "0.3.1",
  "name": "sriov300_1",
  "vlan": 300,
  "ipam": {
    "type": "host-local",
    "subnet": "192.168.30.0/24",
    "routes": [{
      "dst": "0.0.0.0/0"
    }],
    "gateway": "192.168.30.254"
  }
}'

kubectl create -f /root/sriov-network-device-plugin/deployments/sriov-crd1.yaml


続いて、Pod用のCRD設定を行っていきます。

8086:1515 X540 Pod用 ixgbevf
vi /root/sriov-network-device-plugin/deployments/sriov-crd2.yaml

[root@c80g105 ~]# vi /root/sriov-network-device-plugin/deployments/sriov-crd2.yaml

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: sriov-net2
  annotations:
    k8s.v1.cni.cncf.io/resourceName: intel.com/intel_sriov_netdevice2
spec:
  config: '{
  "type": "sriov",
  "cniVersion": "0.3.1",
  "name": "sriov300_2",
  "vlan": 300,
  "ipam": {
    "type": "host-local",
    "subnet": "192.168.30.0/24",
    "routes": [{
      "dst": "0.0.0.0/0"
    }],
    "gateway": "192.168.30.254"
  }
}'

kubectl create -f /root/sriov-network-device-plugin/deployments/sriov-crd2.yaml

<出力例>
以下のように表示されればOKです。

[root@c80g105 ~]# kubectl get network-attachment-definitions
NAME         AGE
sriov-net1  3h29m
sriov-net2  3h29m
6-5.リソースの確認 : Master

SR-IOVのVFがWorkerのリソースとしてk8sに認識されていることを確認します。

dnf -y install jq
kubectl get node c80g106.md.jp -o json | jq '.status.allocatable'

<出力例>
以下のような出力が表示されればOKです。

[root@c80g105 ~]# kubectl get node c80g106.md.jp -o json | jq '.status.allocatable'
{
  "cpu": "40",
  "devices.kubevirt.io/kvm": "110",
  "devices.kubevirt.io/tun": "110",
  "devices.kubevirt.io/vhost-net": "110",
  "ephemeral-storage": "400024062519",
  "hugepages-1Gi": "16Gi",
  "intel.com/intel_sriov_dpdk": "0",
  "intel.com/intel_sriov_netdevice": "0",
  "intel.com/intel_sriov_netdevice1": "16",
  "intel.com/intel_sriov_netdevice2": "16",
  "intel.com/mlnx_sriov_rdma": "0",
  "memory": "313085984Ki",
  "pods": "110"
}

7.VMIとPodのデプロイ

VMI用として事前にqcow2イメージファイルを作成しておきます。*12
以下の過去記事などを参照の上、適当な仮想マシンを作成してください。
CentOS7 kickstartによるインストール - Metonymical Deflection
CentOS8 kickstartによるインストール - Metonymical Deflection

ここでは、CentOS7.7をインストールしたqcow2ファイルが、/root直下に既に存在する前提として話を進めます。

7-1.VMI用のイメージ登録 : Worker
イメージファイルのコピー
mkdir /root/docker
cd /root/docker
cp /root/c771.qcow2 ./

ビルド用のDockerfile作成
cat << END > Dockerfile
FROM scratch
ADD c771.qcow2 /disk/
END

イメージのビルド
docker build -t vmidisks/centos:7.7 .

<出力例>

[root@c80g106 docker]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
vmidisks/centos             7.7                 f5a39b56e448        21 seconds ago      1.64GB
nfvpe/sriov-device-plugin   latest              8c508ab37c1c        6 minutes ago       25.3MB
<none>                      <none>              571b3587b90d        7 minutes ago       855MB
k8s.gcr.io/kube-proxy       v1.17.0             7d54289267dc        6 days ago          116MB
golang                      alpine              69cf534c966a        8 days ago          359MB
nfvpe/multus                v3.4                7cf8e2d1b733        10 days ago         312MB
alpine                      latest              965ea09ff2eb        7 weeks ago         5.55MB
quay.io/coreos/flannel      v0.11.0-amd64       ff281650a721        10 months ago       52.6MB
k8s.gcr.io/pause            3.1                 da86e6ba6ca1        24 months ago       742kB
kubevirt/virt-handler       <none>              c5919b95ca31        49 years ago        313MB
kubevirt/virt-controller    <none>              ab9c8cce9c60        49 years ago        291MB
kubevirt/virt-api           <none>              1a3697b92f09        49 years ago        293MB
kubevirt/virt-operator      <none>              45c6d543afb1        49 years ago        326MB
7-2.VMIのデプロイ : Master
vi /root/sriov-network-device-plugin/deployments/c771.yaml

[root@c80g105 deployments]# vi /root/sriov-network-device-plugin/deployments/c771.yaml

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachineInstance
metadata:
  name: c771
spec:
  domain:
    resources:
      requests:
        memory: "2048Mi"
        cpu: "1"
    devices:
      disks:
      - name: containerdisk
        disk:
          bus: virtio
      interfaces:
      - name: pod
        bridge: {}
      - name: net1
        sriov: {}
      - name: net2
        sriov: {}
  volumes:
  - name: containerdisk
    containerDisk:
      image: vmidisks/centos:7.7
      imagePullPolicy: Never
  networks:
  - name: pod
    pod: {}
  - name: net1
    multus:
      networkName: sriov-net1
  - name: net2
    multus:
      networkName: sriov-net1


kubectl create-f /root/sriov-network-device-plugin/deployments/c771.yaml

<出力例>

kubectl get pods
kubectl get vmi

[root@c80g105 ~]# kubectl get pods
kubectl get vmi
NAME                       READY   STATUS    RESTARTS   AGE
virt-launcher-c771-5kdr2   2/2     Running   0          3h29m

[root@c80g105 ~]# kubectl get vmi
NAME   AGE     PHASE     IP               NODENAME
c771   3h29m   Running   10.244.1.14/24   c80g106.md.jp

<補足>
ポイントを5点ほど。

  1. multus: > networkName: に先ほど作成したCRDの名前sriov-net1を指定している点です。これにより、明示的にX520を使用する設定*13となっています。
  2. spec: > domain: > resources: には、requests:のみを記載している点です。ここでlimits: を追記すると起動後に高確率でOOM Killerが発動しVMIが瞬殺されます。*14
  3. kubectl get podsにて、READYが2/2になっています。これはVMIに加えて、virt-launcherが起動しているためです。
  4. kubectl get vmiにて、IPが10.244.1.14/24*15となっています。IPアドレス自体「10.244.1.14」は、PHASEがRunningになると、すぐに表示されます。しかし、私の環境ではプリフィックス「 /24 」が表示されるまでに90秒程度かかりました。また、プリフィックスが表示されなくてもログインできる場合があります。*16
  5. SR-IOVにてアサインされたNICが保持するIPアドレスを確認するためには、VMIへのログインが必要なので、virtctl console コマンドやsshなどでVMIにログインしてください。ログイン後、ip add showすると、以下のように見えると思います。eth1とeth2のMACアドレスがWorkerのVFのMACアドレスと一致していることを確認してください。加えて、外部NW機器にPingが通ることを確認できれば構築完了です。
[root@c771 ~]# ip add show
1: lo:  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: eth0:  mtu 1450 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 8e:29:cb:fc:87:4a brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.14/24 brd 10.244.1.255 scope global noprefixroute dynamic eth0
       valid_lft 86312966sec preferred_lft 86312966sec
    inet6 fe80::f6a2:e021:e183:9852/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: eth1:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 96:e5:96:36:1c:90 brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.139/24 brd 192.168.30.255 scope global noprefixroute dynamic eth1
       valid_lft 2966sec preferred_lft 2966sec
    inet6 fe80::409f:ff:fe56:8741/64 scope link 
       valid_lft forever preferred_lft forever
4: eth2:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 9e:46:96:a2:4b:4e brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.138/24 brd 192.168.30.255 scope global noprefixroute dynamic eth2
       valid_lft 2966sec preferred_lft 2966sec
    inet6 fe80::6c:5eff:fee0:56ca/64 scope link 
       valid_lft forever preferred_lft forever

Worker上では以下のように認識されます。

[root@c80g106 ~]# ip link show
  一部省略
6: ens1f0:  mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 90:e2:ba:0b:37:b8 brd ff:ff:ff:ff:ff:ff
    vf 0 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 1 MAC 96:e5:96:36:1c:90, vlan 300, spoof checking on, link-state auto, trust off, query_rss off
    vf 2 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 3 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 4 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 5 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 6 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 7 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
7: ens1f1:  mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 90:e2:ba:0b:37:b9 brd ff:ff:ff:ff:ff:ff
    vf 0 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 1 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 2 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 3 MAC 9e:46:96:a2:4b:4e, vlan 300, spoof checking on, link-state auto, trust off, query_rss off
    vf 4 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 5 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 6 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off
    vf 7 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off, query_rss off

7-3.Podのデプロイ
vi /root/sriov-network-device-plugin/deployments/pod2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  annotations:
    k8s.v1.cni.cncf.io/networks: sriov-net2
spec:
  containers:
  - name: pod2
    image: docker.io/centos/tools:latest
    command:
    - /sbin/init
    resources:
      requests:
        intel.com/intel_sriov_netdevice2: '1'
      limits:
        intel.com/intel_sriov_netdevice2: '1'

kubectl create -f /root/sriov-network-device-plugin/deployments/pod2.yaml

<出力例>

[root@c80g105 ~]# kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
pod2                       1/1     Running   1          11h   10.244.1.19   c80g106.md.jp              
virt-launcher-c771-cp2nk   2/2     Running   0          23m   10.244.1.27   c80g106.md.jp              

<補足>
ポイントを3点ほど。

  1. annotations: > k8s.v1.cni.cncf.io/networks: に先ほど作成したCRDの名前sriov-net2を指定している点です。これにより、明示的にX540を使用する設定*17となっています。
  2. resources: > requests: に intel.com/intel_sriov_netdevice2を指定している点です。また「'1'」はVFの数を示していますが、2や3と増やしても、VFは1つしかアサインされませんでした。*18
  3. SR-IOVにてアサインされたNICが保持するIPアドレスは、以下のコマンドで確認できます。net1のMACアドレスがWorkerのVFのMACアドレスと一致していることを確認してください。加えて、外部NW機器にPingが通ることを確認できれば構築完了です。
kubectl exec -it pod2 -- ip addr show

[root@c80g105 ~]# kubectl exec -it pod2 -- ip addr show
1: lo:  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
3: eth0@if31:  mtu 1450 qdisc noqueue state UP group default
    link/ether 0a:56:43:b8:ad:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.1.19/24 scope global eth0
       valid_lft forever preferred_lft forever
24: net1:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 2e:f2:70:b7:e9:ca brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.6/24 brd 192.168.30.255 scope global net1
       valid_lft forever preferred_lft forever

Worker上では以下のように認識されます。

[root@c80g106 ~]# ip link show
  一部省略
8: ens2f0:  mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether a0:36:9f:3e:70:d4 brd ff:ff:ff:ff:ff:ff
    vf 0 MAC 4e:bc:dc:62:a8:7e, spoof checking on, link-state auto, trust off, query_rss off
    vf 1 MAC ee:c9:15:96:2d:5d, spoof checking on, link-state auto, trust off, query_rss off
    vf 2 MAC c2:82:b1:0f:ca:2e, spoof checking on, link-state auto, trust off, query_rss off
    vf 3 MAC 86:e2:0a:d6:96:ff, spoof checking on, link-state auto, trust off, query_rss off
    vf 4 MAC 6e:5e:70:e8:da:48, spoof checking on, link-state auto, trust off, query_rss off
    vf 5 MAC f2:2f:55:d8:b3:40, spoof checking on, link-state auto, trust off, query_rss off
    vf 6 MAC ae:a8:e8:48:25:2c, spoof checking on, link-state auto, trust off, query_rss off
    vf 7 MAC da:d8:2a:7d:2f:5b, spoof checking on, link-state auto, trust off, query_rss off
9: ens2f1:  mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether a0:36:9f:3e:70:d6 brd ff:ff:ff:ff:ff:ff
    vf 0 MAC ba:73:6f:81:ea:31, spoof checking on, link-state auto, trust off, query_rss off
    vf 1 MAC 0a:24:c7:34:26:ec, spoof checking on, link-state auto, trust off, query_rss off
    vf 2 MAC d6:62:b0:f5:01:fc, spoof checking on, link-state auto, trust off, query_rss off
    vf 3 MAC a2:05:32:03:eb:d4, spoof checking on, link-state auto, trust off, query_rss off
    vf 4 MAC b2:46:0e:e4:93:90, spoof checking on, link-state auto, trust off, query_rss off
    vf 5 MAC 76:d6:8a:9f:1a:84, spoof checking on, link-state auto, trust off, query_rss off
    vf 6 MAC 2e:f2:70:b7:e9:ca, vlan 300, spoof checking on, link-state auto, trust off, query_rss off
    vf 7 MAC 8e:c0:94:c2:98:f9, spoof checking on, link-state auto, trust off, query_rss off
7-4.VMIとPodの差異について

以下にまとめます。

8086:10ed X520 VMI用 vfio-pci
8086:1515 X540 Pod用 ixgbevf

VMI用vfio-pciについて

  • worker上でip add showを打っても、vfio-pci上で動作しているため、blacklist登録時と同様にVFのNICは表示されません。このためip link showでMACアドレスを確認します。
  • VMIによってVFが掴まれていないとき、MACアドレスは00:00:00:00:00:00が正常です。
  • 今回の構成では、IPアドレスは外部NW機器*19にてDHCPサーバを立ててIPアドレスアサインしています。

Pod用ixgbevfについて

  • ixgbevfにて動作しているため、ip add showにてVFのNICが表示されます。
  • PodによってVFが掴まれているか否かに関わらず、任意のMACアドレスアサインされます。そのMACアドレスはそのままPodが継承します。
  • IPアドレスは(恐らく)MultusからDHCPのように自動でアサインされています。
  • アドレスレンジを指定する場合は以下のようにCRDに追記してください。
vi /root/sriov-network-device-plugin/deployments/sriov-crd2.yaml

[root@c80g105 ~]# vi /root/sriov-network-device-plugin/deployments/sriov-crd2.yaml

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: sriov-net2
  annotations:
    k8s.v1.cni.cncf.io/resourceName: intel.com/intel_sriov_netdevice2
spec:
  config: '{
  "type": "sriov",
  "cniVersion": "0.3.1",
  "name": "sriov300_2",
  "vlan": 300,
  "ipam": {
    "type": "host-local",
    "subnet": "192.168.30.0/24",
    "rangeStart": "192.168.30.64",
    "rangeEnd": "192.168.30.127",
    "routes": [{
      "dst": "0.0.0.0/0"
    }],
    "gateway": "192.168.30.254"
  }
}'
7-5.VMIとPodのdescribe情報*20

VMIのdescribe
以下のコマンドで確認できます。実際の出力はここにアップしておきます。

kubectl describe pods virt-launcher-c771-cp2nk

Podのdescribe
以下のコマンドで確認できます。実際の出力はここにアップしておきます。

kubectl describe pods pod2

VMIのlog
VMIが正常起動しないときやログインできないときは、以下のログを確認してみてください。
膨大な量のログが出力されるので、ここにアップしておきます。

kubectl logs virt-launcher-c771-cp2nk compute

以上です。

8.最後に

以下のサイトを参考にさせて頂きました。
GitHub - intel/multus-cni
GitHub - intel/sriov-cni: DPDK & SR-IOV CNI plugin
GitHub - intel/sriov-network-device-plugin: SRIOV network device plugin for Kubernetes
KubeVirt Latest | Creating Virtual Machines | Interfaces and Networks
Kubernetes: Multus + SRIOV quickstart – Zenghui Shi

今回はSR-IOVでしたが、次回はOvS-DPDKなどにも挑戦できればと考えています。
f:id:metonymical:20191215111811p:plain

Kubernetesのネットワーク構成といった場合、flannelやCalicoの解説サイトがたくさんあったため、とても助かりました。
しかし、SR-IOVに関してVMIとPodの両方を解説しているサイトが皆無に等しかったため今回の記事を書きました。

今のネットワークのトレンドとしては、P4やeBPF+XDP、SRv6といった辺りかなと思っています。
このため、まだまだ私は遅れ気味だなと日々痛感しておりますが、これでようやく足元ぐらいに辿り着けていられればいいなぁ、と思っています。

また、クラウドネイティブといったキーワードが頻出していますが、実際に自分で手を動かしていじってみた結果、クラウドネイティブであることの意味とか意義とか優位性というモノが、理解できたような気がします。

今回、Podに加えて、KubeVirt上のVMIについても記載しましたが、私の個人的な感想として、一定の需要がありそうな気がしました。

というのも、
いきなり一足飛びでコンテナ化できない or コンテナ化するにはハードルが高いといったケースを鑑みるに、libvirtd上で仮想マシンを稼働させながらも、アーキテクチャk8sに(クラウドネイティブ化したシステムとして)統一したい、といった要件を満たせるかもしれないと思いました。

Migrate for Anthosなどは、まさしくこういった課題を解決するために提供され始めたのかな、という気がします。
Migrate for Anthos  |  Google Cloud

*1:おさらい程度に読み飛ばしてください。

*2:今回は無効化してしまいますが、本来はあまり良くないです。

*3:Masterは不要ですが念のため

*4:名前解決できるようにしておいてください。

*5:このため今回はNICを2枚挿しにしています。

*6:これに気付くまでに2週間程度掛かりました。。。

*7:kubectl get pods上ではrunningになりますが。

*8:virshのようにStart & StopやConsoleログインができます。

*9:私の環境では、tar.gzをDLするとハッシュ値が異なるというエラーで弾かれてしまったためインストールしていません。最近、KubeVirtがv0.24.0にアップデートされた影響かもしれません。

*10:Multusが3番目なのですが、先にインストールしても大丈夫かなと思っています。

*11:Master&Workerにて、それぞれsriov-device-pluginを起動させるため、5-3 & 5-4にて、Docker Imageのビルドをしています。

*12:Cloud Initからイメージファイルを落とした場合、証明書認証が必要となるため、公開鍵を仕込む必要がありますので、私は自前でqcow2ファイルを作っています。

*13:即ち、vfio-pciを使用する設定

*14:これに気付くのに1週間程度掛かりました。。

*15:flannelからアサインされるIP

*16:これの理由は未だによくわかっていません。。

*17:即ち、ixgbevfを使用する設定

*18:この辺りの仕様が正直よくわかっていません。。

*19:構成図右側のスイッチ

*20:何度か作り直しをしているためIPやMACなどが一部異なっていると思います。

CentOS8 ovs(Open vSwitch)+DPDKのビルドとネットワーク設定方法

CentOS8によるovs(Open vSwitch)+DPDKのビルドとネットワーク設定方法について記載しました。
基本的にはCentOS7と同様ですが、CentOS8の場合はdpdkのパッケージがあるため、比較的楽に導入出来ます。

1.構成

1-1.環境
筐体                             : ProLiant DL360e Gen8
System ROM                       : P73 01/22/2018
NIC                              : Intel X540-AT2
OS                               : CentOS8.0(1905)
Kernel                           : 4.18.0-80.el8.x86_64
Installed Environment Groups     : 
  @^graphical-server-environment
  @container-management
  @development
  @virtualization-client
  @virtualization-hypervisor
  @virtualization-tools 
ovs                              : 2.12.90
DPDK                             : 18.11.3
1-2.全体の流れ

事前準備
DPDKインストール
OvSソースビルド
OvS+DPDKのネットワーク設定
仮想マシンのvirsh edit

2.事前準備

2-1.qemu-kvmの実行ユーザをrootへ変更

qemu-kvmの実行ユーザをqemu→rootに変更します。

vi /etc/libvirt/qemu.conf

user = "root"  #コメントを外す
group = "root"  #コメントを外す

viで/etc/libvirt/qemu.confを開き、上記ユーザとグループの行をコメントアウト

2-2.必要なパッケージのインストール
sed -i -e s/enabled=0/enabled=1/g /etc/yum.repos.d/CentOS-PowerTools.repo
dnf -y install libpcap-devel elfutils-libelf-devel numactl-devel libmnl-devel clang
2-3.HugePageとIOMMUの有効化
sed -i -e "/GRUB_CMDLINE_LINUX=/s/\"$/ default_hugepagesz=1G hugepagesz=1G hugepages=16\"/g" /etc/default/grub
sed -i -e "/GRUB_CMDLINE_LINUX=/s/\"$/ intel_iommu=on iommu=pt pci=realloc\"/g" /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg
reboot

hugepageの有効化
iommuの有効化*1
grubに設定反映
再起動

2-4.HugePageの確認とマウント
grep Huge /proc/meminfo

出力例
# grep Huge /proc/meminfo
AnonHugePages:    135168 kB
HugePages_Total:      16
HugePages_Free:       16
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:    1048576 kB

vi /etc/fstab

最終行に以下を追記
nodev  /mnt/huge_1GB hugetlbfs pagesize=1GB    0 0

HugePageの割り当て状況確認
HugePageの永続化マウント

2-5.vfio-pciの設定
echo "vfio-pci" > /etc/modules-load.d/vfio-pci.conf
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modules-load.d/iommu.conf

vfio-pciの永続化設定
vfio-pciのiommu利用の永続化

2-5’.uio_pci_generic設定

vfio-pciが利用できない場合は、uio_pci_genericを使用します。

echo "uio_pci_generic" > /etc/modules-load.d/uio_pci_generic.conf

uio_pci_genericの永続化設定

ここまでの準備が整ったら一旦再起動してください。

reboot

3.DPDKインストール

3-1.インストール
dnf -y install dpdk dpdk-devel dpdk-doc dpdk-tools

4.OvSソースビルド

4-1.ビルド環境準備

ビルド環境の準備をします。

cd /usr/src
git clone https://github.com/openvswitch/ovs.git

ディレクトリ移動
git cloneにてソースのダウンロード

4-2.ビルド

ソースからビルドします。

export DPDK_BUILD=/usr/share/dpdk/x86_64-default-linuxapp-gcc && \
cd /usr/src/ovs && \
./boot.sh && \
./configure --with-dpdk=$DPDK_BUILD CC=clang && \
make && \
make install

dpdk-develへのパスを指定
ディレクトリ移動
boot.sh実行
configure実行*2
ビルド
インストール

多少時間は掛かりますが、最後の方は以下のような出力がでれば正常にビルドが完了しています。

onitor-ipsec vtep/ovs-vtep '/usr/local/share/openvswitch/scripts'
make[3]: Leaving directory '/usr/src/ovs'
make[2]: Leaving directory '/usr/src/ovs'
make[1]: Leaving directory '/usr/src/ovs'

5.OvS+DPDKのネットワーク設定

5-1.全体構成

f:id:metonymical:20190106225241j:plain
前回記事の構成図と比較してください。
グレーアウト&斜体文字になっているのが前回設定した箇所です。
今回は(1)~(6)の黒文字になっている箇所を設定していきます。

5-2.全体の流れ ~概要~
  1. DPDKにバインド:(1)(2)
  2. Bridge作成:(3)
  3. Bond作成:(4)
  4. vHostUserClientポート作成:(5)
  5. 仮想マシンの設定:(6)
5-3.コマンド投入前準備1

コマンド投入前には以下のようにパスを通しておいてください。*3

vi /root/.bash_profile

PATH=$PATH:$HOME/bin:/usr/local/share/openvswitch/scripts
export PATH
5-4.コマンド投入前準備2

OvSを起動後、DPDK周りの詳細設定を追加しておきます。

ovs-ctl --system-id=random start
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem=1024,1024
ovs-vsctl --no-wait set Open_vSwitch . other_config:vhost-iommu-support=true
ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0x33
ovs-vsctl --no-wait get Open_vSwitch . other_config

OvSサービスの開始
DPDKの初期化
NUMA毎のメモリ設定(単位MB)
PMD-CPUマスクの設定
設定内容の確認

上記のうち、dpdk-init=true以外はチューニングパラメータなので、設定しなくてもとりあえずは動きます。

5-5.全体の流れ ~コマンドのみ~

以下のコマンドを投入していきます。
やりたいことが既に決まっている方は、構成図とコマンドの内容を見るだけでもよいと思います。

1.DPDKにバインド
(1)
dpdk-devbind --status
dpdk-devbind --bind=vfio-pci ens1f0
(2)
dpdk-devbind --bind=vfio-pci ens1f1
dpdk-devbind --status

2.Bridge作成
(3)
ovs-ctl --system-id=random stop
ovs-ctl --system-id=random start
ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev

3.Bond作成
(4)
ovs-vsctl add-bond ovsbr0 bond0 dpdk0 dpdk1 \
 vlan_mode=trunk trunks=11,300-304 \
 bond_mode=balance-tcp lacp=active other_config:lacp-time=fast \
 -- set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:08:00.0 \
 -- set Interface dpdk1 type=dpdk options:dpdk-devargs=0000:08:00.1

4.vHostUserClientポート作成
(5)
mkdir -p /usr/local/openvswitch/
touch /usr/local/openvswitch/vhuc0

ovs-vsctl add-port ovsbr0 vhuc0 \
 vlan_mode=access tag=300 \
 -- set Interface vhuc0 type=dpdkvhostuserclient \
 options:vhost-server-path=/usr/local/openvswitch/vhuc0

5.仮想マシンの設定
(6)
virsh edit Guest3

  <currentMemory unit='KiB'>1048576</currentMemory>
  <memoryBacking>
    <hugepages>
      <page size='1048576' unit='KiB' nodeset='0'/>
    </hugepages>
  </memoryBacking>
  
  <cpu mode='host-passthrough' check='none'>
    <numa>
      <cell id='0' cpus='0' memory='1048576' unit='KiB' memAccess='shared'/>
    </numa>
  </cpu>

  <interface type='vhostuser'>
    <source type='unix' path='/usr/local/openvswitch/vhuc0' mode='server'/>
    <model type='virtio'/>
  </interface>青=追記,緑=置換

6.DPDKにバインド

Kernel上で動作しているX540をDPDK上で動作されるようにバインドします。*4
(1)
dpdk-devbind --status
dpdk-devbind --bind=vfio-pci ens1f0
(2)
dpdk-devbind --bind=vfio-pci ens1f1
dpdk-devbind --status

[root@c80gmas ~]# dpdk-devbind --status

Network devices using kernel driver
===================================
0000:02:00.0 'I350 Gigabit Network Connection 1521' if=eno1 drv=igb unused=vfio-pci,uio_pci_generic *Active*
0000:02:00.1 'I350 Gigabit Network Connection 1521' if=eno2 drv=igb unused=vfio-pci,uio_pci_generic
0000:02:00.2 'I350 Gigabit Network Connection 1521' if=eno3 drv=igb unused=vfio-pci,uio_pci_generic
0000:02:00.3 'I350 Gigabit Network Connection 1521' if=eno4 drv=igb unused=vfio-pci,uio_pci_generic
0000:08:00.0 'Ethernet Controller 10-Gigabit X540-AT2 1528' if=ens1f0 drv=ixgbe unused=vfio-pci,uio_pci_generic
0000:08:00.1 'Ethernet Controller 10-Gigabit X540-AT2 1528' if=ens1f1 drv=ixgbe unused=vfio-pci,uio_pci_generic

[root@c80gmas ~]# dpdk-devbind.py --bind=vfio-pci ens1f0
[root@c80gmas ~]# dpdk-devbind.py --bind=vfio-pci ens1f1
[root@c80gmas ~]# dpdk-devbind.py --status

Network devices using DPDK-compatible driver
============================================
0000:08:00.0 'Ethernet Controller 10-Gigabit X540-AT2 1528' drv=vfio-pci unused=ixgbe,uio_pci_generic
0000:08:00.1 'Ethernet Controller 10-Gigabit X540-AT2 1528' drv=vfio-pci unused=ixgbe,uio_pci_generic

Network devices using kernel driver
===================================
0000:02:00.0 'I350 Gigabit Network Connection 1521' if=eno1 drv=igb unused=vfio-pci,uio_pci_generic *Active*
0000:02:00.1 'I350 Gigabit Network Connection 1521' if=eno2 drv=igb unused=vfio-pci,uio_pci_generic
0000:02:00.2 'I350 Gigabit Network Connection 1521' if=eno3 drv=igb unused=vfio-pci,uio_pci_generic
0000:02:00.3 'I350 Gigabit Network Connection 1521' if=eno4 drv=igb unused=vfio-pci,uio_pci_generic

バインドされると、X540がNetwork devices using DPDK-compatible driverに表示されます。

今回利用するドライバはvfio-pciですが、uio_pci_genericでも利用可能です。
利用したい場合は、以下のように変更すればOKです。

dpdk-devbind --bind=uio_pci_generic ens1f0

また、vfio-pciを利用するにあたり、ProLiant DL360G8を使用している方はRMRR設定が必要になる場合があります。
以下のサイトを参考にしてみてください。
DPDK and RMRR Compatibility Issues on the HP Proliant DL360e G8 | www.jimmdenton.com
https://support.hpe.com/hpsc/doc/public/display?sp4ts.oid=7271259&docId=emr_na-c04781229&docLocale=ja_JP

7.Bridge作成

念のため、ovsの再起動をした後、Bridge作成を行ってください。
(3)
ovs-ctl --system-id=random stop
ovs-ctl --system-id=random start
ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev

[root@c80gmas ~]# ovs-ctl --system-id=random stop
Exiting ovs-vswitchd (20081)                               [  OK  ]
Exiting ovsdb-server (20063)                               [  OK  ]
[root@c80gmas ~]# ovs-ctl --system-id=random start
Starting ovsdb-server                                      [  OK  ]
Configuring Open vSwitch system IDs                        [  OK  ]
Enabling remote OVSDB managers                             [  OK  ]
[root@c80gmas ~]# ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev

正常にBridgeが作成されると上記のような出力となります。

8.Bond作成

ovsbr0上にアップリンクポート*5を追加し、Bondを組みます。また、TrunkとLACPの設定も同時に追加します。
(4)
ovs-vsctl add-bond ovsbr0 bond0 dpdk0 dpdk1 \
vlan_mode=trunk trunks=11,300-304 \
bond_mode=balance-tcp lacp=active other_config:lacp-time=fast \
-- set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:08:00.0 \
-- set Interface dpdk1 type=dpdk options:dpdk-devargs=0000:08:00.1
ovs-vsctl show

[root@c80gmas ~]# ovs-vsctl add-bond ovsbr0 bond0 dpdk0 dpdk1 \
>  vlan_mode=trunk trunks=11,300-304 \
>  bond_mode=balance-tcp lacp=active other_config:lacp-time=fast \
>  -- set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:08:00.0 \
>  -- set Interface dpdk1 type=dpdk options:dpdk-devargs=0000:08:00.1
[root@c80gmas ~]# ovs-vsctl show
8daaa733-f6ef-4b67-a1a9-581875f33420
    Bridge "ovsbr0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "bond0"
            trunks: [11, 300, 301, 302, 303, 304]
            Interface "dpdk0"
                type: dpdk
                options: {dpdk-devargs="0000:08:00.0"}
            Interface "dpdk1"
                type: dpdk
                options: {dpdk-devargs="0000:08:00.1"}
    ovs_version: "2.12.90"
[root@c80gmas ~]#

上記のように追加されていればOKです。

FullTrunkにしたい場合は、以下の行を削除してください。

vlan_mode=trunk trunks=11,300-304 \

スイッチ側の仕様でLACPが組めない場合、以下のように修正してください。

 bond_mode=balance-tcp lacp=active other_config:lacp-time=fast \
 ↓
 bond_mode=balance-slb \

9.vHostUserClientポート作成

ovsbr0上にダウンリンクポート*6を追加します。
先にSocketファイルとなるvhuc0を作成し、その後ovsbr0にポートを追加します。
(5)
mkdir -p /usr/local/openvswitch/
touch /usr/local/openvswitch/vhuc0

ovs-vsctl add-port ovsbr0 vhuc0 \
vlan_mode=access tag=300 \
-- set Interface vhuc0 type=dpdkvhostuserclient \
options:vhost-server-path=/usr/local/openvswitch/vhuc0

ovs-vsctl show

[root@c80gmas ~]# mkdir -p /usr/local/openvswitch/
[root@c80gmas ~]# touch /usr/local/openvswitch/vhuc0
[root@c80gmas ~]# ovs-vsctl add-port ovsbr0 vhuc0 \
>  vlan_mode=access tag=300 \
>  -- set Interface vhuc0 type=dpdkvhostuserclient \
>  options:vhost-server-path=/usr/local/openvswitch/vhuc0
[root@c80gmas ~]# ovs-vsctl show
8daaa733-f6ef-4b67-a1a9-581875f33420
    Bridge "ovsbr0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "bond0"
            trunks: [11, 300, 301, 302, 303, 304]
            Interface "dpdk1"
                type: dpdk
                options: {dpdk-devargs="0000:08:00.1"}
            Interface "dpdk0"
                type: dpdk
                options: {dpdk-devargs="0000:08:00.0"}
        Port "vhuc0"
            tag: 300
            Interface "vhuc0"
                type: dpdkvhostuserclient
                options: {vhost-server-path="/usr/local/openvswitch/vhuc0"}
    ovs_version: "2.12.90"

上記のように追加されていればOKです。
ちなみに、vlan_mode=access tag=300としましたが、tag=300のみでも自動的にaccessポートにしてくれます。
また、trunkポートにしたい場合は、Bond設定で投入した「vlan_mode=trunk trunks=11,300-304」を参考に置換してください。

10.仮想マシンの設定

virshで仮想マシンの設定を編集します。
これにより、以下3点を実施します。
仮想マシン上でHugePageを利用可能にする
仮想マシンに対してCPUのパススルー機能を有効化する
・vHostUserにてNICを追加する
(6)
virsh edit Guest3

<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<hugepages>
<page size='1048576' unit='KiB' nodeset='0'/>
</hugepages>
</memoryBacking>


<cpu mode='host-passthrough' check='none'>
<numa>
<cell id='0' cpus='0' memory='1048576' unit='KiB' memAccess='shared'/>
</numa>
</cpu>

<interface type='vhostuser'>
<source type='unix' path='/usr/local/openvswitch/vhuc0' mode='server'/>
<model type='virtio'/>
</interface>


青=追記,緑=置換

[root@c80gmas ~]# virsh edit Guest3

  <currentMemory unit='KiB'>1048576</currentMemory>
  <memoryBacking>
    <hugepages>
      <page size='1048576' unit='KiB' nodeset='0'/>
    </hugepages>
  </memoryBacking>
  
  <cpu mode='host-passthrough' check='none'>
    <numa>
      <cell id='0' cpus='0' memory='1048576' unit='KiB' memAccess='shared'/>
    </numa>
  </cpu>

  <interface type='vhostuser'>
    <source type='unix' path='/usr/local/openvswitch/vhuc0' mode='server'/>
    <model type='virtio'/>
  </interface>青=追記,緑=置換

xmlファイルのため、virsh editで開くと、最初はどこを編集していいか探したり、迷ったりすると思いますが、通常のviエディタと同様に編集可能なため、「cpu mode」などで検索すればすぐに見つかると思います。
あと、vhostuserですが、mode=serverとなっています。以前はmode=clientだったのですが、現在はmode=serverが推奨されています。*7

11.仮想マシンの起動

仮想マシンを起動し、新規に追加されたインターフェースにIP設定後、疎通確認を行ってみてください。

virsh start Guest3

起動時にPermission Denyなどのエラーが出力される場合があります。
その場合、「2-2.qemu-kvmの実行ユーザをrootへ変更」を参照し、Qemuの実行ユーザが確実にrootとなっていることを確認してください。
その上で、

systemctl restart libvirtd.service

を実行し、それでもダメなら、ホストOSを再起動してみてください。

以上です。

12.最後に

CentOS7からの改編となります。

大きく変わっている点は、

  • qemu-kvm-evが不要*8
  • dpdkのビルドが不要*9
  • gccの代わりにclangを使用*10

といったあたりです。

一度勘所がわかると、いくらでも応用が効くようになるので、その積み重ねが大切なのかなと思います。
CentOS8にてopenstackはまだ各種パッケージなどが準備されていないようですが、ovs-dpdkは実装できたので諸々移行できそうです。
LinuxBridge&ovsにて、それぞれsriov&dpdkが使用できれば、概ねやりたいことはできるので。
また、nmcliコマンドはCentOS7でも8でも共通なので、そのまま転用可能です。

ちなみに、元々の動機はCentOS8でこれ↓がやりたかったので、CentOS8でもovs-dpdkを実装してみました。
f:id:metonymical:20191116061552p:plain
f:id:metonymical:20191116061611p:plain
github.com
これができれば、dpdk+dockerやk8sも包含されるため、現段階における仮想化されたネットワークの様々アーキテクチャは網羅されるかな、と考えています。
さらにその次のステップとして、SRv6によるネットワークスライシングなどにも踏み込めれば、楽しそうだなと考えています。

*1:IOMMUについては、DL360G8特有の設定(RMRRの設定)があるため、途中で補足を入れます。

*2:CentOS7のときは、gccを使用していましたが、今回はclangを使用しています。理由はコンパイル時間の短縮です。x86_64アーキテクチャのみの環境であれば、clang/llvmの方が早かったので。ちなみにgccでも問題ありませんが、3倍以上の時間を要しました、また、Warningメッセージが出まくるので少々不安になるかもしれません。

*3:.bash_profileに追記した場合は、ログアウト&ログインを忘れずに。またCentOS7のときとは異なり、dnfコマンドにてdpdkをインストールしているため、dpdk関連コマンドへのパス通しは不要となりました。

*4:CentOS7とは異なり、.pyの拡張子が無くなっています。.pyを入力してしまうと、No such a file or diretory~が出力されます。

*5:DPDK上で稼働しているX540のens1f0とens1f1

*6:仮想マシンが接続されるポート

*7:詳細は、 Data Plane Development Kit vHost User Client Mode with Open vSwitch* | Intel® Softwareに記載されています。

*8:CentOS8の場合、ver2.12となっているため

*9:dnfコマンドでインストールが可能なため

*10:コンパイル時間の短縮のため

CentOS8 小ネタ集その5:リポジトリの設定

CentOS8のリポジトリ設定方法を記載します。

設定するリポジトリは以下の通りです。

基本編

  • epel-release
  • elrepo
  • remi
  • PowerTools

番外編

  • fed2el-release

1.OSインストール直後の状態

[root@c80gmas ~]# dnf repolist all                                                                                      
Last metadata expiration check: 0:00:12 ago on Fri 15 Nov 2019 03:44:42 AM JST.                                         
repo id                                         repo name                                                 status        
AppStream                                       CentOS-8 - AppStream                                      enabled: 5,089
AppStream-source                                CentOS-8 - AppStream Sources                              disabled      
BaseOS                                          CentOS-8 - Base                                           enabled: 2,843
BaseOS-source                                   CentOS-8 - BaseOS Sources                                 disabled      
PowerTools                                      CentOS-8 - PowerTools                                     disabled      
base-debuginfo                                  CentOS-8 - Debuginfo                                      disabled      
c8-media-AppStream                              CentOS-AppStream-8 - Media                                disabled      
c8-media-BaseOS                                 CentOS-BaseOS-8 - Media                                   disabled      
centosplus                                      CentOS-8 - Plus                                           disabled      
centosplus-source                               CentOS-8 - Plus Sources                                   disabled      
cr                                              CentOS-8 - cr                                             disabled      
extras                                          CentOS-8 - Extras                                         enabled:     3
extras-source                                   CentOS-8 - Extras Sources                                 disabled      
fasttrack                                       CentOS-8 - fasttrack                                      disabled      

2.epel-release

dnf -y install epel-release

5.PowerTools

PowerToolsはdevelなどが多く含まれており、ビルドをする際には何かと重宝します。
デフォルトでインストールされていますがDisbaleになっているため、Enableにしてしまいます。

sed -i -e s/enabled=0/enabled=1/g /etc/yum.repos.d/CentOS-PowerTools.repo

<出力例>

[root@c80gmas ~]# sed -i -e s/enabled=0/enabled=1/g /etc/yum.repos.d/CentOS-PowerTools.repo
[root@c80gmas ~]# cat /etc/yum.repos.d/CentOS-PowerTools.repo
# CentOS-PowerTools.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[PowerTools]
name=CentOS-$releasever - PowerTools
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=PowerTools&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/PowerTools/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

ここまでの設定で、以下のようにリポジトリが追加されていると思います。

[root@c80gmas ~]# dnf repolist all                                                                                      
Remi's Modular repository for Enterprise Linux 8 - x86_64                               109 kB/s | 509 kB     00:04     
Safe Remi's RPM repository for Enterprise Linux 8 - x86_64                              271 kB/s | 1.4 MB     00:05     
repo id                       repo name                                                                   status        
AppStream                     CentOS-8 - AppStream                                                        enabled: 5,089
AppStream-source              CentOS-8 - AppStream Sources                                                disabled      
BaseOS                        CentOS-8 - Base                                                             enabled: 2,843
BaseOS-source                 CentOS-8 - BaseOS Sources                                                   disabled      
PowerTools                    CentOS-8 - PowerTools                                                       enabled: 1,507
base-debuginfo                CentOS-8 - Debuginfo                                                        disabled      
c8-media-AppStream            CentOS-AppStream-8 - Media                                                  disabled      
c8-media-BaseOS               CentOS-BaseOS-8 - Media                                                     disabled      
centosplus                    CentOS-8 - Plus                                                             disabled      
centosplus-source             CentOS-8 - Plus Sources                                                     disabled      
cr                            CentOS-8 - cr                                                               disabled      
elrepo                        ELRepo.org Community Enterprise Linux Repository - el8                      enabled:    25
elrepo-extras                 ELRepo.org Community Enterprise Linux Extras Repository - el8               disabled      
elrepo-kernel                 ELRepo.org Community Enterprise Linux Kernel Repository - el8               disabled      
elrepo-testing                ELRepo.org Community Enterprise Linux Testing Repository - el8              disabled      
*epel                         Extra Packages for Enterprise Linux 8 - x86_64                              enabled: 3,153
epel-debuginfo                Extra Packages for Enterprise Linux 8 - x86_64 - Debug                      disabled      
epel-playground               Extra Packages for Enterprise Linux 8 - Playground - x86_64                 disabled      
epel-playground-debuginfo     Extra Packages for Enterprise Linux 8 - Playground - x86_64 - Debug         disabled      
epel-playground-source        Extra Packages for Enterprise Linux 8 - Playground - x86_64 - Source        disabled      
epel-source                   Extra Packages for Enterprise Linux 8 - x86_64 - Source                     disabled      
epel-testing                  Extra Packages for Enterprise Linux 8 - Testing - x86_64                    disabled      
epel-testing-debuginfo        Extra Packages for Enterprise Linux 8 - Testing - x86_64 - Debug            disabled      
epel-testing-source           Extra Packages for Enterprise Linux 8 - Testing - x86_64 - Source           disabled      
extras                        CentOS-8 - Extras                                                           enabled:     3
extras-source                 CentOS-8 - Extras Sources                                                   disabled      
fasttrack                     CentOS-8 - fasttrack                                                        disabled      
remi                          Remi's RPM repository for Enterprise Linux 8 - x86_64                       disabled      
remi-debuginfo                Remi's RPM repository for Enterprise Linux 8 - x86_64 - debuginfo           disabled      
remi-modular                  Remi's Modular repository for Enterprise Linux 8 - x86_64                   enabled:    12
remi-modular-test             Remi's Modular testing repository for Enterprise Linux 8 - x86_64           disabled      
remi-safe                     Safe Remi's RPM repository for Enterprise Linux 8 - x86_64                  enabled: 2,014
remi-safe-debuginfo           Remi's RPM repository for Enterprise Linux 8 - x86_64 - debuginfo           disabled      
remi-test                     Remi's test RPM repository for Enterprise Linux 8 - x86_64                  disabled      
remi-test-debuginfo           Remi's test RPM repository for Enterprise Linux 8 - x86_64 - debuginfo      disabled      

およそ1万超のパッケージが利用可能になっていると思います。

[root@c80gmas ~]# dnf list available | wc -l
11976

これから有用なパッケージが徐々に増えてくると思いますが、現段階において、これだけでは心許無いという方は以下も追加してみてください。

6.fed2el-release

fedora28のリポジトリを追加することにより、6万超のパッケージが利用可能になります。

dnf -y install https://extras.getpagespeed.com/release-el8-latest.rpm
dnf -y install fed2el-release

<追加後の状態>

[root@c80gmas ~]# dnf repolist all                                                                                      
Last metadata expiration check: 0:00:06 ago on Fri 15 Nov 2019 04:02:00 AM JST.                                         
repo id                                            repo name                                              status        
AppStream                                          CentOS-8 - AppStream                                   enabled: 5,089
AppStream-source                                   CentOS-8 - AppStream Sources                           disabled      
BaseOS                                             CentOS-8 - Base                                        enabled: 2,843
BaseOS-source                                      CentOS-8 - BaseOS Sources                              disabled      
PowerTools                                         CentOS-8 - PowerTools                                  disabled      
base-debuginfo                                     CentOS-8 - Debuginfo                                   disabled      
c8-media-AppStream                                 CentOS-AppStream-8 - Media                             disabled      
c8-media-BaseOS                                    CentOS-BaseOS-8 - Media                                disabled      
centosplus                                         CentOS-8 - Plus                                        disabled      
centosplus-source                                  CentOS-8 - Plus Sources                                disabled      
cr                                                 CentOS-8 - cr                                          disabled      
elrepo                                             ELRepo.org Community Enterprise Linux Repository - el8 enabled:    25
elrepo-extras                                      ELRepo.org Community Enterprise Linux Extras Repositor disabled      
elrepo-kernel                                      ELRepo.org Community Enterprise Linux Kernel Repositor disabled      
elrepo-testing                                     ELRepo.org Community Enterprise Linux Testing Reposito disabled      
*epel                                              Extra Packages for Enterprise Linux 8 - x86_64         enabled: 3,153
epel-debuginfo                                     Extra Packages for Enterprise Linux 8 - x86_64 - Debug disabled      
epel-playground                                    Extra Packages for Enterprise Linux 8 - Playground - x disabled      
epel-playground-debuginfo                          Extra Packages for Enterprise Linux 8 - Playground - x disabled      
epel-playground-source                             Extra Packages for Enterprise Linux 8 - Playground - x disabled      
epel-source                                        Extra Packages for Enterprise Linux 8 - x86_64 - Sourc disabled      
epel-testing                                       Extra Packages for Enterprise Linux 8 - Testing - x86_ disabled      
epel-testing-debuginfo                             Extra Packages for Enterprise Linux 8 - Testing - x86_ disabled      
epel-testing-source                                Extra Packages for Enterprise Linux 8 - Testing - x86_ disabled      
extras                                             CentOS-8 - Extras                                      enabled:     3
extras-source                                      CentOS-8 - Extras Sources                              disabled      
fasttrack                                          CentOS-8 - fasttrack                                   disabled      
fedora                                             Fedora 28 - x86_64                                     disabled      
fedora-debuginfo                                   Fedora 28 - x86_64 - Debug                             disabled      
fedora-rpmfusion-free                              RPM Fusion for Fedora 28 - Free                        disabled      
fedora-rpmfusion-free-debuginfo                    RPM Fusion for Fedora 28 - Free - Debug                disabled      
fedora-rpmfusion-free-source                       RPM Fusion for Fedora 28 - Free - Source               disabled      
fedora-rpmfusion-free-updates                      RPM Fusion for Fedora 28 - Free - Updates              disabled      
fedora-rpmfusion-free-updates-debuginfo            RPM Fusion for Fedora 28 - Free - Updates Debug        disabled      
fedora-rpmfusion-free-updates-source               RPM Fusion for Fedora 28 - Free - Updates Source       disabled      
fedora-rpmfusion-free-updates-testing              RPM Fusion for Fedora 28 - Free - Test Updates         disabled      
fedora-rpmfusion-free-updates-testing-debuginfo    RPM Fusion for Fedora 28 - Free - Test Updates Debug   disabled      
fedora-rpmfusion-free-updates-testing-source       RPM Fusion for Fedora 28 - Free - Test Updates Source  disabled      
fedora-rpmfusion-nonfree                           RPM Fusion for Fedora 28 - Nonfree                     disabled      
fedora-rpmfusion-nonfree-debuginfo                 RPM Fusion for Fedora 28 - Nonfree - Debug             disabled      
fedora-rpmfusion-nonfree-source                    RPM Fusion for Fedora 28 - Nonfree - Source            disabled      
fedora-rpmfusion-nonfree-updates                   RPM Fusion for Fedora 28 - Nonfree - Updates           disabled      
fedora-rpmfusion-nonfree-updates-debuginfo         RPM Fusion for Fedora 28 - Nonfree - Updates Debug     disabled      
fedora-rpmfusion-nonfree-updates-source            RPM Fusion for Fedora 28 - Nonfree - Updates Source    disabled      
fedora-rpmfusion-nonfree-updates-testing           RPM Fusion for Fedora 28 - Nonfree - Test Updates      disabled      
fedora-rpmfusion-nonfree-updates-testing-debuginfo RPM Fusion for Fedora 28 - Nonfree - Test Updates Debu disabled      
fedora-rpmfusion-nonfree-updates-testing-source    RPM Fusion for Fedora 28 - Nonfree - Test Updates Sour disabled      
fedora-russian-free                                Russian Fedora for Fedora 28 - Free                    disabled      
fedora-russian-free-debuginfo                      Russian Fedora for Fedora 28 - Free - Debug            disabled      
fedora-russian-free-source                         Russian Fedora for Fedora 28 - Free - Source           disabled      
fedora-russian-free-updates                        Russian Fedora for Fedora 28 - Free - Updates          disabled      
fedora-russian-free-updates-debuginfo              Russian Fedora for Fedora 28 - Free - Updates Debug    disabled      
fedora-russian-free-updates-source                 Russian Fedora for Fedora 28 - Free - Updates Source   disabled      
fedora-russian-nonfree                             Russian Fedora for Fedora 28 - Nonfree                 disabled      
fedora-russian-nonfree-debuginfo                   Russian Fedora for Fedora 28 - Nonfree - Debug         disabled      
fedora-russian-nonfree-source                      Russian Fedora for Fedora 28 - Nonfree - Source        disabled      
fedora-russian-nonfree-updates                     Russian Fedora for Fedora 28 - Nonfree - Updates       disabled      
fedora-russian-nonfree-updates-debuginfo           Russian Fedora for Fedora 28 - Nonfree - Updates Debug disabled      
fedora-russian-nonfree-updates-source              Russian Fedora for Fedora 28 - Nonfree - Updates Sourc disabled      
fedora-source                                      Fedora 28 - Source                                     disabled      
fedora-updates                                     Fedora 28 - x86_64 - Updates                           disabled      
fedora-updates-debuginfo                           Fedora 28 - x86_64 - Updates - Debug                   disabled      
fedora-updates-source                              Fedora 28 - Updates Source                             disabled      
getpagespeed-extras                                GetPageSpeed packages for Enterprise Linux 8 - x86_64  enabled:   369
getpagespeed-extras-mainline                       GetPageSpeed packages of mainline NGINX for Enterprise disabled      
getpagespeed-extras-nginx-mod                      GetPageSpeed packages with patched NGINX for Enterpris disabled      
getpagespeed-extras-noarch                         GetPageSpeed packages for Enterprise Linux 8 - noarch  enabled:    52
getpagespeed-extras-varnish60                      GetPageSpeed packages of Varnish 6.0.x for Enterprise  disabled      
remi                                               Remi's RPM repository for Enterprise Linux 8 - x86_64  disabled      
remi-debuginfo                                     Remi's RPM repository for Enterprise Linux 8 - x86_64  disabled      
remi-modular                                       Remi's Modular repository for Enterprise Linux 8 - x86 enabled:    12
remi-modular-test                                  Remi's Modular testing repository for Enterprise Linux disabled      
remi-safe                                          Safe Remi's RPM repository for Enterprise Linux 8 - x8 enabled: 2,014
remi-safe-debuginfo                                Remi's RPM repository for Enterprise Linux 8 - x86_64  disabled      
remi-test                                          Remi's test RPM repository for Enterprise Linux 8 - x8 disabled      
remi-test-debuginfo                                Remi's test RPM repository for Enterprise Linux 8 - x8 disabled      

これだけあれば一先ず困らないのでは?と思います。
ちなみに、fedora28のリポジトリを使用する場合、デフォルトでは全てDisbaleとなっており、これを全てEnableにするのはしんどいので、以下のようにdnfplusコマンドを使用してください。
<サンプル>

dnfplus -y install filezilla

これでも不足するようであれば、頑張ってビルドしましょう!

以上です。

7.最後に

以下のサイトを参考にさせて頂きました。
50k+ packages for RHEL 8 / CentOS 8, even before EPEL is up - GetPageSpeed
CentOS Repositories - pkgs.org

CentOS8は、まだ実用的ではない部分もありますが、少しづつでも使っていかないと勿体ないので慣れていきましょう。

私事ですが、ovsやovn、openstackなどが使えないと死活問題になるため、CentOS8への移行は少し躊躇っています。
ovsはビルドすればOKなのですが、ovs-dpdkの場合、--with-dpdkの後にmakeするとコケたりするので、ちょっと困っています。。

CentOS7 NextEPCによるEPC構築方法

前回記事のスピンオフとして、CentOS7でのNextEPCの構築方法を記載します。

Redhat系の方が使い慣れている人には最適かなと思います。

1.環境

1-1.VMWare
筐体                             : 自作PC(Win10pro)
CPU                           : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
VMWare              : VMware(R) Workstation 15 Pro 15.1.0 build-13591040  
OS                               : CentOS Linux release 7.7.1908 (Core)
Kernel                           : 3.10.0-1062.el7.x86_64
Installed Environment Groups     : Server with GUI
Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools, development
1-2.全体構成

f:id:metonymical:20191022195027p:plain
緑色の箇所がUbuntu16.04からCentOS7.7に変わっています。
それ以外は全て同じです。

1-3 .全体の流れ ~概要~
  1. 事前準備
  2. NextEPC設定
  3. OAISIM設定(省略)*1
  4. NextEPCの分離

2.事前準備

2-1.c77g132:NextEPCのNW設定
nmcli con add type tun mode tun autoconnect yes ifname pgwtun con-name pgwtun
nmcli con mod pgwtun ipv4.method manual ipv4.addresses 25.0.0.1/8
nmcli con mod pgwtun ipv6.method manual ipv6.addresses cafe::1/64
nmcli con up pgwtun

nmcli con add type ethernet autoconnect yes ifname ens33 con-name ens33
nmcli con mod ens33 ipv4.method manual ipv4.addresses 10.10.0.135/24
nmcli con up ens33

nmcli con add type ethernet autoconnect yes ifname ens35 con-name ens35
nmcli con mod ens35 ipv4.method manual ipv4.addresses 10.20.0.132/24
nmcli con mod ens35 ipv4.method manual +ipv4.addresses 10.20.0.133/24
nmcli con mod ens35 ipv4.method manual +ipv4.addresses 10.20.0.134/24
nmcli con mod ens35 ipv4.method manual +ipv4.addresses 10.20.0.135/24
nmcli con mod ens35 ipv4.method manual +ipv4.addresses 10.20.0.136/24
nmcli con up ens35

3.NextEPC設定

分離するまでは、c77g132のみで設定を行っていきます。

3-1.MongoDBのインストール
sudo sh -c 'cat << EOF > /etc/yum.repos.d/mongodb-org-3.4.repo
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
EOF'

yum -y install mongodb-org && \
systemctl start mongod && \
systemctl enable mongod
3-2.mongo-c-driver-develのインストール
yum -y install epel-release && \
yum -y install mongo-c-driver-devel

<補足>
NextEPCの公式サイトを読むと、外部サイトを参照することになります。
そこでは、

yum install mongo-c-driver

と記載されていますが、これをそのまま真に受けると、makeファイル作成時にエラーを吐いて止まります。
NextEPCのビルドで必要とされるのは、mongo-c-driver-develの方です。*2

3-3.依存関係パッケージのインストール
yum -y install git flex bison autoconf libtool \
lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel \
openssl-devel cyrus-sasl-devel libyaml-devel
3-4.ビルド
git clone https://github.com/nextepc/nextepc && \
cd nextepc && \
autoreconf -iv

./configure --prefix=`pwd`/install && \
make -j `nproc` && \
make install
3-5.WebUIのインストール
curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash - && \
yum -y install nodejs

cd /root/nextepc/webui && \
npm install

#サービス起動
npm run dev

#2回目以降、起動する際はwebuiのディレクトリに入った状態で実行してください。
cd /root/nextepc/webui && \
npm run dev

#アクセス先URL
http://192.168.11.132:3000/

インストール完了後、以下のページが表示されればOKです。
Username/Passwdは以下の通り。
admin/1423
f:id:metonymical:20191020140814p:plain

3-6.SIM情報の登録

上記のアクセス先URLから以下のSIM情報を登録します。

IMSI 001010100001111
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN lte.md.jp
MSISDN 33611123456
IMSI 001010100001112
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN lte.md.jp
MSISDN 33611123457

f:id:metonymical:20191021014216p:plain
IMSI, Subscriber Key(Ki), Operator Key(OPc), USIM Typeが必須項目となります。
APNは任意で構いません。

3-7.nextepc.conf設定

設定変更箇所のみ抜粋。*3

vi /root/nextepc/install/etc/nextepc/nextepc.conf

追記:青 コメントアウト&追記:緑

db_uri: mongodb://localhost/nextepc

logger:
    file: /root/nextepc/install/var/log/nextepc/nextepc.log
    trace:
        app: 1
        s1ap: 1
        nas: 1
        diameter: 1
        gtpv2: 1
        gtp: 1

parameter:
    no_ipv6: true

mme:
    freeDiameter: mme.conf

    s1ap:
      - addr: 10.20.0.132

    gtpc:
      - addr: 10.20.0.132

    gummei:
      plmn_id:
        mcc: 001
        mnc: 01
      mme_gid: 2
      mme_code: 1

    tai:
      plmn_id:
        mcc: 001
        mnc: 01
#      tac: 12345
      tac: 1

    security:
        integrity_order : [ EIA1, EIA2, EIA0 ]
        ciphering_order : [ EEA0, EEA1, EEA2 ]

    network_name:
        full: NextEPC

hss:
    freeDiameter: hss.conf

sgw:
    gtpc:
#      addr: 127.0.0.2
      addr: 10.20.0.134

    gtpu:
      - addr: 10.20.0.134

pgw:
    freeDiameter: pgw.conf

    gtpc:
      addr:
#        - 127.0.0.3
        - 10.20.0.135
        - ::1

    gtpu:
#      - addr: 127.0.0.3
      - addr: 10.20.0.135
      - addr: ::1

    ue_pool:
#      - addr: 45.45.0.1/16
      - addr: 25.0.0.1/8
      - addr: cafe::1/64

    dns:
      - 8.8.8.8
      - 8.8.4.4
      - 2001:4860:4860::8888
      - 2001:4860:4860::8844

pcrf:
    freeDiameter: pcrf.conf

3-8.mme.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/mme.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.2";
ListenOn = "10.20.0.132";

#ConnectPeer = "hss.localdomain" { ConnectTo = "127.0.0.4"; No_TLS; };
ConnectPeer = "hss.localdomain" { ConnectTo = "10.20.0.133"; No_TLS; };

#もしくは
sed -i -e /^ListenOn/s/127.0.0.2/10.20.0.132/g \
/root/nextepc/install/etc/nextepc/freeDiameter/mme.conf
sed -i -e /^ConnectPeer/s/127.0.0.4/10.20.0.133/g \
/root/nextepc/install/etc/nextepc/freeDiameter/mme.conf
3-9.hss.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/hss.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.4";
ListenOn = "10.20.0.133";

#ConnectPeer = "mme.localdomain" { ConnectTo = "127.0.0.2"; No_TLS; };
ConnectPeer = "mme.localdomain" { ConnectTo = "10.20.0.132"; No_TLS; };

#もしくは
sed -i -e /^ListenOn/s/127.0.0.4/10.20.0.133/g \
/root/nextepc/install/etc/nextepc/freeDiameter/hss.conf
sed -i -e /^ConnectPeer/s/127.0.0.2/10.20.0.132/g \
/root/nextepc/install/etc/nextepc/freeDiameter/hss.conf
3-10.pgw.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/pgw.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.3";
ListenOn = "10.20.0.135";

#ConnectPeer = "pcrf.localdomain" { ConnectTo = "127.0.0.5"; No_TLS; };
ConnectPeer = "pcrf.localdomain" { ConnectTo = "10.20.0.136"; No_TLS; };

#もしくは
sed -i -e /^ListenOn/s/127.0.0.3/10.20.0.135/g \
/root/nextepc/install/etc/nextepc/freeDiameter/pgw.conf
sed -i -e /^ConnectPeer/s/127.0.0.5/10.20.0.136/g \
/root/nextepc/install/etc/nextepc/freeDiameter/pgw.conf
3-11.pcrf.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/pcrf.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.5";
ListenOn = "10.20.0.136";

#ConnectPeer = "pgw.localdomain" { ConnectTo = "127.0.0.3"; No_TLS; };
ConnectPeer = "pgw.localdomain" { ConnectTo = "10.20.0.135"; No_TLS; };

#もしくは
sed -i -e /^ListenOn/s/127.0.0.5/10.20.0.136/g \
/root/nextepc/install/etc/nextepc/freeDiameter/pcrf.conf
sed -i -e /^ConnectPeer/s/127.0.0.3/10.20.0.135/g \
/root/nextepc/install/etc/nextepc/freeDiameter/pcrf.conf
3-12.ip forwarding設定

最終行に追記

vi /etc/sysctl.d/99-sysctl.conf

net.ipv4.ip_forward=1

即時反映させる場合は以下のコマンド。

sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
3-13.NextEPC起動

「-d」オプションはDaemonとして起動させます。

/root/nextepc/install/bin/nextepc-epcd -d

出力例
以下のようにDaemonが起動していればOKです。

root@c77g132:~# /root/nextepc/install/bin/nextepc-epcd -d
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44

[10/20 23:18:44.126] WARN: pid file /root/nextepc/install/var/run/nextepc-epcd/pid overwritten -- Unclean shutdown of previous NextEPC run? (application.c:133)
  PID[2136] : '/root/nextepc/install/var/run/nextepc-epcd/pid'
root@c77g132:~#   File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/20 23:18:44.129] PCRF try to initialize
[10/20 23:18:44.148] PCRF initialize...done
[10/20 23:18:44.148] PGW try to initialize
[10/20 23:18:44.207] PGW initialize...done
[10/20 23:18:44.207] gtp_server() [10.20.0.135]:2123
[10/20 23:18:44.208] gtp_server() [10.20.0.135]:2152
[10/20 23:18:44.208] SGW try to initialize
[10/20 23:18:44.209] INFO: CONNECTED TO 'pgw.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/20 23:18:44.210] INFO: CONNECTED TO 'pcrf.localdomain' (TCP,soc#10): (fd_logger.c:93)
[10/20 23:18:44.217] SGW initialize...done
[10/20 23:18:44.218] gtp_server() [10.20.0.134]:2123
[10/20 23:18:44.218] gtp_server() [10.20.0.134]:2152
[10/20 23:18:44.218] HSS try to initialize
[10/20 23:18:44.268] HSS initialize...done
[10/20 23:18:44.268] MME try to initialize
[10/20 23:18:44.380] gtp_server() [10.20.0.132]:2123
[10/20 23:18:44.380] gtp_client() [10.20.0.134]:2123
[10/20 23:18:44.380] MME initialize...done


[10/20 23:18:44.380] INFO: NextEPC daemon start (main.c:177)
[10/20 23:18:44.381] INFO: CONNECTED TO 'mme.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/20 23:18:44.381] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#10): (fd_logger.c:93)
[10/20 23:18:44.387] s1ap_server() [10.20.0.132]:36412

終了させるときは、kill -9などで停止させてください。

分離させた後は以下のコマンドで個別に起動させますが、後ほど詳しく紹介します。

#c77g132:MME,HSS,SGW
/root/nextepc/install/bin/nextepc-sgwd -d
/root/nextepc/install/bin/nextepc-hssd -d
/root/nextepc/install/bin/nextepc-mmed -d

#c77g135:PGW,PCRF
/root/nextepc/install/bin/nextepc-pcrfd -d
/root/nextepc/install/bin/nextepc-pgwd -d

4.OAISIM設定

省略します。
前回記事を参照してください。

5.NextEPCの分離

5-1.クローン作成&c77g135の起動

c77g132をシャットダウン後、c77g132のクローンをc77g135として作成してください。
c77g135を起動後、ネットワーク設定やホスト名を以下のように変更します。

#c77g135の設定
nmcli con del ens35
nmcli con add type ethernet autoconnect yes ifname ens35 con-name ens35
nmcli con mod ens35 ipv4.method manual ipv4.addresses 10.20.0.135/24
nmcli con mod ens35 ipv4.method manual +ipv4.addresses 10.20.0.136/24
nmcli con up ens35

#ホスト名の変更 
vi /etc/hostname

c77g135

#再起動
reboot 
5-2.c77g132のネットワーク設定変更

c77g132を起動してください。そして、以下の通りネットワーク設定を変更してください。

#c77g132の設定
nmcli con mod ens35 ipv4.method manual -ipv4.addresses 10.20.0.135/24
nmcli con mod ens35 ipv4.method manual -ipv4.addresses 10.20.0.136/24
nmcli con up ens35

nmcli con del ens33
nmcli con del pgwtun

#再起動
reboot 
5-3.各種サービス起動

S5/S8でSPGW間を分離していますので、

/root/nextepc/install/bin/nextepc-epcd -d

は使用せず、それぞれ個別にサービスを起動します。

c77g132 MME, HSS, SGW
c77g135 PGW, PCRF
#c77g132のサービス起動:MME, HSS, SGW
/root/nextepc/install/bin/nextepc-sgwd -d
/root/nextepc/install/bin/nextepc-hssd -d
/root/nextepc/install/bin/nextepc-mmed -d

#c77g135のサービス起動:PGW, PCRF
/root/nextepc/install/bin/nextepc-pcrfd -d
/root/nextepc/install/bin/nextepc-pgwd -d

これ以降は前回記事を参照してください。

以上です。

6.最後に

以下のサイトを参考にさせて頂きました。
NextEPC | Installation | CentOS
Installing the MongoDB C Driver (libmongoc) and BSON library (libbson) — MongoDB C Driver 1.15.1

<少し余談な話>
2-1.c77g132:NextEPCのNW設定の項で、UE用インターフェースとしてpgwtunに25.0.0.0/8を設定しましたが、検証用途としてたまに利用させてもらっています。

というのも、
元々25.0.0.0/8のprefixは、英国国防省の機関であるDINSA(Defence Interoperable Network Services Authority)が所有しているそうです。
しかし、既に10年以上(15年くらいだったかも?)、インターネット上にアドバタイズされていないPrefixとなっています。
下記のようなLooking glassサイトで確認しても、フルルート上に載っていないことがわかります。
Looking Glass - NTT - www.gin.ntt.net

この情報ソースは、下記サイトのvirtual-privateの項にNoteとして記載されています。*4
libreswan

そこには、25.0.0.0/8のprefixがあまりにも長期間アドバタイズされていないため、米国のT-MobileやカナダのRogers/Fidoという通信事業者が、CGNATの前で(恐らくUE用として)使用し始めているようだ、と記載されています。

上記のように商用で使うのは、さすがに怖くてできませんが、内部的に閉じられた環境における検証用途*5であれば、Shared Address*6と同様に使ってもよいのかな?と個人的には思います。*7

*1:OAISIMについては、前回記事を参照してください。

*2:よくよく考えれば当たり前なことですし、カーネルのビルドなどをやったことある人であればdevelが必要だと気付けると思うのですが、初めてやる人にとっては、かなり敷居が高いのではないかと個人的には思います。

*3:YAML形式なのでケタ合わせは慎重に。

*4:サイトにアクセス後、25.0で検索すれば見つかります。

*5:一時的に作ってすぐ壊すような環境

*6:100.64.0.0/10として、RFC6598に記載されています。

*7:少なくてもデフォルトで設定されている45.45.0.0/16をそのまま使うのは気が引けたので。

OAISIM + NextEPCによるE-UTRAN + EPC構築方法

3GPPのお勉強や簡易検証を目的として使えそうなE-UTRAN & EPC構築方法を記載します。
UEとeNBはOAISIMにて構築し、残り*1はNextEPCで構築します。
また、MVNOライクにSGWとPGW間(S5/S8)を分離させます。

というのも、

  • SPGW間にLBを入れてPGWのメンテ検証や移行設計したり
  • QCIによる帯域制御検証したり

と色々遊べそうなので。

1.環境

1-1.VMWare
筐体                             : 自作PC(Win10pro)
CPU                           : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
VMWare              : VMware(R) Workstation 15 Pro 15.1.0 build-13591040  
OS                               : Ubuntu 16.04.6 LTS
Kernel                           : 4.4.0-142-generic
1-2.全体構成

f:id:metonymical:20191021014131p:plain

1-3 .全体の流れ ~概要~
  1. 事前準備
  2. NextEPC設定
  3. OAISIM設定
  4. NextEPCの分離*2

2.事前準備

2-1.u16c132:NextEPCのNW設定

NextEPCは後ほど分離しますが、まずはまとめて設定だけしておきます。*3
そして、ワンコール確認まで完了した後、分離します。

vi /etc/network/interfaces

auto ens33
iface ens33 inet static
    address 192.168.11.132
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.1

auto ens34
iface ens34 inet static
    address 10.10.0.135
    netmask 255.255.255.0

auto ens35
iface ens35 inet static
    address 10.20.0.132
    netmask 255.255.255.0

auto ens35:3
iface ens35:3 inet static
    address 10.20.0.133
    netmask 255.255.255.0

auto ens35:4
iface ens35:4 inet static
    address 10.20.0.134
    netmask 255.255.255.0

auto ens35:5
iface ens35:5 inet static
    address 10.20.0.135
    netmask 255.255.255.0

auto ens35:6
iface ens35:6 inet static
    address 10.20.0.136
    netmask 255.255.255.0
2-2.u16c131:OAISIMのNW設定
vi /etc/network/interfaces

auto ens33
iface ens33 inet static
    address 192.168.11.131
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.1

auto ens35
iface ens35 inet static
    address 10.20.0.131
    netmask 255.255.255.0

3.NextEPC設定

分離するまでは、u16c132のみで設定を行っていきます。

3-1.MongoDBのインストール
apt-get -y update && \
apt-get -y install mongodb && \
systemctl enable mongodb && \
systemctl start mongodb

systemctl status mongodb
3-2.pgwtunの設定

PGWのGTP終端インターフェースを作成します。

sh -c "cat << EOF > /etc/systemd/network/99-nextepc.netdev
[NetDev]
Name=pgwtun
Kind=tun
EOF"

sh -c "cat << EOF > /etc/systemd/network/99-nextepc.network
[Match]
Name=pgwtun
[Network]
Address=25.0.0.1/8
Address=cafe::1/64
EOF"

systemctl enable systemd-networkd && \
systemctl restart systemd-networkd
3-3.依存関係パッケージのインストール
apt-get -y install autoconf libtool gcc pkg-config git flex bison libsctp-dev \
libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev
3-4.ビルド
git clone https://github.com/nextepc/nextepc && \
cd /root/nextepc && \
autoreconf -iv

./configure --prefix=`pwd`/install && \
make -j `nproc` && \
make install
3-5.WebUIのインストール
apt-get -y install curl && \
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - && \
apt-get -y install nodejs

cd /root/nextepc/webui/ && \
npm install

#サービス起動
npm run dev

#アクセス先URL
http://192.168.11.132:3000/

インストール完了後、以下のページが表示されればOKです。
Username/Passwdは以下の通り。
admin/1423
f:id:metonymical:20191020140814p:plain

3-6.SIM情報の登録

上記のアクセス先URLから以下のSIM情報を登録します。

IMSI 001010100001111
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN lte.md.jp
MSISDN 33611123456
IMSI 001010100001112
Subscriber Key(Ki) 8baf473f2f8fd09487cccbd7097c6862
Operator Key(OPc) e734f8734007d6c5ce7a0508809e7e9c
USIM Type OPc
APN lte.md.jp
MSISDN 33611123457

f:id:metonymical:20191021014216p:plain
IMSI, Subscriber Key(Ki), Operator Key(OPc), USIM Typeが必須項目となります。
APNは任意で構いません。
MSISDNは、ここでは設定不要ですが、OAISIMのビルド前に必要となりますので、念のため記載しています。

3-7.nextepc.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/nextepc.conf

追記:青 コメントアウト&追記:緑

db_uri: mongodb://localhost/nextepc

logger:
    file: /root/nextepc/install/var/log/nextepc/nextepc.log
    trace:
        app: 1
        s1ap: 1
        nas: 1
        diameter: 1
        gtpv2: 1
        gtp: 1

parameter:
    no_ipv6: true

mme:
    freeDiameter: mme.conf

    s1ap:
      - addr: 10.20.0.132

    gtpc:
      - addr: 10.20.0.132

    gummei:
      plmn_id:
        mcc: 001
        mnc: 01
      mme_gid: 2
      mme_code: 1

    tai:
      plmn_id:
        mcc: 001
        mnc: 01
#      tac: 12345
      tac: 1

    security:
        integrity_order : [ EIA1, EIA2, EIA0 ]
        ciphering_order : [ EEA0, EEA1, EEA2 ]

    network_name:
        full: NextEPC

hss:
    freeDiameter: hss.conf

sgw:
    gtpc:
#      addr: 127.0.0.2
      addr: 10.20.0.134

    gtpu:
      - addr: 10.20.0.134

pgw:
    freeDiameter: pgw.conf

    gtpc:
      addr:
#        - 127.0.0.3
        - 10.20.0.135
        - ::1

    gtpu:
#      - addr: 127.0.0.3
      - addr: 10.20.0.135
      - addr: ::1

    ue_pool:
#      - addr: 45.45.0.1/16
      - addr: 25.0.0.1/8
      - addr: cafe::1/64

    dns:
      - 8.8.8.8
      - 8.8.4.4
      - 2001:4860:4860::8888
      - 2001:4860:4860::8844

pcrf:
    freeDiameter: pcrf.conf

3-8.mme.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/mme.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.2";
ListenOn = "10.20.0.132";

#ConnectPeer = "hss.localdomain" { ConnectTo = "127.0.0.4"; No_TLS; };
ConnectPeer = "hss.localdomain" { ConnectTo = "10.20.0.133"; No_TLS; };
3-9.hss.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/hss.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.4";
ListenOn = "10.20.0.133";

#ConnectPeer = "mme.localdomain" { ConnectTo = "127.0.0.2"; No_TLS; };
ConnectPeer = "mme.localdomain" { ConnectTo = "10.20.0.132"; No_TLS; };
3-10.pgw.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/pgw.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.3";
ListenOn = "10.20.0.135";

#ConnectPeer = "pcrf.localdomain" { ConnectTo = "127.0.0.5"; No_TLS; };
ConnectPeer = "pcrf.localdomain" { ConnectTo = "10.20.0.136"; No_TLS; };
3-11.pcrf.conf設定

設定変更箇所のみ抜粋。

vi /root/nextepc/install/etc/nextepc/freeDiameter/pcrf.conf

追記:青 コメントアウト&追記:緑

#ListenOn = "127.0.0.5";
ListenOn = "10.20.0.136";

#ConnectPeer = "pgw.localdomain" { ConnectTo = "127.0.0.3"; No_TLS; };
ConnectPeer = "pgw.localdomain" { ConnectTo = "10.20.0.135"; No_TLS; };
3-12.ip forwarding設定

設定変更箇所のみ抜粋。

vi /etc/sysctl.conf

追記:青 コメントアウト&追記:緑

#net.ipv4.ip_forward=0
net.ipv4.ip_forward=1

即時反映させる場合は以下のコマンド。

sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
3-13.NextEPC起動

「-d」オプションはDaemonとして起動させます。

/root/nextepc/install/bin/nextepc-epcd -d

出力例
以下のようにDaemonが起動していればOKです。

root@u16c132:~# /root/nextepc/install/bin/nextepc-epcd -d
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44

[10/20 23:18:44.126] WARN: pid file /root/nextepc/install/var/run/nextepc-epcd/pid overwritten -- Unclean shutdown of previous NextEPC run? (application.c:133)
  PID[2136] : '/root/nextepc/install/var/run/nextepc-epcd/pid'
root@u16c132:~#   File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/20 23:18:44.129] PCRF try to initialize
[10/20 23:18:44.148] PCRF initialize...done
[10/20 23:18:44.148] PGW try to initialize
[10/20 23:18:44.207] PGW initialize...done
[10/20 23:18:44.207] gtp_server() [10.20.0.135]:2123
[10/20 23:18:44.208] gtp_server() [10.20.0.135]:2152
[10/20 23:18:44.208] SGW try to initialize
[10/20 23:18:44.209] INFO: CONNECTED TO 'pgw.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/20 23:18:44.210] INFO: CONNECTED TO 'pcrf.localdomain' (TCP,soc#10): (fd_logger.c:93)
[10/20 23:18:44.217] SGW initialize...done
[10/20 23:18:44.218] gtp_server() [10.20.0.134]:2123
[10/20 23:18:44.218] gtp_server() [10.20.0.134]:2152
[10/20 23:18:44.218] HSS try to initialize
[10/20 23:18:44.268] HSS initialize...done
[10/20 23:18:44.268] MME try to initialize
[10/20 23:18:44.380] gtp_server() [10.20.0.132]:2123
[10/20 23:18:44.380] gtp_client() [10.20.0.134]:2123
[10/20 23:18:44.380] MME initialize...done


[10/20 23:18:44.380] INFO: NextEPC daemon start (main.c:177)
[10/20 23:18:44.381] INFO: CONNECTED TO 'mme.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/20 23:18:44.381] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#10): (fd_logger.c:93)
[10/20 23:18:44.387] s1ap_server() [10.20.0.132]:36412

終了させるときは、kill -9などで停止させてください。


分離させた後は以下のコマンドで個別に起動させますが、後ほど詳しく紹介します。

#u16c132:MME,HSS,SGW
/root/nextepc/install/bin/nextepc-sgwd -d
/root/nextepc/install/bin/nextepc-hssd -d
/root/nextepc/install/bin/nextepc-mmed -d

#u16c135:PGW,PCRF
/root/nextepc/install/bin/nextepc-pcrfd -d
/root/nextepc/install/bin/nextepc-pgwd -d

4.OAISIM設定

4-1.git リポジトリの取得
apt-get install git && \
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git && \
cd /root/openairinterface5g && \
git reset --hard 67df8e0e7b46200b2ee43a2705def3340ddfd719
4-2.SIM情報の設定

変更箇所のみ抜粋。UEを2台アタッチさせられるように1台追加しています。

vi /root/openairinterface5g/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf

#画面下の方にスクロール

追記:青 コメントアウト&追記:緑

UE0:
{
    USER: {
        IMEI="356113022094149";
        MANUFACTURER="EURECOM";
        MODEL="LTE Android PC";
        PIN="0000";
    };

    SIM: {
        MSIN="0100001111";
        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
        OPC="e734f8734007d6c5ce7a0508809e7e9c";
        MSISDN="33611123456";
    };

    # Home PLMN Selector with Access Technology
#    HPLMN= "20893";
    HPLMN= "00101";

    # User controlled PLMN Selector with Access Technology
    UCPLMN_LIST = ();

    # Operator PLMN List
    OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028");

    # Operator controlled PLMN Selector with Access Technology
    OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204");

    # Forbidden plmns
    FPLMN_LIST = ();

    # List of Equivalent HPLMNs
#TODO: UE does not connect if set, to be fixed in the UE
#    EHPLMN_LIST= ("20811", "20813");
    EHPLMN_LIST= ();
};

UE1:
{
    USER: {
        IMEI="356113022094150";
        MANUFACTURER="EURECOM";
        MODEL="LTE Android PC";
        PIN="0000";
    };

    SIM: {
        MSIN="0100001112";
        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
        OPC="e734f8734007d6c5ce7a0508809e7e9c";
        MSISDN="33611123457";
    };

    # Home PLMN Selector with Access Technology
    HPLMN= "00101";

    # User controlled PLMN Selector with Access Technology
    UCPLMN_LIST = ();

    # Operator PLMN List
    OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028");

    # Operator controlled PLMN Selector with Access Technology
    OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204");

    # Forbidden plmns
    FPLMN_LIST = ();

    # List of Equivalent HPLMNs
#TODO: UE does not connect if set, to be fixed in the UE
#    EHPLMN_LIST= ("20811", "20813");
    EHPLMN_LIST= ();
};
4-3.ビルド
cd /root/openairinterface5g/cmake_targets && \
./build_oai -I --oaisim --install-system-files

ビルドの最後の方で、以下のように文字化けしますが、ビルドは正常に完了している(ハズなので)ので、exitで抜けて、再度ログインし直してください。

出力例
文字化けしますが、前項で修正したue_eurecom_test_sfr.confの変更点が反映されていることが確認できます。
赤文字箇所

Log file for compilation has been written to: /root/openairinterface5g/cmake_targets/log/usim.Rel14.txt
usim compiled
Log file for compilation has been written to: /root/openairinterface5g/cmake_targets/log/nvram.Rel14.txt
nvram compiled
Log file for compilation has been written to: /root/openairinterface5g/cmake_targets/log/conf2uedata.Rel14.txt
conf2uedata compiled
generate .ue_emm.nvram .ue.nvram

UE's non-volatile data:

IMEI            = 356113022094149
manufacturer    = EURECOM
model           = LTE Android PC
PIN             = 0000
UE identity data file: /root/openairinterface5g/targets/bin/.ue.nvram0

EMM non-volatile data:

IMSI            = 001.010.100001111
RPLMN           = 00101
EPS Mobility Management data file: /root/openairinterface5g/targets/bin/.ue_emm.nvram0

UE's non-volatile data:

IMEI            = 356113022094150
manufacturer    = EURECOM
model           = LTE Android PC
PIN             = 0000
UE identity data file: /root/openairinterface5g/targets/bin/.ue.nvram1

EMM non-volatile data:

IMSI            = 001.010.100001112
RPLMN           = 00101
EPS Mobility Management data file: /root/openairinterface5g/targets/bin/.ue_emm.nvram1
generate .usim.nvram

USIM data:

Administrative Data:
        UE_Operation_Mode       = 0x00
        Additional_Info         = 0xffff
        MNC_Length              = 2

IMSI:
        length  = 8
        parity  = Odd
        digits  = 15
        digits  = 001010100001111

Ciphering and Integrity Keys:
        KSI     : 0x07
        CK      : ""
        IK      : ""

        usim_api_k: 8b af 47 3f 2f 8f d0 94 87 cc cb d7 09 7c 68 62
        opc       : e7 34 f8 73 40 07 d6 c5 ce 7a 05 08 80 9e 7e 9c

EPS NAS security context:
        KSIasme : 0x07
        Kasme   : ""
        ulNAScount      : 0x00000000
        dlNAScount      : 0x00000000
        algorithmID     : 0x02

MSISDN  = 336 1112 3456

PNN[0]  = {Test network, OAI4G}
PNN[1]  = {SFR France, SFR}
PNN[2]  = {SFR France, SFR}
PNN[3]  = {SFR France, SFR}
PNN[4]  = {OAI LTEBOX, OAIALU}
PNN[5]  = {T-Mobile USA, T-MobileCニノテヤノヤノマユモ ユモチ
ミホホロカン  ス 鈼ノテヤノヤノマユモ ユモチャ ニノテヤノヤノマ
ミホホロキン  ス 譿 

マミフローン  ス ーーアーアャ ヤチテ ス ローーーア ュ 跏趾ンャ 胥゚鱠 ス ー
マミフロアン  ス イークアーャ ヤチテ ス ローーーア ュ 跏趾ンャ 胥゚鱠 ス ア

~~~ 中略 ~~~

ホチモテマホニノヌコ
        ホチモ゚モ鱸髜・鴃醪・鴟・         コ ーー
        ホヘマ゚ノ゚ツ裴磋鴆                 コ ーー
        チ矼鞅鴟靄炫・                 コ ーア
        ヘ鴃鳫ミ褪鴆蓚耨裔靫鳫褪      コ ーー
        ナ褓蒟菽聽褫碪鰀           コ ーー
        ヤ鳫褪゚ヤウイエオ゚ツ裴磋鴆           コ ーー
ユモノヘ 蓊 跌・コ ッ・ッ・褓硅ⅵ褪趁肄オ遽襁粳鉧ョ鳫ョⅷ敎
フ・ 跌・ 跣・胥瀇鴈磑鴆・鞦・粢褓 鴟・コ ッ・ッ・褓硅ⅵ褪趁肄オ遽肬硴裃襁・遽・鱇襁鞜碚ョメ褌アエョ・
・鱇襁鞜碚 胥瀇鴈裝
・糀硅゚碚ョ 鴣 ・鸙裝  ナヤネナメホナヤ ・糘碪・
アーョ ツ碯鰀 ・ヤ褫 ョョョ
・タカ羈ウアコッ・褓硅ⅵ褪趁肄オ遽肬硴裃襁

<補足1>
ビルド実行時、バイナリ化されたnvramファイル*4にSIM情報が書き込まれ、以下のパスに保存されます。*5

/openairinterface5g/targets/bin

SIM情報を追加・変更・削除したい場合は、以下のファイルを再度編集の上、

vi /root/openairinterface5g/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf

以下のコマンドで再ビルドしてください。

./build_oai -c --oaisim

<補足2>
以前*6は、以下のコマンドにてSIM情報の書き換えが可能でした。

cd ~/openairinterface5g/targets/bin/
./conf2uedata -c /root/openairinterface5g/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o ./

しかし、今回利用したリポジトリ

git reset --hard 67df8e0e7b46200b2ee43a2705def3340ddfd719

では、
conf2uedataコマンドを実行しても変更したSIM情報がnvramファイルに反映されなかったので、再ビルドしたところ正常に反映されました。

4-4.S1インターフェース周りの設定
vi /root/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf

修正箇所

    mobile_country_code =  "001";

    mobile_network_code =  "01";

#画面下の方までスクロール

    ////////// MME parameters:
    mme_ip_address      = ( { ipv4       = "10.20.0.132";
                              ipv6       = "192:168:30::17";
                              active     = "yes";
                              preference = "ipv4";
                            }
                          );

    NETWORK_INTERFACES :
    {
        ENB_INTERFACE_NAME_FOR_S1_MME            = "ens35";
        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.20.0.131/24";

        ENB_INTERFACE_NAME_FOR_S1U               = "ens35";
        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.20.0.131/24";
        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
    };
4-5.UEの起動台数変更
vi /root/openairinterface5g/cmake_targets/tools/run_enb_ue_virt_s1

修正箇所

#vi上で、「AAWG」で検索してください。

#  exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u1 -Q0"
  exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u2 -Q0"
4-6.eNB起動

以下のコマンドでeNBを起動させます。

/root/openairinterface5g/cmake_targets/tools/run_enb_ue_virt_s1

もし、u16c132:NextEPC側でEPC関連サービスを起動していない場合は、先に以下のコマンドを実行してから、上記のeNB起動を行ってください。

/root/nextepc/install/bin/nextepc-epcd -d

出力例1
u16c132:EPC側の出力例

root@u16c132:~# /root/nextepc/install/bin/nextepc-epcd -d
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44

[10/21 00:16:27.288] WARN: pid file /root/nextepc/install/var/run/nextepc-epcd/pid overwritten -- Unclean shutdown of previous NextEPC run? (application.c:133)
root@u16c132:~#   PID[2495] : '/root/nextepc/install/var/run/nextepc-epcd/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:16:27.290] PCRF try to initialize
[10/21 00:16:27.344] PCRF initialize...done
[10/21 00:16:27.346] PGW try to initialize
[10/21 00:16:27.418] PGW initialize...done
[10/21 00:16:27.418] gtp_server() [10.20.0.135]:2123
[10/21 00:16:27.418] gtp_server() [10.20.0.135]:2152
[10/21 00:16:27.420] SGW try to initialize
[10/21 00:16:27.420] INFO: CONNECTED TO 'pgw.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/21 00:16:27.421] INFO: CONNECTED TO 'pcrf.localdomain' (TCP,soc#13): (fd_logger.c:93)
[10/21 00:16:27.426] SGW initialize...done
[10/21 00:16:27.427] gtp_server() [10.20.0.134]:2123
[10/21 00:16:27.427] gtp_server() [10.20.0.134]:2152
[10/21 00:16:27.427] HSS try to initialize
[10/21 00:16:27.462] HSS initialize...done
[10/21 00:16:27.462] MME try to initialize
[10/21 00:16:27.583] MME initialize...done


[10/21 00:16:27.584] INFO: NextEPC daemon start (main.c:177)
[10/21 00:16:27.584] INFO: CONNECTED TO 'mme.localdomain' (TCP,soc#7): (fd_logger.c:93)
[10/21 00:16:27.584] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#10): (fd_logger.c:93)
[10/21 00:16:27.584] gtp_server() [10.20.0.132]:2123
[10/21 00:16:27.584] gtp_client() [10.20.0.134]:2123
[10/21 00:16:27.584] s1ap_server() [10.20.0.132]:36412

#NextEPC起動時はここまで出力されます。
eNBが起動しS1の通信が開始&アタッチ処理が正常に完了すると、さらに以下のログが出力されます。
UEにアドレスがアサインされていることが確認できます。

[10/21 00:18:07.933] eNB-S1 accepted[10.20.0.131]:36412 in s1_path module
[10/21 00:18:07.934] eNB-S1 accepted[10.20.0.131] in master_sm module
[10/21 00:18:13.416] gtp_client() [10.20.0.132]:2123
[10/21 00:18:13.416] gtp_client() [10.20.0.135]:2123
[10/21 00:18:13.416] gtp_client() [10.20.0.134]:2123
[10/21 00:18:13.416] UE IPv4:[25.0.0.2] IPv6:
[10/21 00:18:13.416] gtp_client() [10.20.0.134]:2152
[10/21 00:18:13.419] gtp_client() [10.20.0.135]:2152
[10/21 00:18:13.821] gtp_client() [10.20.0.131]:2152
[10/21 00:18:14.204] UE IPv4:[25.0.0.3] IPv6:

出力例2
u16c131:eNB側の出力例
以下のようなログが最終的に出力している、かつ、UEのIPアドレスが確認できれば、アタッチは正常に完了しています。
ちなみに、eNB側のログは不定期に出力し続けます。また、ErrorやWarning、Fatalといったメッセージも、ちらほら見受けられますが、あまり気にしないでください。
eNB起動時のログは大量に出力されるため、こちらにアップしました。

[SCTP][I][4][50] Msg of length 62 received from port 36412, on stream 1, PPID 18
[S1AP][I]Decoding message S1ap_DownlinkNASTransportIEs (/root/openairinterface5g/cmake_targets/oaisim_build_oai/build/CMakeFiles/R10.5/s1ap_decoder.c:3150)
[RRC][I][eNB 0] Received S1AP_DOWNLINK_NAS: ue_initial_id 0, eNB_ue_s1ap_id 116541
[PDCP][I][FRAME 00000][eNB][MOD 00][RNTI c745]Received RRC_DCCH_DATA_REQ from TASK_RRC_ENB: instance 0, rb_id 2, muiP 6, confirmP 0, mode 1
[RLC][I][FRAME 00000][eNB][MOD 00][RNTI c745][SRB AM 02] RLC_AM_DATA_REQ size 44 Bytes,  NB SDU 1 current_sdu_index=0 next_sdu_index=1 conf 0 mui 6 vtA 0 vtS 0
[MAC][I][eNB 0], Frame 72, DCCH1->DLSCH, CC_id 0, Requesting 125 bytes from RLC (RRC message)
[PHY][E]Format1A Retransmission but TBS are different: consider it as new transmission !!!
[OSA][E]Mismatch found in integrity for algorithm 2,
        got 60.38.89.c0, expecting 00.00.00.00
[PDCP][E][OSA][RB 2] UE failed to validate MAC-I of incoming PDU
[RRC][N][UE 0] Frame 72: received a DCCH 2 message on SRB 2 with Size 39 from eNB 0
[RRC][E][UE 0] Frame 72: Received message on DL-DCCH (SRB2), should not have ...
[MAC][I][eNB 0], Frame 73, DCCH1->DLSCH, CC_id 0, Requesting 125 bytes from RLC (RRC message)
bad DCI 1A !!!
[PHY][I]bad dci mcs + round
bad DCI 1 !!!
[PHY][E][UE  0] Frame 287, subframe 8: Problem in DCI!
[PHY][E]frame 681, subframe 7, rnti c745, format 0: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[450] > RIV_max[324]
[PHY][E]Wrong DCI0 detection, do not transmit PUSCH for HARQID: 5
[PHY][I][UE  0] frame 683, subframe 2: received DCI 0 with RNTI=0 (C-RNTI:c745, CBA_RNTI 0) and format 2!
[PHY][I]bad dci rballoc rballoc 7346  RIV_max 324
bad DCI 1 !!!
[PHY][E][UE  1] Frame 795, subframe 9: Problem in DCI!
4-7.UEアドレス確認

oip1というインターフェースに25.0.0.x/8のアドレスがアサインされていれば、UEのアタッチ成功です。
今回はUE0とUE1の2台分のIPアドレスアサインされています。

ip add show

root@u16c131:~# ip add show
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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: ens33:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:41:02:e1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.131/24 brd 192.168.11.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe41:2e1/64 scope link
       valid_lft forever preferred_lft forever
3: ens34:  mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:0c:29:41:02:eb brd ff:ff:ff:ff:ff:ff
4: ens35:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:41:02:f5 brd ff:ff:ff:ff:ff:ff
    inet 10.20.0.131/24 brd 10.20.0.255 scope global ens35
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe41:2f5/64 scope link
       valid_lft forever preferred_lft forever
65: oip0:  mtu 1500 qdisc noop state DOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
66: oip1:  mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
    inet 25.0.0.5/8 brd 25.255.255.255 scope global oip1
       valid_lft forever preferred_lft forever
67: oip2:  mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
    inet 25.0.0.4/8 brd 25.255.255.255 scope global oip2
       valid_lft forever preferred_lft forever
68: oip3:  mtu 1500 qdisc noop state DOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00
~~~ 中略 ~~~
84: oip19:  mtu 1500 qdisc noop state DOWN group default qlen 100
    link/generic 00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00

SGiのGWアドレスにoip1を指定して、Pingを飛ばしてみてください。*7

root@u16c131:~# ping 10.10.0.254 -I oip1
PING 10.10.0.254 (10.10.0.254) from 25.0.0.5 oip1: 56(84) bytes of data.
64 bytes from 10.10.0.254: icmp_seq=1 ttl=63 time=131 ms
64 bytes from 10.10.0.254: icmp_seq=2 ttl=63 time=86.7 ms
64 bytes from 10.10.0.254: icmp_seq=3 ttl=63 time=98.3 ms
64 bytes from 10.10.0.254: icmp_seq=4 ttl=63 time=83.4 ms
^C
--- 10.10.0.254 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 83.452/99.940/131.223/18.888 ms
4-8.route追加

うまくPingが飛ばない場合は、u16c131側にDefaultGWアドレスを設定し、既存のDefaultGWアドレスは削除してみてください。

DefaultGWアドレスの設定

route add default gw 25.0.0.1

既存DefaultGWアドレスの削除

vi /etc/network/interfaces

削除箇所

auto ens33
iface ens33 inet static
    address 192.168.11.131
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.1

auto ens35
iface ens35 inet static
    address 10.20.0.131
    netmask 255.255.255.0

systemctl restart networking

ここまでで、ほぼ完成です。
あとは、MVNOライクにS5/S8でSPGWを分離する手順となります。

Pingが飛ばなかったり、IPアドレスアサインされない場合は、u16c132のens35とens34をtcpdumpしてみてください。*8

5.NextEPCの分離

5-1.クローン作成&u16c135の起動

u16c132をシャットダウン後、u16c132のクローンをu16c135として作成してください。
u16c135を起動後、ネットワーク設定やホスト名を以下のように変更します。

#u16c135の設定

vi /etc/network/interfaces

追記箇所 修正箇所 削除箇所

auto ens33
iface ens33 inet static
    address 192.168.11.135
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.1

auto ens34
iface ens34 inet static
    address 10.10.0.135
    netmask 255.255.255.0
    gateway 10.10.0.254

auto ens35
iface ens35 inet static
    address 10.20.0.135
    netmask 255.255.255.0

auto ens35:3
iface ens35:3 inet static
    address 10.20.0.133
    netmask 255.255.255.0

auto ens35:4
iface ens35:4 inet static
    address 10.20.0.134
    netmask 255.255.255.0

auto ens35:5
iface ens35:5 inet static
    address 10.20.0.135
    netmask 255.255.255.0

auto ens35:6
iface ens35:6 inet static
    address 10.20.0.136
    netmask 255.255.255.0

#ホスト名の変更 
vi /etc/hostname

u16c135

#再起動
reboot 
5-2.u16c132のネットワーク設定変更

u16c132を起動してください。そして、以下の通りネットワーク設定を変更してください。

#u16c132の設定

vi /etc/network/interfaces

削除箇所

auto ens33
iface ens33 inet static
    address 192.168.11.132
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.1

auto ens34
iface ens34 inet static
    address 10.10.0.135
    netmask 255.255.255.0

auto ens35
iface ens35 inet static
    address 10.20.0.132
    netmask 255.255.255.0

auto ens35:3
iface ens35:3 inet static
    address 10.20.0.133
    netmask 255.255.255.0

auto ens35:4
iface ens35:4 inet static
    address 10.20.0.134
    netmask 255.255.255.0

auto ens35:5
iface ens35:5 inet static
    address 10.20.0.135
    netmask 255.255.255.0

auto ens35:6
iface ens35:6 inet static
    address 10.20.0.136
    netmask 255.255.255.0

#再起動
reboot 
5-3.各種サービス起動

S5/S8でSPGW間を分離していますので、

/root/nextepc/install/bin/nextepc-epcd -d

は使用せず、それぞれ個別にサービスを起動します。

u16c132 MME, HSS, SGW
u16c135 PGW, PCRF
#u16c132のサービス起動:MME, HSS, SGW
/root/nextepc/install/bin/nextepc-sgwd -d
/root/nextepc/install/bin/nextepc-hssd -d
/root/nextepc/install/bin/nextepc-mmed -d

#u16c135のサービス起動:PGW, PCRF
/root/nextepc/install/bin/nextepc-pcrfd -d
/root/nextepc/install/bin/nextepc-pgwd -d
5-4.eNBの起動

以下のコマンドで再度eNBを起動します。
S5/S8で分離されても、「4-6.eNB起動」以降で動作確認したのと同様に疎通確認してください。

#u16c131で実行

/root/openairinterface5g/cmake_targets/tools/run_enb_ue_virt_s1
5-5.起動時のログ

eNB起動時の

  • u16c132:MME,HSS,SGW
  • u16c135:PGW,PCRF

におけるログとPcapファイルをアップしておきます。
なお、u16c131:UE,eNBの出力ログは4-6の出力例2に載せたものと同様です。

#u16c132の出力例

root@u16c132:~# /root/nextepc/install/bin/nextepc-sgwd -d
root@u16c132:~# /root/nextepc/install/bin/nextepc-hssd -d
root@u16c132:~# /root/nextepc/install/bin/nextepc-mmed -d
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44
  PID[1857] : '/root/nextepc/install/var/run/nextepc-sgwd/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:59:10.412] SGW try to initialize
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44
  PID[1860] : '/root/nextepc/install/var/run/nextepc-hssd/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:59:10.421] HSS try to initialize
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44
[10/21 00:59:10.463] HSS initialize...done
[10/21 00:59:10.464] INFO: NextEPC daemon start (main.c:177)
  PID[1873] : '/root/nextepc/install/var/run/nextepc-mmed/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:59:10.466] MME try to initialize
[10/21 00:59:10.478] SGW initialize...done
[10/21 00:59:10.478] INFO: NextEPC daemon start (main.c:177)
[10/21 00:59:10.478] gtp_server() [10.20.0.134]:2123
[10/21 00:59:10.478] gtp_server() [10.20.0.134]:2152
[10/21 00:59:10.607] gtp_server() [10.20.0.132]:2123
[10/21 00:59:10.607] gtp_client() [10.20.0.134]:2123
[10/21 00:59:10.607] MME initialize...done
[10/21 00:59:10.607] INFO: NextEPC daemon start (main.c:177)
[10/21 00:59:10.608] INFO: CONNECTED TO 'mme.localdomain' (TCP,soc#8): (fd_logger.c:93)
[10/21 00:59:10.608] INFO: CONNECTED TO 'hss.localdomain' (TCP,soc#11): (fd_logger.c:93)
[10/21 00:59:10.615] s1ap_server() [10.20.0.132]:36412

~~~以下はeNBが接続してきた際に出力されるログ~~~
[10/21 01:00:41.550] eNB-S1 accepted[10.20.0.131]:36412 in s1_path module
[10/21 01:00:41.550] eNB-S1 accepted[10.20.0.131] in master_sm module
[10/21 01:00:46.461] gtp_client() [10.20.0.132]:2123
[10/21 01:00:46.461] gtp_client() [10.20.0.135]:2123
[10/21 01:00:46.466] gtp_client() [10.20.0.135]:2152
[10/21 01:00:46.868] gtp_client() [10.20.0.131]:2152

#u16c135の出力例

root@u16c135:~# /root/nextepc/install/bin/nextepc-pcrfd -d
root@u16c135:~# /root/nextepc/install/bin/nextepc-pgwd -d
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44
  PID[1870] : '/root/nextepc/install/var/run/nextepc-pcrfd/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
NextEPC daemon v0.3.10 - Oct 20 2019 23:04:44
MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:59:23.198] PCRF try to initialize
  PID[1873] : '/root/nextepc/install/var/run/nextepc-pgwd/pid'
  File Logging : '/root/nextepc/install/var/log/nextepc/nextepc.log'
  MongoDB URI : 'mongodb://localhost/nextepc'
  Configuration : '/root/nextepc/install/etc/nextepc/nextepc.conf'
[10/21 00:59:23.199] PGW try to initialize
[10/21 00:59:23.235] PCRF initialize...done
[10/21 00:59:23.236] INFO: NextEPC daemon start (main.c:177)
[10/21 00:59:23.352] PGW initialize...done
[10/21 00:59:23.352] INFO: NextEPC daemon start (main.c:177)
[10/21 00:59:23.352] gtp_server() [10.20.0.135]:2123
[10/21 00:59:23.352] gtp_server() [10.20.0.135]:2152
[10/21 00:59:23.354] INFO: CONNECTED TO 'pgw.localdomain' (TCP,soc#9): (fd_logger.c:93)
[10/21 00:59:23.355] INFO: CONNECTED TO 'pcrf.localdomain' (TCP,soc#13): (fd_logger.c:93)

~~~以下はUEにIPアドレスアサインされた際に出力されるログ~~~
[10/21 01:00:46.409] gtp_client() [10.20.0.134]:2123
[10/21 01:00:46.409] UE IPv4:[25.0.0.2] IPv6:
[10/21 01:00:46.409] gtp_client() [10.20.0.134]:2152
[10/21 01:00:46.573] UE IPv4:[25.0.0.3] IPv6:

eNB起動時のPcapファイルはこちらにアップしました。
u16c135のens35でpcapしています。

以上です。

6.最後に

以下のサイトを参考にさせて頂きました。
【プライベートLTE】 第3回:プライベートLTE設備の構築 ~Open Air Interface(OAISIM)による端末(UE)・基地局(eNB)擬似環境の紹介~
LTEを自作してみる(Part2) - Qiita
LTEを自作してみる(Part3) - Qiita

最初の記事が@m0ch1_m0ch1さん、残り2つの記事が@K5Kさんによって書かれています。
お二方はE-UTRANやEPCに関して造詣が深く、大変よくまとめられた記事となっており、これらのサイトが無ければ、今回の記事は書けなかったので、ぜひぜひ読んでみてください。

私個人的にですが、モバイルネットワークの技術は、もっとコモディティ化してもよいと考えています。
最近、プライベートLTEやローカル5Gといった言葉(キーワード)をよく耳にしますが、誰でも簡単に扱えるか?というと、まだもう少し時間がかかるのだろうと思います。
とはいえ、ただただ時間が経つのを待っていれば扱えるようになるか?といえば、それもまた違うと思うで、自ら積極的かつ能動的にこれらの技術を獲りに行ける環境を、まずは構築してみるのが良いのでは?と考えています。

今回の記事はまだ初期段階ですが、次のステップとしては、最初に書いたようなことに加えて、

  • LXC/LXDやDockerなどでコンテナ化してみる
  • SGi側でBGPがしゃべれるようにQuaggaを入れてみる
  • OAISIMが重く不安定なのでリッチな物理サーバに換装してみる

など、色々できることはあるのかなと考えています

*1:MME,HSS,SGW,PGW,PCRF

*2:S5/S8でMME, HSS, SGWとPGW, PCRFを2つのNextEPCに分離します。

*3:分離する際に削除すればいいので。

*4:出力例に表示されている通り、.ue.nvram0とか.ue.nvram1など

*5:本来はUSRPなどでH/W処理されるプロセスをOAISIMとしてS/Wでシミュレートするためバイナリ化するのだと考えています。実際、バイナリ化していても、UE&eNodeBを起動すると、4CoreのCPU使用率が30~40%くらいで推移するため、S/Wでシミュレートするには相当負荷が掛かる処理のようです。

*6:v0.6.1のbranchでは大丈夫でした。

*7:GWアドレスを持つL3デバイスに25.0.0.0/8宛の戻り経路を忘れずに設定してください。

*8:出力例2にも記載しましたが、Phy層でFatal Errorなどのログが出力されていてもPingが飛びます。このため、一度でも成功したことがないと、どういう状態になっていればOKか?の判断が極めて困難だと思います。私自身も最初は勘所が全く掴めなかったので苦労しました。