一、Intro
jenkins和runner,作為主流自動化運維工具來說,兩者的大思路其實是一樣的,就是將我們提交到代碼倉庫的代碼拉到jenkins或者runner運行的機器里,然后執行一系列的命令(這里通常是指打包和發布的命令,當然你想執行什么樣的命令都是可以自己定義的)
二、Runner安裝注冊
准備工作 在gitlab創建個人項目,注意查看如下信息,在注冊runner的時候會用到(必須是項目的管理員才能看到)

gitlab-runner提供windows和linux版本的安裝客戶端,我這邊使用docker的方式安裝舉例
docker pull gitlab/gitlab-runner
為了演示流水線的效果,這邊會將整個過程分成2個階段編譯和發布(中間可以根據自己的需要添加其他階段,比如鏡像打包上傳到鏡像倉庫等)
注冊對應的runner之前應該想清楚這個runner需要實現的目標是什么
-
編譯runner安裝注冊目標: 拉取對應項目的源碼,編譯項目,將編譯后生成的文件保存到gitlab緩存中(這里可以想一下我們一般的在用CI自動化發布的時候是不是將編譯階段也放在
Dockerfile里面,導致每次編譯生成沒有必要的鏡像,其實這一步是不需要放在Dockerfile里面的,因為生成的鏡像對我們是沒有作用的)。分析: 確定拉目標之后,就可以根據目標注冊對應的runner了,想一下我們上面的步驟需要編譯
netcore項目,那么在這個runner里面必須有netcore sdk的環境。實施:
# 創建配置文件目錄 sudo mkdir -p runner/runnertest/builder # 運行runner sudo docker run -d --name runnertest-builder --restart always \ > -v /home/yasewang/runner/runnertest/builder:/etc/gitlab-runner \ > -v /var/run/docker.sock:/var/run/docker.sock \ > gitlab/gitlab-runner:latest # 注冊runner sudo docker exec -it runnertest-builder gitlab-runner register # 配置runner Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://git.greedyint.com/ Please enter the gitlab-ci token for this runner: _jooQZxyy6zCrs8HevDd Please enter the gitlab-ci description for this runner: [653f2eda5bfa]: runnertest-builder Please enter the gitlab-ci tags for this runner (comma separated): 109-runnertest-builder Registering runner... succeeded runner=9x8kWsU1 Please enter the executor: docker-ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, shell, ssh, virtualbox: docker Please enter the default Docker image (e.g. ruby:2.1): microsoft/dotnet:latest #注意這里使用dotnet鏡像,查看鏡像https://hub.docker.com/映射
/var/run/docker.sock這個文件是為了讓容器可以通過/var/run/docker.sock與Docker守護進程通信,管理其他Docker容器
-v /srv/gitlab-runner/config:/etc/gitlab-runner是將runner的配置文件映射到宿主機/srv/gitlab-runner/config方便調整和查看配置
按照上面的順序操作下來,如果順利的話就會在gitlab項目的ci里面看到這個runner已經上線

-
發布runner安裝注冊目標: 將上一步生成的待發布文件打包成鏡像,並運行容器。
分析: 確定拉目標之后,就可以根據目標注冊對應的runner了,想一下我們上面的步驟需要生成
docker鏡像並運行容器,那么在這個runner里面必須能使用docker命令。實施: 采用參數賦值的方式直接注冊
# 創建配置文件目錄 sudo mkdir -p runner/runnertest/deploy # 運行runner sudo docker run -d --name runnertest-deploy --restart always \ > -v /home/yasewang/runner/runnertest/deploy:/etc/gitlab-runner \ > -v /var/run/docker.sock:/var/run/docker.sock \ > gitlab/gitlab-runner:latest # 注冊runner sudo docker exec -it runnertest-deploy gitlab-runner register # 配置runner Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://git.greedyint.com/ Please enter the gitlab-ci token for this runner: _jooQZxyy6zCrs8HevDd Please enter the gitlab-ci description for this runner: [653f2eda5bfa]: runnertest-deploy Please enter the gitlab-ci tags for this runner (comma separated): 109-runnertest-deploy Registering runner... succeeded runner=9x8kWsU1 Please enter the executor: docker-ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, shell, ssh, virtualbox: docker Please enter the default Docker image (e.g. ruby:2.1): docker:stable # 一定要指定,才能正常使用docker命令
三、CICD項目實戰
-
新建webapi項目:
dotnet new webapi -n runnertest --no-https -
添加鏡像檢測刪除腳本(后續ci構建腳本會用到):
# check-dev.sh if [ $(docker ps -a --format {{.Names}} | grep runnertest-dev) ] then docker rm -f runnertest-dev docker rmi runnertest-dev fi # check-master.sh if [ $(docker ps -a --format {{.Names}} | grep runnertest-master) ] then docker rm -f runnertest-master docker rmi runnertest-master fi -
添加
Dockerfile文件FROM mcr.microsoft.com/dotnet/core/aspnet WORKDIR /app COPY out/ /app ENTRYPOINT [ "dotnet", "/app/runnertest.dll" ]
gitlab-ci.yml常用參數
- stages:
pipeline的階段列表。定義整個pipeline的階段 - stage:定義某個
job的所在階段。參考#1 - script:(唯一一個必須寫的參數)
job執行過程中的命令列表 - only/except:觸發類型/限制
job的創建條件。參考可用的選項 - tags:指定
runner的tag,只有擁有指定tag的runner才會接收到這個任務 - cache:緩存。可選部分目錄或未被 git 追蹤的文件進行緩存,參考
- environment:指定部署相關任務的環境,並非真實環境,是對要部署到某環境的任務的歸類。方便在
gitlab上聚合以便進行回滾和重新部署操作,參考 - artifacts:保留文檔。在每次 job 之前
runner會清除未被 git 跟蹤的文件。為了讓編譯或其他操作后的產物可以留存到后續使用,添加該參數並設置保留的目錄,保留時間等。被保留的文件將被上傳到gitlab以備后續使用。參考 - dependencies:任務依賴。指定
job的前置job。添加該參數后,可以獲取到前置job的artifacts。注意如果前置 job 執行失敗,導致沒能生成artifacts,則 job 也會直接失敗。
yml階段構建腳本(.gitlab-ci.yml)
stages:
- build
- deploy-dev
- deploy-master
# 構建
build-job:
stage: build
only:
- develop
- master
cache:
untracked: true
script:
- dotnet restore
- dotnet publish -o ./out -c Release
artifacts:
# 可以緩存在gitlab的流水線記錄中,供直接下載
expire_in: 30 days
paths:
- out/
tags:
- 109-runnertest-builder
# 發布測試
deploy-dev-job:
stage: deploy-dev
only:
- develop
dependencies:
- build-job # 這里一定要依賴build-job,不然dockerfile里面的out目錄無法使用
script:
- ls out/
- sh ./check-dev.sh
- docker build -t runnertest-dev .
# 這里可以添加將生成好的image上傳到dockerhub或者docker本地倉庫
### 如果生成的鏡像需要統一上傳到倉庫管理,則后面的邏輯可以分離到另外一個runner去執行
# 這里可以添加從dockerhub或本地倉庫拉取指定鏡像
- docker run -d --name runnertest-dev -p 10001:80 runnertest-dev
tags:
- 109-runnertest-deploy
# 發布正式
deploy-master-job:
stage: deploy-master
only:
- master
dependencies:
- build-job # 這里一定要依賴build-job,不然dockerfile里面的out目錄無法使用
script:
- ls out/
- sh ./check-master.sh
- docker build -t runnertest-master .
# 這里可以添加將生成好的image上傳到dockerhub或者docker本地倉庫
### 如果生成的鏡像需要統一上傳到倉庫管理,則后面的邏輯可以分離到另外一個runner去執行
# 這里可以添加從dockerhub或本地倉庫拉取指定鏡像
- docker run -d --name runnertest-master -p 10000:80 runnertest-master
when: manual
tags:
- 109-runnertest-deploy
其他
做完上面的工作之后,將代碼提交到gitlab的develop或者master分支就會自動觸發構建任務了(第一次運行會比較慢,因為要拉取netcore和docker鏡像,所以在沒開始學習這個教程之前可以將幾個鏡像都准備好)。
各個階段效果圖如下:
- 構建


- 發布

服務器運行之后docker容器狀態:

網頁訪問api效果圖:

整個過程走下來會發現其實耗時的操作都是拉取鏡像,這個情況只有第一次的時候才會出現,后續構建就不會有這個問題了。
