4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kubernetes環境でfree 5GCを動かすまで

Last updated at Posted at 2023-03-15

修士の研究でfree 5GCをKubernetes上で動かす必要があったが、どちらも全く触ったことがなかったので備忘録として手順を残しておく。

ポートとかファイアウォールとかセキュリティに関してはザルなので(とにかく動くこと優先)、その辺は参考にしないように。

2台のPCを使って同一LAN内で環境構築することを前提とする。

マシンの準備

何はともあれマシンを準備する。
研究室でおねだりした結果、ノートPCとデスクトップの2台のPCを借りられたのでノートPCをMaster Node, デスクトップをWorker Nodeとして使う。

  • Master Node(DELL XPS-13-9305)
    CPU: 第11世代 インテル® Core™ i7-1165G7
    メモリ: 16GB 4267MHz LPDDR4x メモリー

  • Worker Node(研究室で余ってたやつ)
    CPU: インテル® Core™ i7-11700
    メモリ: 32GB 8GB*4枚

OSのセッティング

ubuntuをインストールしてカーネルのバージョンを下げる。

Ubuntuのインストール

今回はUbuntu 20.04 LTSをインストールする。Worker Nodeには何のOSも入っていなかったので、何の工夫もなくインストールできたが、Master Nodeには元々windowsがインストールされているのでデュアルブートする必要がある。
https://www.pc-koubou.jp/magazine/35542 などを参考にデュアルブートしてください。(ミスるとwindowsごとぶっ壊す可能性があるので自己責任で)

カーネルのダウングレード

5GCのパケット処理に使われるカーネルモジュールgtp5gはlinuxのカーネルバージョンが5.4以下でないと動作しないので、カーネルをダウングレードする。

https://kazuhira-r.hatenablog.com/entry/2020/03/08/141730 
https://level69.net/archives/31142

この辺の記事を参考にカーネルバージョンを下げる。

各種モジュールのインストール

free5gcのパケット処理に使われるgtp5g、kubernetesのコンテナランタイムとなるdocker、kubernetes環境を構築するためのツールkubeadmをインストールする。 

gtp5gのインストール

リポジトリを参考にインストール

git clone https://github.com/free5gc/gtp5g.git
cd gtp5g
make clean && make
sudo make install

dockerのインストール

kubernetesのコンテナランタイム(CRI)にはdocker, containerd, CRI-Oの三つがあるが、今回はdockerを採用する。理由としてはcadvisorでコンテナメトリクスを収集するのにdockerである必要があるから。

ちなみにkubernetesではdockerが非推奨になっているっぽい。dockerの内部にはcontainerdがあるため、dockerとcontainerdがどちらも入っているとdockerが優先される。

こちらを参考にインストール

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
apt-cache policy docker-ce

今回インストールしたdockerのバージョンは23.0.1。サーバーとクライアントのバージョンは揃えているが、揃わないと動かないかは知らん。

最後にこのコマンドでインストールできる。

sudo apt install docker-ce=23.0.1

dockerがインストールできているか確認する。

sudo docker version

ちゃんとインストールされていれば次のように出力される。 

Client: Docker Engine - Community
 Version:           23.0.1
 API version:       1.42
 Go version:        go1.19.5
 Git commit:        a5ee5b1
 Built:             Thu Feb  9 19:46:56 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.1
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.5
  Git commit:       bc3805a
  Built:            Thu Feb  9 19:46:56 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.16
  GitCommit:        31aa4358a36870b21a992d3ad2bef29e1d693bec
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

kubeadm, kubelet, kubectlのインストール

kubeadmはkubernetesクラスターの構築をめちゃめちゃ簡単にできるツールで、kubeadm initkubeadm joinの二つのコマンドを提供する。
kubeadm initは最初にクラスターを作成する時に使い、(今回のように2台構成なら)Master Nodeで打つ。
kubeadm joinはクラスターにノードを追加する時に使い、Worker Nodeや2つ目以降のMaster Nodeで打つ。

kubeletはクラスター内の全てのマシンで実行され、podの起動などを請け負っている。(ユーザーがこのコマンドを使うことはあんまりない)

kubectlはクラスターを操作するコマンド。 デプロイや削除など基本的にはこのコマンドで全てを行う。

kubeadmをインストールする前にいくつか準備が必要。

MACアドレスとproduct_uuidが全てのノードでユニークであることの検証

ip linkもしくはifconfig -aでMACアドレスを確認。
また、sudo cat /sys/class/dmi/id/product_uuidでproduct_uuidを確認。
今回はハードウェアが異なるので、どちらもユニークだったが、VMの場合はこれらが同じになる場合がある。

iptablesがブリッジを通過するトラフィックを処理できるようにする

何してるかはよくわからんが、公式ページに書いてあったのでやっておく。(通信についての設定かな?)

modprobe br_netfilter

cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

必須ポートの確認

このサイトの通りにポートを開いておく。

https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
 
開いているポートの確認はsudo ufw statusでできる。
ポートの解放はsudo ufw allow <開きたいポート番号>でできる。

スワップをオフにする

kubernetesではメモリのスワップがあると動作しないのでMasterもWorkerもどちらもswapoff -aでスワップをオフにする。

kubeadm, kubelet, kubectlのインストール

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

kubeadmでクラスター作成

kubernetesクラスターの作成にはkubeadmを使う。

kubeadm init

Master Nodeでkubeadm initをしてクラスターを作成する。

kubeadm init --apiserver-advertise-address=172.19.109.201 --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock

apiserver-advertise-addressはクラスター内で使うipアドレスを指定している。Master Nodeのipアドレスを指定しておく。

pod-network-cidrはpod間通信をするためのCNIが利用するipアドレス。

cri-socketはdockerdのソケットのパスを渡す。

成功すると、次のコマンドを打つよう指示されるのでコマンドを打つ。

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

CNI(flannel)の導入

pod間通信を可能にする仮想ネットワークのアドオンであるflannelを導入する。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

動いたか確認

kubectl get nodes

kubeadm joinでWorker Nodeを追加

kubeadm initした際にWorker Nodeを追加する用のコマンドが出力されるので、それをWorker Nodeで打つ。

kubeadm join 172.19.109.201:6443 --token <表示されるtoken> --discovery-token-ca-cert-hash sha256:...

追加されたら、Master Nodeで確認

kubectl get nodes

二つのノードが表示されたらOK

クラスターのリセット

色々試しててクラスターがぐちゃぐちゃになってしまった時はクラスターをリセットする。(マジで役に立った)

Master NodeでWorker Nodeを削除する

kubectl delete node <worker nodeの名前>

Worker NodeとMaster Nodeからreset

kubeadm reset --force
systemctl stop kubelet
rm -rf /etc/kubernetes/
rm -rf ~/.kube/
rm -rf /var/lib/kubelet/
rm -rf /var/lib/cni/
rm -rf /etc/cni/
rm -rf /var/lib/etcd/
iptables -F && iptables -X

注) 最後のiptablesは実行するとwifiや有線LANが繋がらなくなるかもしれないので、繋がらなくなったら再起動しましょう。

ノードを再起動したら、
これで完全にリセットされるので、再度クラスターを作成する。

デプロイ

free5gcやらcadvisorやらprometheusやら色々デプロイしていく。

free5gcのデプロイ

ここにfree5gcのマニフェストファイルがあるので、これを利用する。(stage-3.1.1を利用するが、確認すると無くなってる)

マニフェストファイルの詳しい説明は省略するが、podの様式をyamlで書いておいて簡単にデプロイできるようにしたもの。

このfree5gcのcnfをクラスター上にデプロイしていく。

以降のコマンドは全てMaster Nodeで実行する。
まず、namespaceを作成する。

kubectl create namespace free5gc

namespaceはクラスター上の仮想環境みたいなもの。

free5gcは次の順番でデプロイしていく。
NRF > UDR > UDM > AUSF > NSSF > AMF > PCF > UPF > SMF
必ず、前のpodがrunningになったことを確認してから次のNFをデプロイする。

kubectl apply -f 03-free5gc-nrf.yaml -n free5gc
kubectl apply -f 06-free5gc-udr.yaml -n free5gc
kubectl apply -f 08-free5gc-udm.yaml -n free5gc
kubectl apply -f 10-free5gc-ausf.yaml -n free5gc
kubectl apply -f 09-free5gc-nssf.yaml -n free5gc
kubectl apply -f 04-free5gc-amf.yaml -n free5gc
kubectl apply -f 07-free5gc-pcf.yaml -n free5gc
kubectl apply -f 02-free5gc-upf.yaml -n free5gc
kubectl apply -f 05-free5gc-smf.yaml -n free5gc
kubectl apply -f 01-free5gc-mongodb.yaml -n free5gc
kubectl apply -f 11-free5gc-webui.yaml -n free5gc

正常に動作しているか確認。

>> kubectl get pods -n free5gc


NAME                                        READY   STATUS    RESTARTS   AGE
free5gc-amf-deployment-5b94ff96d-f5vjh      1/1     Running   0          3m7s
free5gc-ausf-deployment-5548b989-nvc9f      1/1     Running   0          3m39s
free5gc-mongodb-7d954666d4-mvmnz            1/1     Running   0          62s
free5gc-nrf-deployment-5f9666c4f4-8l9m7     1/1     Running   0          4m42s
free5gc-nssf-deployment-586cb84fcd-zfzzn    1/1     Running   0          3m23s
free5gc-pcf-deployment-6f99976745-pp9tq     1/1     Running   0          2m48s
free5gc-smf-deployment-7647c6787-hm9c8      1/1     Running   0          2m17s
free5gc-udm-deployment-6f5f499c5f-pkktr     1/1     Running   0          3m58s
free5gc-udr-deployment-5749586f77-dqnrl     1/1     Running   0          4m13s
free5gc-upf-deployment-5f575485fc-tkwrh     1/1     Running   0          2m32s
free5gc-webui-deployment-57cc7b5498-gpdfr   1/1     Running   0          27s

web uiの確認
クラスターのPCから確認する場合は、http://<web uiのpodのipアドレス>:5000

podのipアドレスは次のコマンドで確認できる。

>> kubectl get pods -n free5gc -o wide


NAME                                        READY   STATUS    RESTARTS   AGE     IP            NODE                  NOMINATED NODE   READINESS GATES
free5gc-amf-deployment-5b94ff96d-f5vjh      1/1     Running   0          9m20s   10.244.1.7    system-product-name   <none>           <none>
free5gc-ausf-deployment-5548b989-nvc9f      1/1     Running   0          9m52s   10.244.1.5    system-product-name   <none>           <none>
free5gc-mongodb-7d954666d4-mvmnz            1/1     Running   0          7m15s   10.244.1.11   system-product-name   <none>           <none>
free5gc-nrf-deployment-5f9666c4f4-8l9m7     1/1     Running   0          10m     10.244.1.2    system-product-name   <none>           <none>
free5gc-nssf-deployment-586cb84fcd-zfzzn    1/1     Running   0          9m36s   10.244.1.6    system-product-name   <none>           <none>
free5gc-pcf-deployment-6f99976745-pp9tq     1/1     Running   0          9m1s    10.244.1.8    system-product-name   <none>           <none>
free5gc-smf-deployment-7647c6787-hm9c8      1/1     Running   0          8m30s   10.244.1.10   system-product-name   <none>           <none>
free5gc-udm-deployment-6f5f499c5f-pkktr     1/1     Running   0          10m     10.244.1.4    system-product-name   <none>           <none>
free5gc-udr-deployment-5749586f77-dqnrl     1/1     Running   0          10m     10.244.1.3    system-product-name   <none>           <none>
free5gc-upf-deployment-5f575485fc-tkwrh     1/1     Running   0          8m45s   10.244.1.9    system-product-name   <none>           <none>
free5gc-webui-deployment-57cc7b5498-gpdfr   1/1     Running   0          6m40s   10.244.1.12   system-product-name   <none>           <none>

クラスター外(同一LAN内)から確認する場合
http://<Worker Nodeのローカルipアドレス>:31111

web uiはID/pass:admin/free5gc でログインできる。

スクリーンショット 2023-03-07 21.15.45.png

UERANSIMのデプロイ

UERANSIMはその名の通りUEと基地局のシミュレータで、いろんなシミュレーションができる。

まず、UERANSIMのマニフェストファイルを書き換える。
gnbのマニフェストファイルを以下の部分を書き換える。

  name: ueransim-gnb-configmap
data:
  free5gc-gnb.yaml: |
    mcc: '208'          # Mobile Country Code value
    mnc: '93'           # Mobile Network Code value (2 or 3 digits)

    nci: '0x000000010'  # NR Cell Identity (36-bit)
    idLength: 32        # NR gNB ID length in bits [22...32]
    tac: 1              # Tracking Area Code

-    linkIp: 10.244.3.31  # gNB's local IP address for Radio Link Simulation (Usually same with local IP)
-    ngapIp: 10.244.3.31   # gNB's local IP address for N2 Interface (Usually same with local IP)    
-    gtpIp: 10.244.3.31    # gNB's local IP address for N3 Interface (Usually same with local IP)
+    linkIp: 10.244.1.13  # gnbのpodのipアドレス
+    ngapIp: 10.244.1.13  # gnbのpodのipアドレス
+    gtpIp: 10.244.1.13   # gnbのpodのipアドレス

    # List of AMF address information
    amfConfigs:
-      - address: 10.244.3.22
-        port: 38412
+      - address: 10.244.1.7  # AMFのpodのipアドレス
+        port: 38412 # AMFのSCTPプロトコルのポート

kubernetesのpodのipアドレスは一つずつインクリメントされるため、最後にデプロイされたpodのipアドレス(ここではweb ui)に1足したものを入力する。

変更したらデプロイする。

kubectl apply -f ueransim/ueransim-gnb.yaml -n free5gc

podの中に入って、is-ngap-up: trueになることを確認。

kubectl -n free5gc exec -it ueransim-gnb-deployment-7cf855fc85-z998r -- bash

/UERANSIM# cd build
/UERANSIM/build# ./nr-cli UERANSIM-gnb-208-93-1
-------------------------------------------------------------------------------------
$ status
is-ngap-up: true
-------------------------------------------------------------------------------------

次にueransim-ue.yamlの次の部分を書き換える。

data:
  free5gc-ue.yaml: |
    # IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 digits)
    supi: 'imsi-208930000000003'
    # Mobile Country Code value of HPLMN
    mcc: '208'
    # Mobile Network Code value of HPLMN (2 or 3 digits)
    mnc: '93'

    # Permanent subscription key
    key: '8baf473f2f8fd09487cccbd7097c6862'
    # Operator code (OP or OPC) of the UE
    op: '8e27b6af0e692e750f32667a3b14605d'
    # This value specifies the OP type and it can be either 'OP' or 'OPC'
    opType: 'OP'
    # Authentication Management Field (AMF) value
    amf: '8000'
    # IMEI number of the device. It is used if no SUPI is provided
    imei: '356938035643803'
    # IMEISV number of the device. It is used if no SUPI and IMEI is provided
    imeiSv: '4370816125816151'

    # List of gNB IP addresses for Radio Link Simulation
    gnbSearchList:
-      - 10.244.3.31
+      - 10.244.1.13 # gnbのpodのipアドレス

書き換えたらデプロイ

kubectl apply -f ueransim/ueransim-ue.yaml -n free5gc

podの中に入って確認

kubectl -n free5gc exec -it ueransim-ue-deployment-dd445b88d-wcmm9 -- bash

/UERANSIM# cd build
/UERANSIM/build# ./nr-cli -d imsi-208930000000003
imsi-208930000000003
/UERANSIM/build# ./nr-cli imsi-208930000000003
-------------------------------------------------------------------------------------
$ status
cm-state: CM-CONNECTED
rm-state: RM-REGISTERED
mm-state: MM-REGISTERED/NORMAL-SERVICE
5u-state: 5U1-UPDATED
sim-inserted: true
selected-plmn: 208/93
current-cell: 1
current-plmn: 208/93
current-tac: 1
last-tai: PLMN[208/93] TAC[1]
stored-suci: no-identity
stored-guti: 
 plmn: 208/93
 amf-region-id: 0xca
 amf-set-id: 1016
 amf-pointer: 0
 tmsi: 0x00000001
has-emergency: false
-------------------------------------------------------------------------------------

cm-state: CM-CONNECTEDになっていることを確認

cAdvisorのデプロイ

dockerのコンテナメトリクスを収集できるcAdvisorを導入する。
まずはnamespaceの作成。

kubectl create namespace cadvisor

cadvisorのgithubにkubernetes用のマニフェストファイルがあるので、これを利用。

daemonset.yamlの最後に次のコードを追加

---          
apiVersion: v1
kind: Service
metadata:
  name: cadvisor
  namespace: cadvisor
spec:
  selector:
    app: cadvisor
  ports:
  - protocol: TCP
    port: 8080
    nodePort: 30080
  type: NodePort

これによってサービスとして外部に公開できる。

kustomizeによってデプロイする。

kubectl apply -k cadvisor/ -n cadvisor

デプロイできたか確認

>> kubectl get pod -n cadvisor
NAME             READY   STATUS    RESTARTS   AGE
cadvisor-z6v7l   1/1     Running   0          21s


>> kubectl get service -n cadvisor
NAME       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
cadvisor   NodePort   10.102.196.48   <none>        8080:30080/TCP   33s


>> kubectl get daemonset -n cadvisor
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
cadvisor   1         1         1       1            1           <none>          42s

uiにはfree5gcのweb uiと同様にアクセスできる。

スクリーンショット 2023-03-07 21.15.31.png

prometheusのデプロイ

httpプル方式でメトリクスを蓄積、監視するprometheusを導入して、cadvisorのメトリクスをこちらに流す。

https://uzimihsr.github.io/post/2022-11-28-kubernetes-prometheus-kube-state-metrics-cadvisor-ja/
こちらを参考にprometheusのマニフェストファイルとコンフィグファイルをgistにしたので、これを使えばできるはず。

kubectl -n prometheus create serviceaccount prometheus
kubectl create clusterrole prometheus --verb=get,list,watch --resource=pods,services,endpoints
kubectl create clusterrolebinding prometheus --clusterrole=prometheus --serviceaccount=prometheus:prometheus
kubectl apply -f configmap.yaml -n prometheus
kubectl apply -f deployment.yaml -n prometheus

uiにアクセスできるか確認。
スクリーンショット 2023-03-07 21.38.55.png

service discoveryにcadvisorがあることを確認。
スクリーンショット 2023-03-07 21.40.39.png

デプロイメントの削除

デプロイしたものを削除したいときは次のコードで削除できる。

kubectl delete -f 01-free5gc-mongodb.yaml -n free5gc
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?