我們用一個系列來講解從需求到上線、從程式碼到k8s部署、從日誌到監控等各個方面的微服務完整實踐。
整個專案使用了go-zero開發的微服務,基本包含了go-zero以及相關go-zero作者開發的一些中介軟體,所用到的技術棧基本是go-zero專案組的自研元件,基本是go-zero全家桶了。
實戰專案地址:https://github.com/Mikaelemmmm/go-zero-looklook
1、概述
上一節,我們已經把gitlab、jenkins、harbor、k8s都已經搭建好了,這一節我們來編寫jenkins的pipline將我們的服務通過jenkins完整的釋出到k8s中。
2、部署中介軟體
將mysql、redis、es等部署到k8s之外 , 模擬用作線上獨立環境(至於線上你想把某些中介軟體部署到k8s內部這個自行處理,本次重點是如何將go-zero開發的微服務部署到k8s叢集內部),這裡我就直接使用專案下的docker-compose-env.yaml了,把所有依賴的第三方中介軟體環境直接安裝在srv-data.com(192.168.1.181)這臺伺服器,前提是這臺伺服器已經安裝好docker、docker-compose。
登陸到 192.168.1.181
$ mkdir data && cd data && vim docker-compose.yml
$ docker-compose up -d
$ docker-compose ps #檢視確認
3、獨立配置
將每個服務的配置都獨立出來,統一放在一個git倉庫,這樣只給一個人線上倉庫的許可權,如果線上配置有變直接修改這個倉庫的檔案,在jenkins做cd的時候,會先拉取程式碼再拉取對應服務的配置自動構建,具體可以看後面的pipline。
【問】為什麼不用配置中心?
1)修改db、redis等需要重啟服務,但是有一些配置又不需要重啟服務,運維又要去記,記混了比較容易造成線上事故
2)方便回滾。我們發新版本到線上,並且又改了新版本配置。這時候線上使用者反饋有問題,線上需要快速回滾的話,如果我們使用將檔案構建到映象中,直接使用k8s一行命令就可以將上一個版本程式碼加配置直接回滾回來。如果使用了配置中心,回滾了程式碼,還要將上個版本的配置去配置中心改回來,很麻煩。
獨立線上倉庫目錄結構如下(這個結構是跟pipline中寫法相關的)
倉庫地址 : https://github.com/Mikaelemmmm/go-zero-looklook-pro-conf , 直接下載就好
1、修改配置中的中介軟體,資料庫、redis等都要改成192.168.1.181這臺機器,我們把這臺機器當成線上環境的中介軟體。
2、另外一個就是我們的服務發現,線上我們部署在k8s中,go-zero直接支援k8s服務發現,所以不需要etcd等,我們在配置zrpc client的時候,要改成target,k8s的配置方式。
4、編寫 jenkins 的 pipline
4.1 配置引數
訪問 http://192.168.1.180:8989/ 開啟jenkins,進入jenkins首頁,點選左側選單新建Item
我們先建立 identity
授權服務的流水線
然後點選“General” , 選擇“This project is parameterized” , "新增引數",“Choice Parameter”,如下圖
然後編寫內容如下
直接儲存。
4.2 編寫pipline
向下滑動找到Pipeline script
,填寫指令碼內容
pipeline {
agent any
parameters {
gitParameter name: 'branch',
type: 'PT_BRANCH',
branchFilter: 'origin/(.*)',
defaultValue: 'master',
selectedValue: 'DEFAULT',
sortMode: 'ASCENDING_SMART',
description: '選擇需要構建的分支'
}
stages {
stage('服務資訊') {
steps {
sh 'echo 分支:$branch'
sh 'echo 構建服務型別:${JOB_NAME}-$type'
}
}
stage('拉取程式碼') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: '$branch']],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook.git']]])
}
}
stage('獲取commit_id') {
steps {
echo '獲取commit_id'
git credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook.git'
script {
env.commit_id = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
}
}
stage('拉取配置檔案') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: '$branch']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'conf']],
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook-pro-conf.git']]])
}
}
stage('goctl版本檢測') {
steps{
sh '/usr/local/bin/goctl -v'
}
}
stage('Dockerfile Build') {
steps{
sh 'yes | cp -rf conf/${JOB_NAME}/${type}/${JOB_NAME}.yaml app/${JOB_NAME}/cmd/${type}/etc' //線上配置檔案
sh 'cd app/${JOB_NAME}/cmd/${type} && /usr/local/bin/goctl docker -go ${JOB_NAME}.go && ls -l'
script{
env.image = sh(returnStdout: true, script: 'echo ${JOB_NAME}-${type}:${commit_id}').trim()
}
sh 'echo 映象名稱:${image} && cp app/${JOB_NAME}/cmd/${type}/Dockerfile ./ && ls -l && docker build -t ${image} .'
}
}
stage('上傳到映象倉庫') {
steps{
//docker login 這裡要注意,會把賬號密碼輸出到jenkins頁面,可以通過port.sh類似方式處理,官網文件有這裡我就不詳細寫了
sh 'docker login --username=${docker_username} --password=${docker_pwd} http://${docker_repo}'
sh 'docker tag ${image} ${docker_repo}/go-zero-looklook/${image}'
sh 'docker push ${docker_repo}/go-zero-looklook/${image}'
}
}
stage('部署到k8s') {
steps{
script{
env.deployYaml = sh(returnStdout: true, script: 'echo ${JOB_NAME}-${type}-deploy.yaml').trim()
env.port=sh(returnStdout: true, script: '/root/port.sh ${JOB_NAME}-${type}').trim()
}
sh 'echo ${port}'
sh 'rm -f ${deployYaml}'
sh '/usr/local/bin/goctl kube deploy -secret docker-login -replicas 2 -nodePort 3${port} -requestCpu 200 -requestMem 50 -limitCpu 300 -limitMem 100 -name ${JOB_NAME}-${type} -namespace go-zero-looklook -image ${docker_repo}/${image} -o ${deployYaml} -port ${port} --home /root/template'
sh '/usr/local/bin/kubectl apply -f ${deployYaml}'
}
}
stage('Clean') {
steps{
sh 'docker rmi -f ${image}'
sh 'docker rmi -f ${docker_repo}/${image}'
cleanWs notFailBuild: true
}
}
}
}
非常重要!!!
-
構建優化:pipline中生成dockerfile的時候,我們是使用k8s方式部署不需要etcd,但是這種方式部署需要指定賬號(有去k8s的endpoints中get的許可權,使用預設default就好了,每次建立一個新的名稱空間k8s會自動幫我們建立好一個default),但是使用goctl 生成的 k8s yml沒有新增指定賬號選項,這個已經反饋了,可能後續版本會加上,這裡我們也用模版做了,同樣模版是在專案目錄下https://github.com/Mikaelemmmm/go-zero-looklook/tree/main/deploy/goctl,pipline中構建指定這個模版即可
-
${credentialsId}要替換為你的具體憑據值,即【新增憑據】模組中的一串字串,我們之前配置的是gitlab-cert所以這裡就填寫gitlab-cert,如果你不是這個自己要更換,${gitUrl}需要替換為你程式碼的git倉庫地址,其他的${xxx}形式的變數無需修改,保持原樣即可。
-
這裡跟官方文件有一點點不一樣,由於我專案資料夾目錄不同,goctl生成的dockerfile檔案我手動做了點調整,在一個我不是在構建時候生成的dockerfile,是在建立專案時候就把dockerfile一起放在目錄下,這樣構建映象時候不需要goctl了
5、配置k8s拉取私有倉庫映象
k8s在預設情況下,只能拉取harbor映象倉庫的公有映象,如果拉取私有倉庫映象,則是會報 ErrImagePull
和 ImagePullBackOff
的錯誤
1、先在jenkins釋出機器登陸harbor
$ docker login 192.168.1.180:8077
$ Username: admin
$ Password:
Login Succeeded
2、在k8s中生成登陸harbor配置檔案
#檢視上一步登陸harbor生成的憑證
$ cat /root/.docker/config.json
{
"auths": {
"192.168.1.180:8077": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
}
3、對祕鑰檔案進行base64加密
$ cat /root/.docker/config.json | base64 -w 0
ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
4、建立docker-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: docker-login
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
$ kubectl create -f docker-secret.yaml -n go-zero-looklook
secret "docker-login" created
6、構建
我們進入首頁,點選idenity進入詳情頁
然後可以看到,上面我們配置好的identity服務,如下圖 ,點選“Build with Parameters”, 然後選擇rpc,點選“開始構建”
第一次構建在拉程式碼時候都會失敗,應該是初始化啥東西,再點一次就好了。
部署成功
同樣道理,去構建identity-api,再去配置usercenter服務 構建usercenter-rpc、構建usercenter-api,接著配置其他服務、構建即可,本次我們先只構建identity-api、identity-rpc、usercenter-rpc、usercenter-api給大家演示。
6、新增閘道器
因為我們的api服務通過goctl釋出在k8s中都會暴露nodeport埠,索引我們看下k8s中go-zero-looklook名稱空間下的service的nodeport埠服務,然後將nodeport配置在nignx即可。
本次我們獨立一臺虛擬機器在k8s之外,安裝nginx,將k8s後端api服務通過nodeport方式把埠暴露給nginx,然後nginx在配置中配置此api服務,這樣nginx就充當閘道器使用。
nginx的安裝就不再這裡多說了,記得一定要有auth_request模組,沒有的話自己去安裝。
nginx的配置
server{
listen 8081;
access_log /var/log/nginx/looklook.com_access.log;
error_log /var/log/nginx//looklook.com_error.log;
location /auth {
internal;
proxy_set_header X-Original-URI $request_uri;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.1.182:31001/identity/v1/verify/token;
}
location ~ /usercenter/ {
auth_request /auth;
auth_request_set $user $upstream_http_x_user;
proxy_set_header x-user $user;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.182:31002;
}
location ~ /travel/ {
auth_request /auth;
auth_request_set $user $upstream_http_x_user;
proxy_set_header x-user $user;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.182:31003;
}
location ~ /order/ {
auth_request /auth;
auth_request_set $user $upstream_http_x_user;
proxy_set_header x-user $user;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.182:31004;
}
location ~ /payment/ {
auth_request /auth;
auth_request_set $user $upstream_http_x_user;
proxy_set_header x-user $user;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.182:31005;
}
}
如果是線上的話,應該配置多臺nignx保持高可用,在nignx前面還會有一個slb,你的域名包括https配置都應該解析到slb,在slb前面在有防火牆等這些。
8、結束語
至此,整個系列就結束了,整體架構圖應該如第一篇所展示,本系列希望能給你帶來幫助。
專案地址
https://github.com/zeromicro/go-zero
歡迎使用 go-zero
並 star 支援我們!
微信交流群
關注『微服務實踐』公眾號並點選 交流群 獲取社群群二維碼。