在Kubernetes环境下,直到成功运行free 5GC为止

因為研究碩士的需要,我需要在Kubernetes上運行free 5GC,但由於我對這兩者都沒有接觸過,所以我將把步驟記錄下來作為備忘錄。

由于端口,防火墙和安全方面都相当松散(首要目标是使其正常运行),请不要参考这些方面。

前提是使用两台计算机在同一局域网内进行环境配置。

机器的准备

在准备好设备之前,我向实验室请求,并成功借到了一台笔记本电脑和一台台式电脑,所以我将笔记本电脑用作主节点,台式电脑用作工作节点。

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

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

操作系统的设置

安装Ubuntu并降低内核版本。

安装Ubuntu系统

这次要安装Ubuntu 20.04 LTS。由于Worker Node没有安装任何操作系统,所以可以毫无工作就进行安装,但由于Master Node原本安装了Windows,所以需要进行双重引导。
请参考https://www.pc-koubou.jp/magazine/35542等进行双重引导。(如果操作不当可能会彻底损坏Windows,请自行承担责任)

内核降级

为了处理5GC数据包,需要使用的内核模块gtp5g要求运行在Linux内核版本为5.4以下,所以需要降级内核。

请将以下内容以中文本地化的方式进行改写,只需要一种选项:

仮想マシンのUbuntuのKernelをダウングレードする

根据这些文章参考,降低内核版本。

安裝各種模組

安装用于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 init和kubeadm join。kubeadm init用于首次创建集群时使用,例如在这种场景中,可以在主节点上执行。而kubeadm join用于在集群中添加节点时使用,可以在工作节点或第二个及之后的主节点上执行。

kubelet在集群中的所有机器上运行,并负责启动pod等任务。(用户很少使用该命令)

kubectl是操作集群的命令。基本上,可以使用此命令来进行部署、删除等操作。

在安装kubeadm之前,需要进行一些准备工作。

验证在所有节点上MAC地址和product_uuid是唯一的。

可以使用ip link或ifconfig -a命令来确认MAC地址。
另外,可以使用sudo cat /sys/class/dmi/id/product_uuid命令来确认product_uuid。
由于本次硬件不同,所以这两个值都是唯一的,但在虚拟机的情况下,可能会出现它们相同的情况。

使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

请确认必要的端口

按照这个网站的说明打开端口。

可以使用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初始化

使用 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地址。请提前指定主节点的IP地址。

pod-network-cidr是用于容器间通信的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)

引入一个名为flannel的插件,它是一个能够实现pod间通信的虚拟网络。

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

确认是否移动过

kubectl get nodes

使用kubeadm join命令来添加Worker节点。

当您运行”kubeadm init”时,将输出用于添加工作节点的命令,请在工作节点上运行该命令。

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

当有任何追加时,请在主节点上进行确认。

kubectl get nodes

当有两个节点显示时,可以接受

重置集群

当你尝试了各种方法,导致集群变得一团糟时,重置集群是个好办法。(真的非常有用)

删除Worker Node在Master Node上。

kubectl delete node <worker nodeの名前>

重置来自工作节点和主节点的状态。

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命令可能导致无线网络或有线局域网断开连接,如果出现断开,请重新启动。

当节点重新启动,
它将被完全重置,因此需要重新创建集群。

部署

我会部署各种不同的东西,像是free5gc、cadvisor、prometheus等等。

请部署free5gc。

因为这里有 free5gc 的清单文件,所以我要使用它(我打算使用 stage-3.1.1,但是确认后发现它已经不在了)。

 

详细解释清单文件将被省略,但是将pod的样式用yaml语言写下,以便能够简单地通过部署。

将这个free5gc的cnf部署到集群上。

所有以下命令都在主节点上执行。
首先,创建一个命名空间。

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

通过集群中的 PC 进行确认时,请访问 http://: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>

如果从集群外(同一局域网内)进行确认,可以使用以下地址:
http://<Worker节点的本地ip地址>:31111

网页用户界面可用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状态为已连接

cAdvisor的部署

首先,需要安装cAdvisor来收集Docker容器的度量信息。
首先,创建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

你可以像访问free5gc的web界面一样访问ui。

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

Prometheus的部署

使用HTTP拉取方式引入Prometheus来存储和监视度量指标,并将cAdvisor的度量指标发送到此处。

我把这个链接中的示例作为参考,将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
スクリーンショット 2023-03-07 21.38.55.png
スクリーンショット 2023-03-07 21.40.39.png

 

删除部署

当你想要删除已部署的东西时,你可以使用以下代码进行删除。

kubectl delete -f 01-free5gc-mongodb.yaml -n free5gc
广告
将在 10 秒后关闭
bannerAds