從零拆解-怎么把Go項(xiàng)目部署到K8s上運(yùn)行
K8s 基礎(chǔ)
K8s現(xiàn)在在各家公司的普及度已經(jīng)很高,網(wǎng)上介紹它的資料也有很多,那什么是K8s呢?它的本名叫Kubernetes(單詞太長(zhǎng),后面還是用 K8s 代替 )是一個(gè)基于容器技術(shù)的分布式架構(gòu)方案。
它具備完善的集群管理能力,包括多層次的安全防護(hù)和準(zhǔn)入機(jī)制、多租戶應(yīng)用支撐能力、透明的服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)機(jī)制、內(nèi)建負(fù)載均衡器、故障發(fā)現(xiàn)和自我修復(fù)能力、服務(wù)滾動(dòng)升級(jí)和線上擴(kuò)容、可擴(kuò)展的資源自動(dòng)調(diào)度機(jī)制、多粒度的資源配額管理能力。還提供完善的管理工具,涵蓋開(kāi)發(fā)、部署測(cè)試、運(yùn)維監(jiān)控等各個(gè)環(huán)節(jié)。
總結(jié)一句話:是一套結(jié)合了容器編排和集群調(diào)度管理的大規(guī)模分布式系統(tǒng)解決方案。
在K8s 中會(huì)把各種資源抽象成對(duì)象--簡(jiǎn)而言之就是面向?qū)ο螅蟮郊旱墓?jié)點(diǎn)(Node)、小到配置項(xiàng) (ConfigMap) 都是對(duì)象,常用的有以下對(duì)象。
圖片
Pod是K8s 里的最小調(diào)度單元,Pod里面則是容器(一個(gè)Pod里可以有多個(gè)容器,但只有一個(gè)主容器,其他都是輔助它的)。
控制器則是管理 Pod 用的,對(duì)于我們來(lái)說(shuō)常用的控制器只有Deployment,它能夠控制Pod的滾動(dòng)更新。
圖片
Deployment 是一個(gè)復(fù)合型的控制器,它包裝了一個(gè)叫做 ReplicaSet -- 副本集的控制器。ReplicaSet 管理正在運(yùn)行的Pod數(shù)量,Deployment 在其之上實(shí)現(xiàn) Pod 滾動(dòng)更新,對(duì)Pod的運(yùn)行狀況進(jìn)行健康檢查以及回滾更新的能力。他們?nèi)咧g的關(guān)系可以用下面這張圖表示。
圖片
另外還有就是K8s的操作都是通過(guò)kubectl 把指令提交給集群的,這里匯總了一些比較常用的kubectl命令
- kubectl apply -f xxx.yaml 讓K8s 創(chuàng)建在集群里按配置文件創(chuàng)建/更新資源對(duì)象
- kubectl get pod | deploy | svc | ingress 查看集群中的pod、Deployment、Service、Ingress 資源的狀態(tài)
- kubectl describe pod | deploy | svc | ingress {$objectName} 查看具體資源對(duì)象當(dāng)前的詳細(xì)信息
- kubectl delete pod | deploy | svc | ingress {$objectName} 刪除指定對(duì)象
Go Mall 項(xiàng)目部署到 K8s
接下來(lái)我們演示一下怎么把我們專欄的項(xiàng)目部署到K8s上,首先說(shuō)明一點(diǎn),因?yàn)槲覀冺?xiàng)目依賴的MySQL和Redis都是在本地電腦上安裝的,把項(xiàng)目部署到容器后就沒(méi)辦法再用本地電腦上的MySQL和Redis了,所以在演示項(xiàng)目的K8s部署和運(yùn)行時(shí)還需要把MySQL在Redis都部署到K8s上,這樣他們才能在集群內(nèi)部通信。
所以我們首先把項(xiàng)目中 application.test.yaml 的數(shù)據(jù)庫(kù)和Redis的連接配置做一個(gè)更改:
app:
......
database:
master:
type:mysql
#通過(guò)k8s service name連接, 在k8s集群內(nèi)的管理 mysql pod的service名是mysql
dsn:root:superpass@tcp(mysql:3306)/go_mall?charset=utf8&parseTime=True&loc=Asia%2FShanghai
maxopen:100
maxidle:10
maxlifetime:300000000000
redis:
addr:redis:6379#通過(guò)k8s service name連接, 在k8s集群內(nèi)的管理 redis pod的service名是redis
password:123456
pool_size:
這也就意味著我們把項(xiàng)目部署到K8s時(shí),還需要給它指定ENV環(huán)境變量為test,這樣才能應(yīng)用上這個(gè)配置文件。
接下來(lái)我們就看一下go-mall項(xiàng)目的 Deployment 文件的定義
apiVersion: apps/v1
kind:Deployment
metadata:
name:go-mall
spec:
replicas:2
selector:
matchLabels:
app:go-mall-app
template:
metadata:
labels:
app:go-mall-app
spec:
containers:
-name:go-mall-container
image:go-mall:v202501111557
env:
-name:ENV
value:test
resources:
limits:
memory:"200Mi"
cpu:"50m"
ports:
-containerPort:8080
volumeMounts:
-name:app-log
mountPath:/home/applog
volumes:
-name:app-log
hostPath:
path:/tmp/applog
type:DirectoryOrCreate
Deployment中template下的配置是關(guān)于Pod的定義,其中容器鏡像指定的是 go-mall:v202501111557,我們每次發(fā)版本部署的時(shí)候都會(huì)給這個(gè)鏡像版本,然后再提交給K8s集群讓他們負(fù)責(zé)滾動(dòng)更新。
env選項(xiàng)中我們指定了ENV=test的環(huán)境變量,此外我們還把容器中的日志文件目錄/home/applog 掛載到了電腦上的/tmp/applog目錄。
把項(xiàng)目部署到K8s上去后,如果不做任何操作它只能在K8s的集群內(nèi)部訪問(wèn),如果想要在集群外部能訪問(wèn)就需要用Service把它們暴露出來(lái)。
apiVersion: v1
kind:Service
metadata:
name:go-mall-svc
spec:
type:NodePort
selector:
app:go-mall-app
ports:
-name:http
protocol:TCP
nodePort:32080
port:8080
targetPort:8080
這個(gè)Service服務(wù)管理標(biāo)簽為 app: go-mall-app 的Pod,并把它們通過(guò)端口32080暴露到集群外部。
好了關(guān)于項(xiàng)目的K8s配置介紹的差不多了,但是我們現(xiàn)在還不能把它們提交給K8s,需要先把依賴的MySQL和Redis部署上去。這里我給大家準(zhǔn)備好了運(yùn)行整個(gè)項(xiàng)目需要的全套K8s配置,點(diǎn)下面的鏈接即可下載:https://github.com/user-attachments/files/18385362/go-mall-k8s.zip
需訂閱專欄后聯(lián)系我開(kāi)通項(xiàng)目權(quán)限才能訪問(wèn)
下載解壓后,項(xiàng)目的目錄如下:
圖片
部署到K8s后怎么調(diào)試
把我們的項(xiàng)目部署到K8s后,因?yàn)樵谌萜髦羞\(yùn)行,想要調(diào)試就沒(méi)有在本地IDE里那么方便了,這里介紹幾個(gè)必要的命令幫助大家調(diào)試。
首先是kubctl get pods | grep go-mall 來(lái)查看現(xiàn)在正運(yùn)行著go-mall項(xiàng)目的Pod,上面我們講解過(guò),我們給項(xiàng)目分配了兩個(gè)復(fù)制集,所以這個(gè)命令會(huì)顯示出兩個(gè)Pod。
如果我們想要要登錄到其中一個(gè)Pod中,那么需要我們執(zhí)行以下命令(注意下面的Pod名稱 go-mall- 后面是隨機(jī)的,執(zhí)行時(shí)記得換成自己當(dāng)時(shí)查看到的Pod名稱)
kubectl exec -it go-mall-6459549b69-cmwsb -- /bin/sh
假如說(shuō)我們通過(guò)kubectl get pods 查看Pod時(shí)發(fā)現(xiàn) go-mall-6459549b69-cmwsb 這個(gè)Pod 啟動(dòng)失敗了,大概率是項(xiàng)目啟動(dòng)時(shí)有問(wèn)題,那么這個(gè)時(shí)候需要我們查看Pod當(dāng)時(shí)寫(xiě)到標(biāo)準(zhǔn)輸出中的日志,怎么查看呢?用下面這個(gè)命令。
kubectl logs go-mall-6459549b69-cmwsb
執(zhí)行的時(shí)候也是記得要換成自己的Pod名哦,不要直接抄過(guò)去。