摘自百度:持續(xù)集成是一種軟件開(kāi)發(fā)實(shí)踐,即團(tuán)隊(duì)開(kāi)發(fā)成員經(jīng)常集成他們的工作,通過(guò)每個(gè)成員每天至少集成一次,也就意味著每天可能會(huì)發(fā)生多次集成。每次集成都通過(guò)自動(dòng)化的構(gòu)建(包括編譯,發(fā)布,自動(dòng)化測(cè)試)來(lái)驗(yàn)證,從而盡早地發(fā)現(xiàn)集成錯(cuò)誤。
gitlab是一個(gè)基于 git 的倉(cāng)庫(kù)管理程序,也是一個(gè)方便軟件開(kāi)發(fā)的強(qiáng)大完整應(yīng)用。

Docker, 是一個(gè)開(kāi)源的應(yīng)用容器引擎, 可以輕松的部署各個(gè)應(yīng)用。
GitLab,是一個(gè)利用 Ruby on Rails 開(kāi)發(fā)的開(kāi)源應(yīng)用程序,實(shí)現(xiàn)一個(gè)自托管的Git項(xiàng)目倉(cāng)庫(kù),可通過(guò)Web界面進(jìn)行訪問(wèn)公開(kāi)的或者私人項(xiàng)目安裝,十分方便。
Jenkins, 是一個(gè)開(kāi)源的持續(xù)集成的服務(wù)器,Jenkins開(kāi)源幫助我們自動(dòng)構(gòu)建各類項(xiàng)目。Jenkins強(qiáng)大的插件式,使得Jenkins可以集成很多軟件,可能幫助我們持續(xù)集成我們的工程項(xiàng)目(可以結(jié)合git,svn等構(gòu)建項(xiàng)目,在服務(wù)器上打包)。
Docker簡(jiǎn)介及其安裝,可以參考本人另一篇博客-> Docker入門及centOS7下安裝
gitlab官方推薦的內(nèi)存為2g以上,而且cpu占有高,博主的服務(wù)器總共只有2g內(nèi)存(還是1核的QAQ),需通過(guò)增加4G的swap空間來(lái)提升性能。
配置高土豪可忽略這步
因?yàn)間itlab太占資源,本人云服務(wù)為1核2g,gitlab推薦配置為2g以上
第一次啟動(dòng)鏡像時(shí)cpu和內(nèi)存使用占太高,導(dǎo)致服務(wù)器崩潰,,
這里通過(guò)swap把硬盤內(nèi)存分配給內(nèi)存(雖然讀寫慢但總比崩潰好)
#查看系統(tǒng)存儲(chǔ)空間
df -h
#查看swap使用情況 單位m
free -m
#在根目錄創(chuàng)建充當(dāng)臨時(shí)內(nèi)存空間的swap文件 大小為4g 命名為swapfile
cd #
#sudo fallocate -l 4G /swapfile #這種方案在我這邊報(bào)fallocate failed: Operation not supported文件系統(tǒng)不支持,可能因?yàn)楣P者是云服務(wù)器 因此采用其他方式創(chuàng)建
#創(chuàng)建空間4g 4096個(gè)1m 可自行調(diào)整
dd if=/dev/zero of=/swapfile bs=4096 count=1M
#設(shè)置文件權(quán)限
chmod 600 /swapfile
#將/swapfile指定為交換文件
mkswap /swapfile
#啟用
swapon /swapfile
#永久生效,這步如果不設(shè)置重啟服務(wù)器就沒(méi)了 可能會(huì)導(dǎo)致宕機(jī)
vi /etc/fstab #在這個(gè)文件最后一行添加 /swapfile swap swap sw 0 0
#創(chuàng)建完可以 ls -lh /swapfile 檢查文件大小
ls -lh /swapfile
#查看使用情況
swapon -s
#停用
swapoff /swapfile
#搜索docker鏡像
docker search gitlab
#拉取dockerhub上第一個(gè)
docker pull gitlab/gitlab-ce
#運(yùn)行鏡像 配置低啟動(dòng)后剛開(kāi)始502 三五分鐘后才能正常進(jìn)入頁(yè)面。。。(hostname這邊填寫自己的ip或者域名)
docker run -d \
--hostname 111.230.47.36 \
--publish 543:443 --publish 81:80 --publish 222:22 \
--name gitlab \
--restart always \
--volume /srv/gitlab/config:/etc/gitlab \
--volume /srv/gitlab/logs:/var/log/gitlab \
--volume /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce
#其中 --name=gitlab 指定容器名稱 -d 后臺(tái)運(yùn)行容器并返回容器id -p:指定映射端口號(hào),本文是將ssh的22端口映射為222端口,web訪問(wèn)的80端口映射為81端口 --volume為掛載容器的數(shù)據(jù)文件到本地(用來(lái)指定掛載目錄,將config配置目錄、data數(shù)據(jù)目錄、logs日志目錄掛載到宿主機(jī)上、數(shù)據(jù)持久化防止容器停止后數(shù)據(jù)丟失)
#查看容器啟用情況 health代表健康啟動(dòng) starting代表還在啟動(dòng)中 如果出現(xiàn)unhealthly 可docker logs xxx查看日志
首次進(jìn)入需設(shè)置root用戶密碼

配置gitlab服務(wù)器訪問(wèn)信息
上述方式啟動(dòng)容器沒(méi)有問(wèn)題并能夠成功訪問(wèn),但在gitlab上創(chuàng)建項(xiàng)目時(shí),生成項(xiàng)目url的訪問(wèn)地址是按容器的hostname生成,即容器id,這邊配置一個(gè)固定的url訪問(wèn)地址
/etc/gitlab/:配置文件所在的目錄
/var/log/gitlab:日志所在目錄
/var/opt/gitlab:數(shù)據(jù)所在目錄
# 詳細(xì)參考 https://blog.csdn.net/michael_base/article/details/77966647
# 配置http協(xié)議所使用的訪問(wèn)地址 這邊可以進(jìn)入容器修改 docker exec -it gitlab /bin/bash
# 但因?yàn)閱?dòng)容器的時(shí)候已將容器內(nèi)的配置文件/etc/gitlab掛在到本地/srv/gitlab/config 直接在本地做配置
# 修改gitlab.rb 默認(rèn)全為注釋
# 調(diào)整unicorn進(jìn)程數(shù),減少內(nèi)存占用 默認(rèn)為1調(diào)為2
unicorn['worker_processes'] = 2
unicorn['worker_timeout'] = 120
# 調(diào)整時(shí)區(qū)為上海
gitlab_rails['time_zone'] = 'Asia/Shanghai'
#配置http協(xié)議時(shí)使用訪問(wèn)地址 (內(nèi)網(wǎng)ip)
external_url 'http://111.230.47.36:81'
# 配置ssh協(xié)議所使用的訪問(wèn)地址和端口
gitlab_rails['gitlab_ssh_host'] = '111.230.47.36'
gitlab_rails['gitlab_shell_ssh_port'] = 222
#默認(rèn)情況下 nginx監(jiān)聽(tīng)端口為external_url中定義的,或者默認(rèn)的80/443 docker run時(shí)暴露容器80端口
#修改nginx的監(jiān)聽(tīng)端口
# nginx['listen_port'] = nil #默認(rèn)
nginx['listen_port'] = 80
#最后重啟容器讓配置生效docker restart gitlab或者在容器內(nèi)執(zhí)行 gitlab-ctl reconfigure 讓配置生效 此過(guò)程還需幾分鐘

#這邊本人刪掉容器出現(xiàn)個(gè)問(wèn)題 網(wǎng)絡(luò)被占用 /usr/bin/docker-current: Error response from daemon: service endpoint with name gitlab already exists.
#解決方案
#強(qiáng)制刪除
docker rm -f xxx
#清理網(wǎng)絡(luò)占有
docker network disconnect --force bridge gitlab
#查看是否有同名容器占用
docker network inspect gitlab
取消注冊(cè)功能
由于gitlab一般用于小團(tuán)隊(duì),本人又是用于公網(wǎng)和團(tuán)隊(duì)共同使用,取消注冊(cè)步驟如下
登陸root用戶 -> settings -> Sign-in Restrictions -> Sign-up enbaled是否開(kāi)啟注冊(cè)功能取消


默認(rèn)root用戶為管理者,可以添加編輯刪除用戶等權(quán)限操作。
兩種方式提交到gitlab
1.先在gitlab創(chuàng)建一個(gè)空項(xiàng)目(可以Add README.md文件做測(cè)試),然后本地拉取后再做提交
1.創(chuàng)建用戶linjw 并新建一個(gè)項(xiàng)目,public:都能看 private:私有 自己和小組成員可看
2.用idea拉取到本地(如網(wǎng)絡(luò)需代理的話需給git設(shè)置代理,可以用http或者ssh免密)
#查看當(dāng)前git代理
git config --get --global http.proxy
#設(shè)置全局代理
git config --global http.proxy 代理ip:port
#查看當(dāng)前信息
git config --list
#全局修改當(dāng)前郵箱密碼 idea查看git歷史記錄的用戶名采用這邊的配置
git config --global user.name 用戶名 (當(dāng)前項(xiàng)目: git config -- user.name 用戶名 )
git config --global user.email 郵箱
3.拉取后修改README.md文件然后提交,會(huì)提示輸入密碼,輸入一次后即可提交,在gitlab項(xiàng)目可以看到提交記錄


2.本地發(fā)布完整項(xiàng)目到gitlab(客戶端和gitlab需建立ssh通信)
#mac下創(chuàng)建ssh密鑰(已有的話忽略) 想同時(shí)存在github和gitlab配置第二個(gè)密鑰 參考 https://www.w3ctech.com/topic/2040 https://blog.csdn.net/zengshunyao/article/details/50212987
#查詢命令
cat ~/.ssh/id_rsa.pub
#創(chuàng)建密鑰
ssh-keygen -t rsa -C "xxx@xxx.com" #賬號(hào)郵件地址
#驗(yàn)證github 出現(xiàn)用戶名success說(shuō)明成功
ssh -T git@github.com
#驗(yàn)證gitlab 后面跟自己gitlab服務(wù)器地址 如果出現(xiàn)Could not read from remote repository.說(shuō)明ssh互信沒(méi)成功
ssh -T git@gitlab #gitlab為別名 默認(rèn)為HostName
#或者git clone ssh的方式判斷是否能夠拉取下來(lái)
git clone ssh://git@111.230.47.36:222/linjw/ssh.git


1.在idea新建一個(gè)項(xiàng)目(這邊我新建springboot項(xiàng)目,都一樣撒),建立本地git倉(cāng)庫(kù)
2.vcs->import into version control->create git repository,open要提交的文件后,變色git化,這時(shí)項(xiàng)目右鍵可以使用Git,選擇add把準(zhǔn)備要提交的文件加到索引庫(kù)。
3.右鍵git commit directory -> commit and push(取消perform code analysis檢查代碼選項(xiàng)可以變快) 第一次提交需指定遠(yuǎn)程倉(cāng)庫(kù)地址
pull/commit 可能出現(xiàn)的問(wèn)題問(wèn)題及解決方案:
Push failed: Failed with error: fatal: Could not read from remote repository (提交時(shí)沒(méi)有認(rèn)到git倉(cāng)庫(kù))
#查看當(dāng)前使用倉(cāng)庫(kù)地址
git remote -v
#刪除舊的
git remote remove origin
#添加新的(后面地址填自己的)
git remote add origin http://111.230.47.36:81/linjw/gitlab.git #也可以選擇ssh
you are not allowed to push code to protected branches on this project(分支被保護(hù))
#詳細(xì)參考 https://stackoverflow.com/questions/32246503/how-to-fix-you-are-not-allowed-to-push-code-to-protected-branches-on-this-proje
Push rejected: Push master to origin/master was rejected by remote(拒絕提交到master分支)
一:通過(guò)master提交
#默認(rèn)master分支為protected狀態(tài),除了master權(quán)限的人員不可push、delete等操作
1.進(jìn)入gitlab要提交的項(xiàng)目主頁(yè) Settings?Repository?Protected Branches
2.第一次提交到master,將狀態(tài)改為unprotected或者允許提交和合并里選擇developer+Masters,然后再做提交。
#仍然報(bào)這個(gè)錯(cuò),原因可能是建立倉(cāng)庫(kù)的時(shí)候,生成了個(gè)readme文件,導(dǎo)致不同步,所以無(wú)法push,也無(wú)法pull 解決方案
#1.先從master分支pull下來(lái) 然后再push
git pull origin master --allow-unrelated-histories
#2.在Terminal終端中填寫提交命令
git push -u origin master
#強(qiáng)制推送
git push -u origin master -f
#這邊不知道為什么剛開(kāi)始設(shè)置為unprotected才可以提交,提交過(guò)后再protected又可以。。
二:通過(guò)develop提交
設(shè)置保護(hù)分支的時(shí)候 一般模式為:
1.master分支(原始分支) 允許推送和合并 只有master分支可以
2.創(chuàng)建develop分支 設(shè)置developer+Masters(開(kāi)發(fā)人員+主持人(master(default))) 允許推送和合并
#gitlab頁(yè)面 項(xiàng)目?Repository?Branches新建develop分支 新建切換為develop分支且developer+Masters
3.idea vcs?update project顯示剛剛創(chuàng)建的分支 并checkout,在develop上提交會(huì)變得容易很多




Docker安裝jenkins
jenkins是一個(gè)用Java編寫的開(kāi)源的持續(xù)集成工具,可以于GitLab等代碼管理工具聯(lián)動(dòng),觸發(fā)一定條件之后,實(shí)現(xiàn)自動(dòng)進(jìn)行測(cè)試、編譯、部署等一系列動(dòng)作。
#jenkins的特性
1.易于安裝-只要把jenkins.war部署到servlet容器,不需要數(shù)據(jù)庫(kù)支持。
2.易于配置-所有配置都是通過(guò)其提供的web界面實(shí)現(xiàn)。
3.集成RSS/E-mail通過(guò)RSS發(fā)布構(gòu)建結(jié)果或當(dāng)構(gòu)建完成時(shí)通過(guò)e-mail通知。
4.生成JUnit/TestNG測(cè)試報(bào)告。
5.分布式構(gòu)建支持Jenkins能夠讓多臺(tái)計(jì)算機(jī)一起構(gòu)建/測(cè)試。
6.文件識(shí)別:Jenkins能夠跟蹤哪次構(gòu)建生成哪些jar,哪次構(gòu)建使用哪個(gè)版本的jar等。
7.插件支持:支持?jǐn)U展插件,您可以開(kāi)發(fā)適合自己團(tuán)隊(duì)使用的工具。
#拉取官方j(luò)enkisn鏡像 這個(gè)鏡像里自帶jdk
sudo docker pull jenkins
#初次安裝jenkins 文件夾歸屬必須是1000 參考 https://blog.csdn.net/mmd0308/article/details/77206563?locationNum=6&fps=1 不然會(huì)報(bào)權(quán)限錯(cuò)誤
cd /home
mkdir jenkins_home
#更改文件夾歸屬者
sudo chown -R 1000:1000 jenkins_home
#查看
ls -nd jenkins_home
#啟動(dòng)鏡像 -d后臺(tái)運(yùn)行 --privileged=true 添加一些權(quán)限 -p端口映射 -v掛載/var/jenkins_home到本地
docker run -d \
--name jenkins \
--privileged=true \
-p 9090:8080 \
-p 50000:50000 \
-v /home/jenkins_home:/var/jenkins_home jenkins
#在掛載的目錄查看初始密碼
cat /home/jenkins_home/secrets/initialAdminPassword
#進(jìn)入 ip:9090頁(yè)面 輸入初始密碼 并安裝需要的插件 安裝的插件會(huì)存在掛載目錄中

jenkins結(jié)合gitlab持續(xù)集成
jenins默認(rèn)用戶可以做所有事,為了安全應(yīng)當(dāng)設(shè)置安全矩陣或者登陸用戶可以做任何事
系統(tǒng)管理 -> Configure Global Security ->授權(quán)策略-> 登陸用戶可以做任何事
1.確保已安裝有GitLab 插件 如果沒(méi)有安裝在 系統(tǒng)管理 -> 插件管理里安裝
2.系統(tǒng)管理 -> 配置


構(gòu)建步驟
創(chuàng)建一個(gè)新任務(wù) -> 構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目 -> 源碼管理選擇git -> 添加ssh或token認(rèn)證 -> 在jenkins容器內(nèi)創(chuàng)建ssh,添加到gitlab里項(xiàng)目創(chuàng)建人的ssh中
Credentials -> Add Credentials 添加證書存放私鑰
進(jìn)入項(xiàng)目點(diǎn)擊立即構(gòu)建
這邊要注意,因?yàn)閖enkins是Docker安裝 所以gitlab與jenkins關(guān)聯(lián) 要用到容器的
# jenkins容器內(nèi)生成ssh密鑰
# 進(jìn)入jenkins容器 創(chuàng)建密鑰
docker exec -it jenkins /bin/bash
# 進(jìn)入容器后建立.ssh目錄,創(chuàng)建密鑰文件私鑰id_rsa,公鑰id_rsa.pub
mkdir ~/.ssh && cd ~/.ssh
ssh-keygen -t rsa
# 一直回車即可獲取
#查看jenkins容器內(nèi)的公鑰
cat ~/.ssh/id_rsa.pub
#之后將ssh公鑰加在gitlab 在容器內(nèi)git clone測(cè)試是否能拉取下來(lái) 如果可以說(shuō)明ssh互信成功
jenkins配置證書
#從宿主機(jī)進(jìn)入容器
docker exec -it jenkins /bin/bash
#查看jenkins容器內(nèi)私鑰
cat ~/.ssh/id_rsa
#在jenkins里配置私鑰到證書里





修改要構(gòu)建項(xiàng)目的配置,將其構(gòu)建為jar包
參考 https://blog.csdn.net/u011904605/article/details/54604851
1.需確保安裝有g(shù)radle plugin插件
2.jenkins項(xiàng)目 -> 配置 -> 構(gòu)建 -> 增加構(gòu)建步驟 -> Involk gradle script -> 更多 -> use gradle wrapper
3.之后按下面操作
如果構(gòu)建的時(shí)候出現(xiàn)問(wèn)題 點(diǎn)擊構(gòu)建任務(wù)查看控制臺(tái)輸出


成功構(gòu)建為jar包

自定義命名jar包構(gòu)建
build.gradle添加以下配置
#archivesBaseName為自定義jar包名 不寫的話默認(rèn)為項(xiàng)目名
archivesBaseName = "gitlab-jenkins_${releaseTime()}"
#jar包版本
version = '1.0-FINAL'
#獲取當(dāng)前時(shí)間
def releaseTime() {
//return new Date().format("yyyy-MM-dd-hh-mm-ss", TimeZone.getTimeZone("UTC")) //UTC為國(guó)際時(shí)間
return new Date().format("yyyy-MM-dd-HH-mm-ss")
}
提交到gitlab 構(gòu)建項(xiàng)目效果

代碼一提交到gitlab就觸發(fā)jenkins構(gòu)建項(xiàng)目(我認(rèn)為大型項(xiàng)目不推薦。。因?yàn)闃?gòu)建很花時(shí)間,除非很少有提交事件,比如很少改動(dòng)的master分支)
這邊主要利用到gitlab的webhook功能
webhock:webhook是個(gè)在特定情況下觸發(fā)的一種api. 越來(lái)越多在web上的操作被描述為事件
gitlab中解釋為: web 鉤子用于在項(xiàng)目發(fā)生相關(guān)事件時(shí)通知外部服務(wù)器。(在這邊的項(xiàng)目事件為項(xiàng)目的更改,外部服務(wù)器為jenkins)
實(shí)現(xiàn)步驟
1.jenkins安裝Gitlab Hook Plugin還有Build Authorization Token Root Plugin插件,兩個(gè)插件安裝完成后,項(xiàng)目配置 -> 構(gòu)建觸發(fā)器(將多出Build when a change is pushed to GitLab. GitLab webhook URL: xxx選項(xiàng),勾選并復(fù)制這個(gè)url),
2.登陸gitlab進(jìn)入要配置的項(xiàng)目,添加webhock 項(xiàng)目主頁(yè) -> Settings -> Integrations -> 添加上面的url并創(chuàng)建webhock,創(chuàng)建成功后test查看是否成功(在jenkins查看是否在構(gòu)建,test好像默認(rèn)是測(cè)試master分支的?)


這邊我在gitlab測(cè)試的時(shí)候出現(xiàn)403,view detail報(bào)了Error 403 anonymous is missing the Job/Build permission的錯(cuò)
解決方案:
jenkins -> 系統(tǒng)管理 -> Configure Global Security -> 取消防止跨站點(diǎn)請(qǐng)求偽造的勾選
jenkins - 系統(tǒng)管理 -> 系統(tǒng)設(shè)置 -> 取消 Enable authentication for '/project' end-point的勾選
之后在idea上提交了代碼把develop,jenkins也正常的進(jìn)行構(gòu)建develop分支上的項(xiàng)目。
總結(jié)
1.有錢真好QAQ,剛開(kāi)始博主因?yàn)榕渲玫宛埩它c(diǎn)彎路,在這提供了一種解決方案,老實(shí)說(shuō)1核2g的配置運(yùn)行g(shù)itlab挺卡的,
2.由于博主也是一邊學(xué)習(xí)一邊寫筆記,記錄著一些踩過(guò)的坑,寫得不好的地方見(jiàn)諒
3.微服務(wù),docker是這幾年十分火熱的技術(shù),也算是個(gè)趨勢(shì),還是得多學(xué)學(xué)~