GitLab流水線配置
yuchendulang主導(dǎo)下的阿G信息辦是值得尊敬的

破壁越做越大已經(jīng)站穩(wěn)了腳跟,于是信息辦希望我們可以把代碼庫從阿里云云效遷移到學(xué)校的git,這篇文章記錄了一個gitlab倉庫中的CI/CD流水線(超好用的push代碼自動觸發(fā)更新部署)是怎么打造起來的,前前后后花了比較久的時間,所以里面會夾雜一些牢騷,不過字多的話,重點主干流程是會彩色加粗標(biāo)注的,不過因為b站沒辦法插入站外鏈接,所以這里的鏈接只能復(fù)制并且刪掉b站為剪切板默認(rèn)添加的尾巴才能訪問到qwq。下面進(jìn)入主題
O ping通目標(biāo)Gitlab網(wǎng)址

這個Gitlab基站是建在校園網(wǎng)服務(wù)器上的,由于現(xiàn)在技術(shù)力有限,所以這里只能搞一個校內(nèi)服務(wù)器嘗試(感謝chen的服務(wù)器和simba的賬號,雖然我是偷偷用的)。如果看官想做的是公網(wǎng)Gitlab的話,直接用云服務(wù)器就行,因為只涉及到內(nèi)網(wǎng)訪問問題,操作上毫無差別的,但是一定要有這一步,避免后面奇葩bug返工。
一 下載docker
本來我是用阿里云服務(wù)器的,所以記錄一下Alibaba Cloud?Linux這個奇葩的操作系統(tǒng)是怎么安裝docker的。先放一個官方操作文檔:https://help.aliyun.com/zh/ecs/use-cases/deploy-and-use-docker-on-alibaba-cloud-linux-2-instances。
它逆天的地方在于照著里面cv會報錯..... 好在在CSDN上找到了安好的文章:https://blog.csdn.net/m0_51041464/article/details/121048535
而正常的Linux系統(tǒng)安裝docker可以參考菜鳥教程:https://www.runoob.com/docker/centos-docker-install.html,賊簡單
二 下載jdk
jdk17官網(wǎng):https://www.oracle.com/java/technologies/downloads/#java17
安裝jdk17:https://blog.csdn.net/qq_53679247/article/details/130784450
若有報錯:/lib/ld-linux-aarch64.so.1:?No?such?file?or?directory,
可能是沒找對tar.gz,比如x64的找了arm64,找對就好了
三 下載maven
先耍個嘴皮子。maven是個神奇的東西,剛學(xué)springboot的時候了解到有maven這個東西,一直管他叫倉庫,但是這次下載maven報了各種錯誤,產(chǎn)生了?"運行springboot項目只需要java -jar my.jar就可以了,maven到底啥用" 等等問題,于是順帶去研究了一下maven和nexus,感覺還是挺有意思的。
話說回來,裝個maven為什么會去研究Nexus?原來是裝完docker又在docker內(nèi)安裝gitlab-runner之后,(經(jīng)歷了2天bug)我就直接開始跑流水線了。(經(jīng)歷了無數(shù)次無法啟動)后終于成功報錯了!——mvn沒找到。上網(wǎng)查mvn怎么裝——噢原來是這樣(一番操作,mvn -v,mvn clean都有效了,滿懷欣喜重新跑),又報錯了,然后才反應(yīng)過來docker是個全新的環(huán)境,在服務(wù)器上裝沒用啊,得在那個docker環(huán)境里裝(此時意識到docker原來是這樣一個東西,之前還特地搜了老多視頻了,腦子比較鈍都沒聽明白docker是個啥東西,集裝箱鯨魚共享什么的一團(tuán)亂麻),于是搜索“如何在docker里安裝maven”,搜到這篇很猛的知乎文章,提了個新鮮詞Nexus,還把maven是什么也講清楚了:https://zhuanlan.zhihu.com/p/568437960?utm_id=0。但是光看沒用啊,啃了快一個小時理論倒是曉得了,部署不來,干脆放棄了,再搜搜其他的有沒有簡單易懂的部署。然后看到有一篇博客里部署成功了,而且需要的前提是“宿主機(jī)部署jdk和maven”,來勁了,又搜了好一會兒,搜到了下面將要講的方式。

以下是本機(jī)以及docker內(nèi)部署maven的流程。
本機(jī)部署Maven:https://blog.csdn.net/HJW_233/article/details/131800582
Maven官網(wǎng):https://maven.apache.org/download.cgi
在創(chuàng)建docker環(huán)境時將本機(jī)文件掛載進(jìn)docker環(huán)境里再相應(yīng)地配置一下環(huán)境變量:https://blog.csdn.net/qq1445654576/article/details/104448915
二 下載gitlab-runner
因為最開始省事直接yum?install?gitlab-runner,卻發(fā)現(xiàn)找不到包....所以我的gitlab-runner是在docker環(huán)境內(nèi)下載的(參考官方文檔:https://docs.gitlab.com/runner/install/docker.html),不過也挺簡單的,執(zhí)行下面這句話就行了:未安裝則自動安裝,已安裝則顯示--help
sudo docker run ?\
?-d --name gitlab-runner --restart always\
?-p 9000:9000 \
?-v /srv/gitlab-runner/config:/etc/gitlab-runner \
?-v /usr/local/java/jdk-17.0.8:/usr/local/java/jdk-17.0.8 \
?-v /home/apache-maven-3.9.4:/home/apache-maven-3.9.4 \
?-v /home/project:/home/project \
?-v /home/repository:/home/repository \
?-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
以下是docker容器的相關(guān)操作
# 進(jìn)入這個容器
sudo docker exec -it gitlab-runner bash
# 重啟容器
sudo docker restart gitlab-runner
# 停止容器
sudo docker stop gitlab-runner
# 刪除容器-1
sudo docker kill gitlab-runner
# 刪除容器-2
sudo docker rm gitlab-runner
# 刪除鏡像
sudo docker rmi gitlab/gitlab-runner:latest
可以看見服務(wù)器里的命令行和進(jìn)入docker后的命令行頭顯示是不一樣的(因為我用的服務(wù)器不是root,有各種各種sudo和文件上傳刪除寫入的權(quán)限;進(jìn)入docker發(fā)現(xiàn)我是root了,我哭死)

上面給出的新建一個gitlab-runner容器的代碼中出現(xiàn)了好多冒號,當(dāng)時我也挺迷登的,這里也解釋一下。
-v 里冒號的意思是,左邊為本服務(wù)器的文件路徑,右邊為docker環(huán)境中的文件路徑。這里我偷懶直接服務(wù)器怎么配置,docker里相同地配置一次就行了。其實也很好理解的,這段代碼為鏡像(英文image)gitlab/gitlab-runner:latest,創(chuàng)建了一個新的容器(英文container)gitlab-runner,這個容器可以理解為一個嶄新的服務(wù)器,操作上和我們的本服務(wù)器一樣的操作,只是啥都要自己配(vim都要自己裝qwq(apt-get update、apt-get install?vim就好了))它的執(zhí)行結(jié)果就是進(jìn)入容器,ls /home,就能看到一個現(xiàn)成的apache-maven文件夾,當(dāng)然java等文件夾同理嘛,這樣就引入了我們在宿主服務(wù)器上下載的maven和java,然后進(jìn)入/etc/profile編輯一下,再source /etc/profile一下,就也在docker環(huán)境里裝好java和maven啦
-p 里冒號的意思是,左邊為服務(wù)器的端口,右邊是docker容器的端口。比如我想在這個docker里部署9000端口的springboot項目,那么右邊就需要填9000,然后我們畢竟是要從自己的服務(wù)器訪問嘛,所以左邊就是我們服務(wù)器的接口,如果是8000,那么就可以從"服務(wù)器ip:8000"訪問到接口了
三 注冊gitlab-runner
這個注冊也是個相當(dāng)炸裂的存在,只需要運行一段話就行了,注冊的結(jié)果會顯示在/etc/gitlab-runner/config/config.toml文件里。
但是這段話現(xiàn)在還說不出口,不想看牢騷的看官可以直接跳到這一點的結(jié)尾

我原以為是Warning的問題?,F(xiàn)在重新一想,似乎還是那么的有道理:failed,這種方式已經(jīng)被拋棄了,怎么辦?復(fù)制warning上百度查找。甚至翻出去bing國際版都沒碰到幾個說這種問題的,看了gitlab的整個issue稀里糊涂腦子里只有個:噢!runner15.6版本以后帶參注冊被拋棄了,死局。

驚喜地看到一篇文章里一摸一樣地報錯截圖,說是沒配置gitlab證書,需要去整個證書,半信半疑的偶然點開了官方文檔(就是上面提到的https://docs.gitlab.com/runner/install/docker.html),突然發(fā)現(xiàn)里面有提到安裝證書的事——這下好了,一邊罵自己不看文檔,瞎捷報亂查,一邊開始整。
于是這個還沒意識到i/o timeout的兄弟接著用阿里云服務(wù)器開始整https證書了,恰好chen有個項目需要部署前端,他的阿里云整了個域名,于是一發(fā)不可收拾

申請免費的阿里云SSL證書:https://blog.csdn.net/gla2018/article/details/127003666
域名是配置在chen的名下的,所以整個證書需要請chen幫忙做DNS解析。然后證書歡歡喜喜批下來了,卻發(fā)現(xiàn)自己阿里云服務(wù)器上的nginx不知道裝哪里去了,root find似乎只能掃描/root里的( ?)上網(wǎng)搜默認(rèn)安裝的/etc/nginx居然也沒有安裝到默認(rèn)位置,屬實跌股。
終于在/usr/nginx里找到了文件,然后修改conf發(fā)現(xiàn)并沒有起作用,上網(wǎng)重新各種搜nginx用法,倒騰一晚上終于決定重裝一個,這一裝就發(fā)現(xiàn)問題了——原來/usr/nginx里放的只是解壓了沒刪的tar.gz安裝包,真正configure過的文件放到了/usr/local/nginx里頭——改/usr/nginx里的文件有用才怪力。為了方便想root里解壓了直接配置到原文件夾力算了,省的之后找不到。于是整出了一堆鮮紅ERROR,無奈只能還是配置到/usr/local/nginx里頭,然后root里建一個空文件命名nginx_locates_in_usr_local,兜兜轉(zhuǎn)轉(zhuǎn)還是回來了
安裝完nginx,睡了
第二天早上起來發(fā)現(xiàn)Xshell連不上服務(wù)器了,上控制臺一看:CPU98%+,實例云盤讀寫每秒幾千次,怕不是被掃了,然后重啟。
為域名部署https參考:https://blog.csdn.net/weixin_44192066/article/details/117627342
注意要給開443端口;http中不支持同一個ip在多個server{}中每個代理不同的端口;https不支持location加路徑;https不支持號端口訪問;子域名配置https需要重新申請SSL證書
但是早上重啟后忘了把網(wǎng)頁的服務(wù)也重啟了,一上午瞎整各種404 500 502 403一頓查,終于到飯點了,才發(fā)現(xiàn)原來代理的目標(biāo)網(wǎng)頁都還沒跑起來,不想多說
吃完飯下午是七夕
回歸正題,證書整好了,https整好了,對著那個官方文檔一看,好家伙,我gitlab-runner放/srv文件夾下的,/etc下面沒有g(shù)itlab-runner,死局!
擺了。清理桌面前偶然一看,發(fā)現(xiàn)不對勁,這都和我這個錯的報的不是一個ERROR啊,搜了那么久的WARNING,咋沒想到WARNING是還可以跑,紅ERROR才是重點啊。他們有it doesn't contain any IP SANs,有connect: no route to host,就是沒有i/o timeout?一查似乎是網(wǎng)絡(luò)訪問的問題,ping了一下,果然是學(xué)校內(nèi)網(wǎng),本機(jī)x 阿里云服務(wù)器x 破壁服務(wù)器x?掛校園網(wǎng)VPN本機(jī)v,好了是時候甩鍋給yu老師了。
老師其實人挺不錯的,是秒回,說自己今天出來了,明天再來處理然后給我講講這個是怎么配的。不過大概也能領(lǐng)會到,畢竟已經(jīng)放暑假了他也沒有義務(wù)幫我處理這個爛攤子,于是乎,開始擺爛
(事后諸葛亮:可以參考docker新建gitlab-runner容器的代碼,那里將/srv下的/gitlab-runner掛到docker里的/etc下了,所以去docker環(huán)境里找是有的,只不過Xftp看不到的啦;此外原文檔里說的是Gitlab網(wǎng)頁用的是自簽發(fā)證書的話,那么需要把這個自簽發(fā)證書放在gitlab-runner里面以便容器能識別,可不是說自己的服務(wù)器的SSL證書放在里頭)
破局。兩天后的一個上午,突然想到chen之前分過一臺服務(wù)器,居然ping通了,干活!上面這些東西都是沒用的,下面這段代碼才是重點,而且只需要這段代碼就行了
sudo docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
?--non-interactive \
?--executor "shell" \
?--docker-image alpine:latest \
?--url "Gitlab主服務(wù)器的ip" \
?--registration-token "項目的專有token" \
?--description "springboot" \
?--tag-list "java" \
?--run-untagged="true" \
?--locked="false" \
?--access-level="not_protected"
比較重要的參數(shù)解釋如下:
--exector?填shell,不要被docker環(huán)境蒙蔽了填了"docker"(背后是一天的悲傷故事)
--taglist?表示該runner的標(biāo)簽,.gitlab-ci.yml文件中會有指定tag的字段,用于指定某個過程由帶有哪個標(biāo)簽的runner執(zhí)行
--docker-image?指定使用哪個鏡像,這里alpine是一個現(xiàn)成的基礎(chǔ)鏡像。上網(wǎng)搜索得知gitlab-runner將借助這個鏡像實現(xiàn)相關(guān)功能,不需要額外定義它,也不要因為沒見過改成別的名字

--url、--registration-token?取自?“項目-設(shè)置-CI/CD-runner”。如下圖

注冊后可以在上圖所示的位置查看有沒有顯示出來
注:這里給出的是specific-runner的構(gòu)建過程,還有g(shù)roup-runner和shared-runner另外兩種類型,有需要可以繼續(xù)研究
四?配置.gitlab-ci.yml文件
這個文件的位置可選的,默認(rèn)是根目錄,構(gòu)建上傳時識別到根目錄下有個.gitlab-ci.yml文件,也有可用的runner,就會調(diào)用runner里的docker鏡像執(zhí)行yml文件里的代碼。當(dāng)然還可以指定不同分支的變動觸發(fā)不同的shell代碼,具體的各字段表示什么意思以及“流水線是怎么流起來的”可以看這篇文章:https://blog.csdn.net/axibazZ/article/details/118387932,下面貼一份本項目的完整yml代碼,學(xué)東西還得是有源碼學(xué)的最快啊啊?。。ㄕ鹇暎?/p>
# 定義一些變量, 下面各階段會使用
variables:
? ?jar_name: work1-0.0.1-SNAPSHOT.jar
? ?java_path: /usr/local/java/jdk-17.0.8/bin
? ?upload_path: /home/dch/recognize/gitlab-runner/
# 定義執(zhí)行的各個階段及順序
stages:
? ?- build
? ?- upload
? ?- deploy
# 使用 maven 鏡像打包項目
maven-build:
? ?stage: build
? ?script:
? ? ?- mvn -B clean package -Dmaven.test.skip=true > /home/gitlab/build1.log 2>&1
? ?artifacts:
? ? ?paths:
? ? ?- target/$jar_name
? ?tags:
? ? ?- java
? ?only:
? ? ?- main
# 上傳生成的 jar 包到應(yīng)用服務(wù)器相應(yīng)目錄
upload-jar:
? ?stage: upload
? ?script:
? ? ?- scp target/$jar_name /home/gitlab
? ?tags:
? ? ?- java
? ?only:
? ? ?- main
# 啟動 SpringBoot jar包
deploy-test:
? ?stage: deploy
? ?script:
? ? ?- sh /home/gitlab/restart.sh
? ?tags:
? ? ?- java
? ?only:
? ? ?- main
第一段的variable定義用到的變量,可以看作是宏定義
第二段為流水線定義了3個任務(wù),分別是build -> upload -> deploy

第三段為build階段,only表示只有提交main分支時才被觸發(fā)。script內(nèi)要執(zhí)行的shell語句,其含義為清理原maven倉庫重新構(gòu)建,并打包項目為jar,存放路徑為倉庫內(nèi)代碼的根目錄/target/下面,使用tag為java的runner運行
第四段表示upload階段,將jar包移動到相應(yīng)的執(zhí)行目錄內(nèi),只有main分支提交時才觸發(fā)。
第五段為構(gòu)建方面,此處編寫的shell文件。腳本通過執(zhí)行腳本即可實現(xiàn)有責(zé)殺掉并重寫無則直接運行的邏輯,使用標(biāo)簽為JAVA的runner
其中,第四段upload階段其實還隱藏了一層git fetch的邏輯,從下圖中可以看到上傳前流水線自動將編譯好的文件拉取到docker鏡像中/home/gitlab-runner/builds/tEt2Wm3B/0/wallbreaker/background/back-end的奇葩路徑下,比較省心的是使用相對路徑就可以很簡單的將項目內(nèi)想要的文件復(fù)制到目標(biāo)目錄(注意target前面不能有斜杠)

五 將yml文件更新到main分支,自動觸發(fā)試試叭

如果運行流水線時報這樣not found的錯,多半是docker里面沒裝這個東西。比如這里是沒裝maven,已經(jīng)在前面通過掛載和配置系統(tǒng)變量解決了,自測一下docker內(nèi)mvn -v輸出沒問題就沒問題了,java -version同理的。(如果注冊時--docker-image參數(shù)用的不是alpine:latest而改成了普通的my:latest什么的話這里會報sh command not found的錯)

如果運行流水線時報AccessDenied,則需要手動賦予文件夾權(quán)限,具體可查看這篇GitLab CI/CD常見問題匯總的第一條:https://www.cnblogs.com/huiguo/p/15347085.html

最后
最難繃的還是內(nèi)網(wǎng)卡訪問...然后SSL證書一頓瞎整,然后用的校內(nèi)服務(wù)器賬號還沒有root權(quán)限,老是忘記sudo不說,連Xftp都用不了,想刪改只能vim vim vim vim vim vim vim vim vim...(已瘋)


總的來說,現(xiàn)在回頭看來搭這個東西還有點意思的,也不知道自己在做啥,花了一周時間



是這個hello world嗎?
cc之前說過一句 "現(xiàn)在應(yīng)該多做些之后不會做的東西,像搭網(wǎng)頁寫小游戲什么的你以后工作了有的是時間做這個都在做這個" ,這句話記得挺清楚的,也是一種警示吧


25號中午煩心,刷到言葉之庭的一個剪輯,只看幾秒畫風(fēng)突然啪的一下坐起來了,不斷進(jìn)步,人生理應(yīng)大有可為,前半生靠激情活著,現(xiàn)在就畫好舒適圈守著了?
然后26號一杯水一臺電腦一整天,配環(huán)境各種bug,那是一點脾氣都沒有
ps:一篇2500字的論文我一定是至少2天寫完的,看到右下角顯示字?jǐn)?shù),今天這篇已經(jīng)寫了6500多個字,有點意思
