一、GitLab版本管理
Git是一個開源的分布式版本控制系統,用於代碼的存儲和版本控制。
GitLab 是一個用於倉庫管理系統的開源項目。使用Git作為代碼管理工具,並在此基礎上搭建起來的web服務。
因為GitLab是為基於Linux的操作系統開發的,不能在Windows系統上運行,官方也沒有計划支持Windows,所以只能安裝到Linux系統。
如果windows機器,可以選擇使用Linux虛擬機或docker來安裝。
參考鏈接:https://docs.gitlab.com/ee/install/requirements.html
注意:本文僅用作演示,所以將在windows下安裝docker,再在docker中運行gitlab,來進行環境搭建。該方式可能會有gitlab數據備份失敗的問題。
1.docker安裝
Docker 並非是一個通用的容器工具,它依賴於已存在並運行的 Linux 內核環境。
因此,Docker 也必須部署在 Linux 內核的系統上。如果其他系統想部署 Docker 就必須安裝一個虛擬 Linux 環境。
win10系統的話可以很方便的安裝docker,也是我本次采用的方式。
Hyper-V 是微軟開發的虛擬機,類似於 VMWare 或 VirtualBox,僅適用於 Windows 10。這是 Docker Desktop for Windows 所使用的虛擬機。
參考鏈接:https://www.runoob.com/docker/windows-docker-install.html
1-1 查看電腦是否支持虛擬化
如果不支持的話,需要進BIOS修改,不同電腦biso選項不同,比如:
1-2 啟用Hyper-V
控制面板-》程序和功能-》啟動或關閉Window功能
1-3 下載安裝包並安裝
win10 系統可以直接下載官方提供的Docker Desktop Installer.exe進行安裝。
下載鏈接:https://hub.docker.com/editions/community/docker-ce-desktop-windows
其他windows環境可以參考鏈接:https://www.runoob.com/docker/windows-docker-install.html
1-4 安裝完畢后,桌面會有docker圖標,雙擊即可啟動docker
第一次打開docker會有一個示例,依照示例可以創建已經鏡像,並啟動一個容器,之后就可以在儀表盤可視化管理容器和鏡像。
如果感覺難以理解鏡像、容器、程序之間的關系,我可以根據個人理解提供一個比喻:
運行程序就像是打游戲,docker則是一間網吧。因為網吧的電腦配置資源有限,一次安裝不下多款游戲,所以老板自己做了幾個電腦系統,
其中一個系統只裝了游戲A(就叫系統A),一台機器只裝了游戲B(就叫系統B)...,這個過程就是創建鏡像。
客人來了想玩游戲A,老板就給他找了台電腦安裝了系統A,並運行里面的游戲A,這就是運行起來一個容器。
docker常用的命令有:
docker pull: 從鏡像倉庫中拉取或者更新指定鏡像。
實例:從Docker Hub下載java最新版鏡像。【 docker pull java 】
docker build: 創建本地鏡像。
實例:從Docker Hub下載java最新版鏡像。【 docker build -t runoob/ubuntu:v1 . 】
解析:-t runoob/ubuntu:v1,為構建的鏡像標記名稱,鏡像名為:runoob/ubuntu,tag為v1;.,單獨的點,意思為根據當前目錄下的Dockerfile文件生成鏡像。
docker run: 運行鏡像。
實例:從Docker Hub下載java最新版鏡像。【 docker run -p 8080:80 -v /home/data:/data -d runoob/ubuntu:v1 】
解析:使用鏡像runoob/ubuntu:v1,(-d)以后台模式啟動一個容器,(-p)將容器的80端口映射到主機的8080端口,(-v)將主機的目錄/home/data 映射到容器的目錄/data。
更多可以參考鏈接:https://www.runoob.com/docker/docker-command-manual.html
2. 在Docker中安裝gitlab
2.1 拉取gitlab的鏡像,gitlab-ce為穩定版本,后面不填寫版本則默認pull最新latest版本
執行命令: $ docker pull gitlab/gitlab-ce
2.2 運行gitlab, 注意22 對應的ssh;80對應的是http;443 對應的是https。
a. 通過命令運行
執行命令: $ docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
# -d:后台運行
# -p:將容器內部端口向外映射
# --name:命名容器名稱
# -v:將容器內數據文件夾或者日志、配置等文件夾掛載到宿主機指定目錄
b. 通過docker客戶端運行
先點擊要運行的gitlab鏡像右邊的【run】按鈕
添加容器配置和容器名稱,點擊【run】按鈕
到容器列表界面可以看到,容器已經運行起來了。
2.3 額外配置
按上面的方式,gitlab容器運行沒問題,但在gitlab上創建項目的時候,生成項目的http地址是按容器的hostname來生成的,也就是容器的id。
作為gitlab服務器,我們需要一個固定的URL訪問地址,因此我們要改一下gitlab.rb的配置。
通過docker窗口可以方便的看到配置文件的路徑
windows系統下對應資源管理器路徑:\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes
external_url 'http://10.100.17.37:80'
改完重啟gitlab即可。
注意external_url配置的端口是內部http的端口,我之前配的是【external_url 'http://10.100.17.37:32770'】,這樣會把內部端口由80改為了32770,這樣再把內部80端口映射到宿主機的32770時,就映射不到啦。
當時的解決方法是創建容器時,直接將內部端口由32770映射到外部的32770。即使用命令【docker run -d -p 32773:443 -p 32770:32770 -p 32771:22 --name gitlab --restart always gitlab/gitlab-ce】,
然后再修改external_url為http://10.100.17.37:32770就不會報錯。
2.4 創建gitlab賬號權限及組
經過不懈努力,我們已經可以訪問gitlab網站了。不過地址端口要注意使用80映射的那個端口(使用docker客戶端默認打開地址的是ssh映射的端口)
a. 管理員第一次登錄gitlab,需要重置管理員賬戶(root)密碼:
cmd輸入命令【 docker ps 】,查詢出gitlab容器的id。
cmd輸入命令【 docker exec -it 容器id /bin/bash 】,進入到容器內部。
繼續輸入命令【 gitlab-rails console 】
彈出 Loading production environment 后,在下面逐步輸入:
1、【user=User.where(id:1).first】 查出指定修改的用戶,1 為root
2、【user.password='hzq123456'】 需要設置的密碼
3、【user.password_confirmation='hzq123456'】 確認上面輸入的密碼
4、【user.save!】 保存
注意,圖中因為密碼太短所以改失敗了,換個長點的密碼即可。
有了賬戶密碼我們現在可以登錄進去啦!
b.有了管理員賬戶,我們還需要創建常規用戶。
這步也有兩種方式,一種是讓用戶在登錄界面注冊,然后通過root賬戶審批通過即可;
另一種方式是通過root賬戶創建:
注意,如果剛接觸gitlab,實在找不到對應頁面的入口,直接輸入圖中的地址哦。
管理員創建用戶必須填寫用戶郵箱地址,以便發送重置密碼的鏈接,用戶第一次登錄前必須重置密碼。所以還需要配置郵件服務器,這部分可以在網上搜索配置。
c. 創建組,及為組分配用戶
點擊保存后會自動跳轉到用戶分配頁面:
創建項目后,也可以在項目界面分配用戶或組:
OK! Gitlab准備完畢后,就可以繼續CI/CD自動化部署的流程了。
二、Gitlab CI/CD
持續集成 CI(Continuous Integration):在源代碼變更后,觸發自動檢測、構建和測試的過程。在代碼提交后,會自動進行構建和測試,並反饋結果。當結果符合預期時,再將代碼集成到主干。持續集成的目標是快速確保當前變更是可用的。
持續交付 CD(Continuous Delivery):是基於持續集成基礎上,將集成后的代碼自動化部署到各個環境測試,確定可以發布生產版本。
持續部署 CD(Continuous Deployment):是基於持續交付的基礎上,將在各個環境經過測試的應用自動化部署到生產環境。其實各個環境的發布過程都是一樣的。應用發布到生產環境后,我們需要對應用進行健康檢查、添加應用的監控項、 應用日志管理。
1. 安裝並運行gitlab-runner
參考鏈接:https://docs.gitlab.com/runner/install
GiTLab Runner是一個腳本運行器,類似於Jenkins,可以為我們執行一些CI持續集成、構建的腳本任務(即.gitlab-ci.yml),運行器具有執行腳本、調度、協調的工作能力。
在windows環境下,可以直接在服務器安裝runner,也可以安裝在docker中。
因為runner執行ci腳本時需要使用各種命令,如果本機已經安裝了執行腳本要用的各類軟件,比如maven、docker、nodejs等,最好直接在服務器上安裝gitlab-runner。這樣runner可以直接使用本機的環境來運行,這種情況下注冊時注意選擇【shell】作為執行器。
不過由於我這里用工作的電腦來演示,為了保持原系統的干凈,采用麻煩一些的方式,依然使用docker安裝,注冊時執行器也選擇【docker】,方便拉取不同的鏡像來執行腳本。
1-1 拉取 gitlab-runner 鏡像
cmd輸入命令:
【 docker pull gitlab/gitlab-runner:latest 】
1-2 啟動 gitlab-runner
cmd輸入命令:
【 docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest 】
注意:那個【-v /var/run/docker.sock:/var/run/docker.sock】 一定要加上。
因為docker daemon進程默認監聽的是/var/run/docker.sock這個文件,所以docker客戶端只要把請求命令發往這里,daemon就能收到並且做出響應。
這個命令將外部docker客戶端的/var/run/docker.sock映射給了內部docker客戶端,使內部docker客戶端也可以訪問外部的docker daemon服務。
否則后面注冊如果選擇了docker作為執行器時,因為是docker-in-docker模式,內部的docker將無法啟動。例如出現下面的錯誤:
啟動后如果看日志可能會發現提示缺少【/etc/gitlab-runner/config.toml】文件,這是因為還需要注冊。無需關閉容器,直接進行下一步操作即可。
2. 將gitlab項目或組注冊到gitlab-runner
2-1 先使用管理員賬戶,進入【項目】或【組】的頁面,然后打開Settings -> CI/CD。
注意紅框中的地址和token,注冊時要用到。
2-2 開始注冊
先說明一下,executer有多種選擇,常見如下:
shell-需要在安裝runner的機器上手動安裝需要的依賴,比如要編譯maven項目,需要安裝maven,編譯vuejs需要安裝node等;
docker-一個很好的選擇是使用Docker,因為它允許一個干凈的構建環境,以及簡單的依賴管理(所有用於構建項目的依賴都可以放在Docker映像中)。Docker執行器允許你輕松地創建一個帶有依賴服務的構建環境,比如MySQL;
Kubernetes-執行程序允許您為構建使用一個現有的Kubernetes集群。執行程序將調用Kubernetes集群API,並為每個GitLab CI作業創建一個新的Pod(帶有一個構建容器和服務容器)。
方式A: 逐步注冊,然后根據需要修改配置文件
首先在cmd輸入命令:【 docker exec -it gitlab-runner gitlab-runner register 】
執行器選【docker】的話,注冊共需要再進行6次輸入:
1-輸入gitlab的地址;(地址為上圖Gitlab的ci/cd配置頁面紅框選中內容,不能用localhost,可以用ip)
2-輸入token;(token為上圖Gitlab的ci/cd配置頁面紅框選中內容)
3-可以輸入空;
4-可以輸入空;
5-輸入docker;(表示使用docker鏡像來執行gitlab-ci.yml文件內部script命令,具體參加注意事項)
6-執行gitlab-ci.ym文件內script命令的默認鏡像,因為gitlab-ci.yml中可以為每一階段單獨指定執行命令的鏡像,這里理論上隨便輸入一個hub.docker.com上存在的鏡像即可,建議根據實際要用到的腳本來選擇。
因為我后面自動部署是要將程序做成鏡像發布,要使用docker的命令,所以這里最終也填了【docker】。
注意,因為注冊的環境里再次使用了docker鏡像,相當於docker-in-docker-in-docker的模式。
為了讓runner下載的docker鏡像也能連上docker daemon,需要修改runner的配置【/etc/gitlab-runner/config.toml】
當然如果你不需要把程序打包成docker鏡像來運行,可以不管這個配置。
步驟如下:
進入到容器內部,先使用【cat etc/gitlab-runner/config.toml】打開配置文件,將里面的配置復制到文本編輯器。
修改volumes 配置為【volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]】
再次使用【cat > etc/gitlab-runner/config.toml】命令開始重寫配置文件,將改好的配置粘貼進去,再按CTRL+ c 退出即可自動保存。
方式B: 使用組合命令,注冊時同時修改配置
docker exec gitlab-runner gitlab-runner register -n \
--url http://xx.xxx.xx.xx:32770/ \
--registration-token aGzYCxxxxxnrMxY7u_k \
--tag-list department-A \
--executor docker \
--docker-image "docker" \
--docker-volumes /root/.m2:/root/.m2 \
--docker-volumes /root/.npm:/root/.npm \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock \
--description "the runner of department-A" \
1. executor,使用docker。
2. 通過docker-image指定一個docker鏡像。這里使用的是docker:latest。
3. 通過docker-volumns掛載本地目錄:
掛載docker.sock是為了docker:latest鏡像操控runner服務器的docker服務;
掛載.m2文件夾,是為了避免maven每次編譯項目時都重新下載jar包。(后面.gitlab-ci.yml文件中使用了maven鏡像)
第一句的-n是什么作用我也不清楚,去掉貌似也沒影響。
另外有個鏡像拉取策略的配置【pull_policy】可以關注一下,可以選擇優先使用本地緩存的鏡像還是拉取最新的鏡像,官方有比較詳細的解釋。默認為always,在斷網或者想要加快ci執行的速度時貌似可以設置if-not-present。
參考鏈接:https://docs.gitlab.com/runner/executors/docker.html#using-multiple-pull-policies
以上步驟做完之后,咱們再回到gitlab頁面刷新看看效果,這時項目下面已經存在一個可用的runner了。
3.在項目根目錄下創建runner執行文件【.gitlab-ci.yml】
.gitlab-ci.yml位於git項目根目錄下,用於定義 CI/CD 流程分為幾個階段,每個階段需要執行哪些任務等。
3-1 創建項目
我這里直接使用以前寫的一個demo項目。在項目根目錄建一個.gitlab-ci.yml文件,然后因為我准備把程序做成鏡像在docker上運行,還在要發布的模塊根目錄下新建一個Dockerfile文件。
3-2 .gitlab-ci.yml 文件
before_script: - export DOCKER_IMAGE_TAG=$(date +%Y%m%d%H%M) stages: - compile - build #編譯配置 auto-compile: stage: compile tags: [ "department-A" ] image: name: maven only: # 打包分支 - develop script: - mvn clean install -Dmaven.test.skip=true -f ./Maven_Demo/demo/pom.xml artifacts: paths: - Maven_Demo/demo/demo-springboot/target/*.jar #構建配置 auto-build: stage: build tags: [ "department-A" ] # image: docker only: # 打包分支 - develop dependencies: - auto-compile script: - docker build -t hzq/demo-springboot:$DOCKER_IMAGE_TAG ./Maven_Demo/demo/demo-springboot - docker stop mydemo || true - docker rm mydemo || true - docker run --name mydemo -p 13005:13005 -d hzq/demo-springboot:$DOCKER_IMAGE_TAG
export 用來設置一個變量,我這里設置一個時間字符串,用作鏡像名稱的標簽。
stages 表示分成幾個job來執行,因為每一步需要用到的image不同。
auto-compile和auto-build 只是作為當前job的名稱,貌似可以順便寫。不過里面的stage要和stages里面寫的步驟一致。
tags 用來選擇該標簽對應的注冊runner的實例。
image 該步驟要用來執行script的鏡像。
only 用來指定哪些分支發生提交時,才需要執行當前job。
expect 與only相反
script 該步驟需要執行的shell腳本,里面具體的命令大家可以去網上查。
dependencies 要依賴哪個步驟完成再執行。
variables 定義變量。
allow_failure 指定當前job是否容錯,正常job失敗會跳過后續job流程
before_script 在當前job執行前執行的shell腳本
after_script 在當前job執行后執行的shell腳本
when 依賴的上一個job執行什么狀態后執行當前job, on_success on_failure always manual 默認on_success
3-3 Dockerfile文件
Dockerfile是給.gitlab-ci.yml里面的docker build命令構建程序鏡像用的。
里面主要包含指定程序運行的環境,導入執行文件,設置執行命令等操作。
### 基礎鏡像 FROM openjdk:11 #聲明一個掛載點,容器內此路徑會對應宿主機的某個文件夾 VOLUME /tmp #聲明工作目錄 WORKDIR /home #應用構建成功后的jar文件被復制到鏡像的工作目錄內,名字也改成了app.jar COPY target/*.jar /home/app.jar #添加運行權限 RUN chmod +x app.jar #設置時區,容器時間與主機時間保持一致 RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone #暴露端口 EXPOSE 13005 #啟動容器時的進程 ENTRYPOINT java -jar /home/app.jar --spring.profiles.active=dev
3-4 提交代碼,驗證結果
這時候提交代碼就可以在gitlab中看到執行.gitlab-ci.yml的過程,注意分支要和only屬性配置的一致。
我們再打開docker,可以看到程序鏡像已經創建好,並自動運行起來了。
每次修改代碼並重新提交后,將會自動創建新的鏡像和容器並運行。這樣簡單的CI/CD就搭建完畢啦。
其他關於Kubernetes,Rancher,Jenkins工具的使用,等有空再一起探索吧。
--------------------------------------------------------------------------------------------------------------------
以下是參考的鏈接:
GITLab:
https://www.cnblogs.com/zxtceq/p/11082525.html
https://blog.csdn.net/weixin_30549657/article/details/100093425
https://blog.csdn.net/MonoBehaviour/article/details/84852984
http://www.360doc.com/content/17/0215/11/17572791_629136631.shtml
CI/CD:
(gitlab-runner,shell注冊,netcore)https://www.cnblogs.com/yuyoho/p/13273794.html
(gitlab-runner,docker注冊,sh腳本,node)https://blog.csdn.net/qq_36737839/article/details/113694367
(gitlab-runner,docker注冊,maven,docker push)https://blog.csdn.net/qq_34596292/article/details/111349745
(gitlab-runner,docker注冊,vue,maven,CI示例)https://blog.csdn.net/qq_34596292/article/details/111349745
(docker.sock詳解)https://blog.csdn.net/boling_cavalry/article/details/92846483
--------------------------------------------------------------------------------------------------------------------