iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0

本文目標:

  • 介紹 Infra labs
  • 使用 kubeadm 安裝 kubernetes
  • 在 kubernetes 上安裝 free5GC
  • 簡單的探討分散式架構的 log 蒐集方式

Cloud Native Infra Labs 計畫

Infra lab 是由 Cloud Native Taiwan User Group 發起,其目的在於培養基礎設施相關的技術人員(學生或是工程師都可以申請)。
申請該計畫後會取得一個 OpenStack 帳號,讓你能夠在上面學習基礎設施技術:

申請成功後,你會被分配到一定的硬體資源,這些資源可以用來建立 VM Instance。

安裝 Kubernetes

在這篇文章中,我會使用 kubeadm 安裝 Kubernetes 至兩台 VM 上:

參考上圖,在這次的實驗中,我會將 vm-1 作為 k8s cluster 的 controller node,vm-2 則作為一般的 worker node。

前置作業

以下設定需要套用在 vm-1 以及 vm-2 這兩台機器上。
首先,關閉 swap space:

$ swapoff -a

修改 host file:

$ vim /etc/hosts

新增 vm-1 以及 vm-2 的主機位址內容如下:

127.0.0.1 localhost
10.10.3.193 vm-1 # vm-1 的私網 IP
10.10.2.176 vm-2 # vm-2 的私網 IP

在安裝 Kubernetes 之前,我們還需要先檢查系統是否已經安裝 Docker,如果沒有,請輸入以下指令完成安裝:

$ apt-get install -y docker.io

安裝完成後,讓我們準備安裝 Kubernetes 吧!

$ apt-get update && apt-get install -y apt-transport-https curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl

安裝 kubeletkubeadmkubectl 後,我們需要設定 kubeadm 的 configuration:

$ vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  • 10-kubeadm.conf 新增 Environment=”cgroup-driver=systemd/cgroup-driver=cgroupfs”

設定 controll plane

文章前面有提到,在這次的範例中筆者使用 vm-1 作為 k8s cluster 的 controll plane。因此,以下設定只需要套用到 vm-1 即可:

$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=<IP_OF_VM1>
  • 由於我們選用 Calico 作為 CNI,所以按照建議將 pod 的 CIDR 設置為 192.168.0.0/16
  • <IP_OF_VM1> 需代入 vm-1 的內網 IP。

初始化工作完成後,我們會看到以下訊息:

kubeadm 會要求我們在 vm-1 輸入以下命令:

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

同時畫面切換到 vm-2,使用 kubeadm join 加入 cluster:

加入完成後,在 vm-1 上面輸入 kubectl get node,這時 kubectl 會表示兩個節點都處於 Not ready 階段。之所以會處於 Not ready,是因為我們沒有為它安裝 CNI。

$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml
$ curl https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml -O
$ kubectl create -f custom-resources.yaml

參考 calico 官方文件,依序輸入上述命令即可完成 calico 的安裝,輸入這些命令後,我們可以使用 kubectl get pod -n calico-system 檢查 calico 為我們建立了哪些資源:

當 CNI 完成安裝後,我們可以預期 vm-1 與 vm-2 切換至 Ready 狀態:

$ kubectl get node
NAME   STATUS   ROLES           AGE     VERSION
vm-1   Ready    control-plane   5h57m   v1.25.1
vm-2   Ready    <none>          5h55m   v1.25.1

確認狀態符合預期代表 Kubernetes 的安裝與設定就告一個段落囉!

安裝 gtp5g

使用以下命令完成安裝:

$ git clone https://github.com/free5gc/gtp5g.git
$ cd gtp5g
$ sudo apt-get install linux-headers-`uname -r`
$ make
$ sudo make install

安裝 free5gc

筆者本來計畫使用昨天介紹 helm 提到的 towards5gs 專案,沒想到在安裝上遇到了一些無法解決的問題。
因此,本篇文會先用實驗室學長實作的專案為主。

首先,我們先將專案 clone 至 vm-1:

$ git clone https://github.com/oommcclee/k8s-helm-free5gc.git

接著,參考 ./charts/mongo/templates/persistentvolume.yaml 的內容設定 nfs server,或是依據個人設定修改 persistentVolume 的 path。
如果你只有運作一個節點,那麼可以直接把 path 修改為 hostPath:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /tmp

接下來,讓我們輸入 helm install free5gc-k8s . 完成 helm chart 的安裝。
當安裝完成後,我們預期看到以下資源:

root@vm-1:/home/ubuntu/k8s-helm-free5gc# kubectl get pod
NAME                     READY   STATUS             RESTARTS         AGE
amf-78b79c6686-8cd8w     1/1     Running            0                4h35m
ausf-85f5bd98cd-lrv7m    1/1     Running            0                4h35m
mongo-0                  1/1     Running            0                4h35m
nrf-7bf78bf5f5-qb948     1/1     Running            0                4h35m
nssf-67d484dc58-t68mb    1/1     Running            0                4h35m
pcf-6d746c8dd9-mtbn4     1/1     Running            0                4h35m
smf-7645654b6c-rrqn6     1/1     Running            0                4h35m
udm-659665bd6c-8nzf8     1/1     Running            0                4h35m
udr-567f677998-zq9rv     1/1     Running            0                4h35m
ulcl-58445d58f5-ws46n    1/1     Running            0                4h35m
upf1-667d5d9cf8-wgswz    1/1     Running            0                4h35m
webui-67595f44c9-44b8t   1/1     Running            0                4h25m

root@vm-1:/home/ubuntu/k8s-helm-free5gc# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
amf-78b79c6686     1         1         1       4h36m
ausf-85f5bd98cd    1         1         1       4h36m
nrf-7bf78bf5f5     1         1         0       4h36m
nssf-67d484dc58    1         1         1       4h36m
pcf-6d746c8dd9     1         1         1       4h36m
smf-7645654b6c     1         1         1       4h36m
udm-659665bd6c     1         1         1       4h36m
udr-567f677998     1         1         1       4h36m
ulcl-58445d58f5    1         1         1       4h36m
upf1-667d5d9cf8    1         1         1       4h36m
webui-67595f44c9   1         1         1       4h36m

root@vm-1:/home/ubuntu/k8s-helm-free5gc# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)            AGE
amf          NodePort    10.105.94.190    <none>        38412:30412/SCTP   4h36m
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP            6h7m
mongo        NodePort    10.99.27.231     <none>        27017:30017/TCP    4h36m
webui        NodePort    10.100.125.214   <none>        5000:30300/TCP     4h36m

觀察 service 列表,可以發現 webui 藉由 service 物件將 pod 的 5000 port 與本地的 30300 port 做了對應。所以,使用 curl 向 127.0.0.1:30300 發出請求應該能得到 html 檔案:

root@vm-1:/home/ubuntu/k8s-helm-free5gc# curl 127.0.0.1:30300
<!doctype html><html lang="en" class="perfect-scrollbar-off"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous"><link href="https://fonts.googleapis.com/css?family=Open+Sans:100,400,600,700" rel="stylesheet"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.0/gh-fork-ribbon.min.css"/><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>free5GC Web Console</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><div class="clearfix"></div><div style="margin:14px;font-size:18px;float:left">Loading...</div><script src="https://unpkg.com/react-jsonschema-form/dist/react-jsonschema-form.js"></script><script type="text/javascript" src="/static/js/main.2c86c86b.js"></script></body></html>

小技巧:觀察 pod 的 log

使用 kubectl logs 可以觀察特定 pod 的 log:

kubectl logs amf-78b79c6686

在沒有設定 security group 的情況下,進入 webui

將 vm-1 的 5000 port forward 到 local:

ssh -L localhost:30300:localhost:30300 ubuntu@<IP_OF_VM1> -i <SECRET_FILE>

打開瀏覽器輸入 http://localhost:30300/#/ 並登入 webconsole 就能夠設定 Subscriber 的資訊囉:

蒐集 pod 的 log

以微服務架構部署應用程式都會碰到 log 蒐集的問題,grafana lab 提出的 Loki 專案是 log collection 的解決方案之一,我們可以使用它加上之前介紹過的 Prometheus(專注於 metrics)加上 Grafana 打造服務的監控面板與告警系統。


上圖取自官網,Loki 的設計靈感很多來自於 Prometheus,它只對 metadata 進行索引的設計也讓它比起其他的解決方案有著更好的查詢效能。


而整個工作流程也與 Prometheus 十分相似,它提供 Promtail 在 Cluster 中的每一個節點上運作,並且蒐集 log。最後這些 log 會聚合到 Loki 並儲存到 permanenet storage 上。
輸出的部分可以搭配 Loki cli、Grafana 或是 Prometheus alert manager。

安裝方式可以參考對岸的文章:https://blog.csdn.net/networken/article/details/120491802

總結

其實筆者申請 Infra labs 也有好一段時間了,不過平常因為工作加上課業的關係真的沒什麼時間玩它 Orz
一直到連假才終於把之前搞到爛掉的環境處理完畢+寫稿。
呼應到系列文的主題,5G 核心網路將服務拆成了很多個 Network Function,所以很多問題都可以用微服務架構的解決方案嘗試,甚至部署方式也可以使用 IaC 或是 GitOps 達成,如果手邊沒有什麼大型服務可以實驗但又想要學習維運的技能,我想 free5GC 真的是一個不錯的練習對象。

References


上一篇
使用 Helm 管理 Kubernetes 資源
下一篇
淺談 Infrastructure as Code
系列文
5G 核心網路與雲原生開發之亂彈阿翔36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言