在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以下,所以需要降级内核。
请将以下内容以中文本地化的方式进行改写,只需要一种选项:
根据这些文章参考,降低内核版本。
安裝各種模組
安装用于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 进行登录。

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。

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


删除部署
当你想要删除已部署的东西时,你可以使用以下代码进行删除。
kubectl delete -f 01-free5gc-mongodb.yaml -n free5gc