1.使用場景
CICD,顧名思義就是持續內建(Continuous Integration)和持續部署(Continuous Deployment)簡稱,指在開發過程中自動執行一系列腳本來減低開發引入 bug 的機率,在新代碼從開發到部署的過程中,盡量減少人工的介入。
以前的老技術,比如git/svn+jenkins這種,jenkins的配置多數還是依賴于負責維護CI的人,很多人不熟悉jenkins怎麼配置,每一個步驟應該怎麼編譯和測試,一般都由CI的人來定義。
而CICD,其實可以使用jenkinsfile,就象gitlab的 .gitlab-ci.yaml檔案,把CICD的流程控制和步驟也作為開發的一部分,由開發去維護。并且可以很快的部署到多個環境。
持續內建
持續內建指在和向遠端倉庫 push 代碼後,在這次送出合并入主分支前進行一系列測試,建構等流程。假設現在有個應用的代碼存儲在 gitlab 上,每天開發者都 push 很多次送出,針對每次 push,你可以建立一系列腳本進行自動測試,降低往應用裡引入錯誤的機率。這就是持續內建,它可應用在包括開發分支在内的多個分支上。
持續部署
持續部署在持續內建的基礎上更進一步,指将推送指倉庫預設分支的部署至産品環境。如果這部分需要手動觸發,這就是一個持續傳遞(Continuous Delivery)環節。
-
安裝環境
Gitlab 内置了 CICD 工具,不需要使用第三方工具。使用gitlab的CICD流程,使用物聯管理平台項目為例子。搭建一個pipe。一旦送出代碼,自動将物聯管理平台部署到docker(k8s叢集)中。
使用到的技術有: docker,gitlab-runner,linux shell,(k8s,helm)
環境:
IP 安裝軟體
172.26.67.109 docker、gitlab
172.26.67.108 docker、gitlab-runner
2.1 安裝docker和docker-compose
在兩台伺服器上安裝docker,百度或參考以前寫的《Centos7下安裝Docker.docx》、《通過 docker-compose 快速建構部署.docx》
2.2 安裝gitlab
在172.26.67.109上使用docker安裝gitlab
在172.26.67.109上編寫一個docker-compose.yml檔案
version: '3'
services:
gitlab:
image: twang2218/gitlab-ce-zh
restart: always
container_name: "gitlab"
privileged: true
hostname: "172.26.67.109"
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://172.26.67.109'
gitlab_rails["time_zone"] = "Asia/Shanghai"
gitlab_rails["gitlab_shell_ssh_port"] = 1222
nginx["listen_port"] = 80
ports:
- "80:80"
- "8443:443"
- "1222:22"
volumes:
- ./gitlab/config:/etc/gitlab
- ./gitlab/data:/var/opt/gitlab
- ./gitlab/logs:/var/log/gitlab
- "/etc/localtime:/etc/localtime:ro"
然後docker-compose up -d運作𧘖安裝gitlab,𧘖安裝後浏覽器打開
http://172.26.67.109建立組、使用者、項目等
2.3 安裝gitlab-runner
在172.26.67.108上使用docker安裝gitlab-runner
在172.26.67.108上編寫一個docker-compose.yml檔案
gitlab-runner:
container_name: gitlab-runner
restart: always
privileged: true
image: gitlab/gitlab-runner
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "./gitlab-runner/config:/etc/gitlab-runner"
- "/etc/localtime:/etc/localtime:ro"
然後docker-compose up -d運作𧘖安裝gitlab-runner,然後注冊gitlab-runner到gitlab上
1、從gitlab上擷取注冊令牌
2、注冊gitlab-runner
docker exec -it gitlab-runner gitlab-ci-multi-runner register -n \
--url
http://172.26.67.109/\
--registration-token XXXXXXXXXXXS5UDqw \
--tag-list=dev,uat,prod \
--description "project_build_runner" \
--docker-privileged=false \
--docker-pull-policy="if-not-present" \
--docker-image "livingobjects/jre8" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock \
--docker-volumes /opt/data/gitlab-runner/.m2:/root/.m2 \
--executor docker
在gitab上可以看到己注冊的gitlab-runner
-
持續內建、部署
使用 Gitlab 的 CICD ,隻需要在 Gitlab 的倉庫的根目錄中添加 .gitlab-ci.yml 檔案。
這個檔案中,可以定義CICD 的各個環節,配置每個環節執行的指令,觸發方式等。這個配置檔案其實就是按照 YAML 規定了一些結構的 shell 腳本,裡面的指令會在符合條件時逐一執行。一旦在倉庫中添加這個檔案,Gitlab 會檢測到它并用名為 Gitlab Runner 工具執行它。每次觸發的 CICD 會把配置中的腳劃分為不同的 job,多個 job 組成一個 pipeline。
最簡單的 .gitlab-ci.yml 檔案可以包含:
before_script:
-
apt-get install rubygems ruby-dev -y
run-test:
script:
- ruby --version
其中 before_scripts 屬性會在執行任一腳本前預裝一些需要的依賴(類似 unittest 的 setUp 方法),此後名為 run-test 的腳本會顯示目前系統的 ruby 版本。這兩個步驟組成了一個 pipeline 會在這個倉庫的每次push後執行。這行任務的執行情況也可以在 Gitlab 的對應頁面上檢視,就像在 Terminal 中看日志一樣。
而每個 pipeline 的 job 的執行情況也可以在頁面上檢視
如果中途報錯了,可以一鍵復原
CICD 工作流
假設你在本地修改了一些代碼以增加一些特性,當你把這些改動 push 到遠端倉庫的特性分支後,項目裡設定的 CICD pipeline 就被觸發了,一般流程如下:
運作自動腳本(串行或并行):
建構并測試應用
在合并前 review 改動
上述流程如果沒有問題就可以把改動合并入主分支,CD 會自動把它部署到産品中,如果發現了任何問題,還能一鍵復原。
工作流程圖如下:
該圖簡要顯示了基本的工作流,想要了解 Gitlab CICD 的更多特請,請參閱CICD 索引表
.gitlab-ci.yml 檔案結構
.gitlab-ci.yml 是指定了 CICD 相關配置的 YAML 檔案。(YAML 是專門用來寫配置檔案的語言,簡潔強大,和 python 一樣用縮進代表層級,表達能力和 JSON 基本一緻,但格式更友善。
一般而言,CICD 過程會包含如下最外層的 key:
stages: 定義整個 CICD pipeline 的 job 數量和名稱
variables: 定義 CICD 流程中的一些環境變量
before_scripts: 在每個 job 的 scripts 執行前進行的指令集,一般是建立目錄,列印 context 目錄等操作,可類比 unittest 的 setUp 方法
stage: 定義了一個 job 的具體流程,可以在前面加上名稱
下面通過一個例子進行一些講解
stages:
- test
- build
-
deploy
variables:
GIT_STRATEGY: none
PROJECT_REPO_NAMESPACE: test
PROJECT_REPO_NAME: cicd_learn
DEPLOYMENT_REPO_NAMESPACE: test
DEPLOYMENT_REPO_NAME: deploy_test
- export ROOT_PATH=$(pwd)
- echo 'root path:' $ROOT_PATH
- mkdir $PROJECT_REPO_NAME
- cd $PROJECT_REPO_NAME
-
echo 'date:' $DATE
test_stage:
stage: test
script:
- <test related command here>
artifacts:
paths:
- xxxx.html
when: always
allow_failure: false
build_stage:
stage: build
- <build related command here>
when: manual
allow_failure: false
only:
- master
deploy:
stage: deploy
- <deploy related command here>
- master
stages
例子中 stages 值為一個數組(p.s. 用 - 代表數組和 markdown 類似)。包含了三個 job,test, build, deploy分别實作自動測試,打包項目和部署。下方的 stage 必須在全局定義的 stages 内。
variables
值為鍵值對象,為了後續的流程,此處定義了開發項目和部署項目的 namespace 和 repo_name。同 shell 類似,後續使用其值需要加上 $ 符号。定義的變量也有對應的作用域,定義在頂層就可以作為全局變量供所有 job 使用,如果是一些 job 特有的變量,就定義在 job 内部。
before_script
值為數組,每一個元素其實就是一個 linux 指令,寫的時候裝作自己在寫 shell 就好。該部分主要生成了後續建構需要的鏡像标簽,切換目前目錄等。為了 debug 友善,這些變量最好列印。類似的,如果在 job 完成後有一些時候操作,可以定義 after_script。需要注意的是如果定義在頂層,内部的指令會在每個 job 運作之前執行,如果某些 job 需要特别的預操作,可以在 job 内部再配置一個 before_script 對象,它會複寫外部的全局預操作。
test_stage
名為 test 的 job 的具體配置,一般是個複合對象。
stage
job 對應的 stage,如果有多個 job 對應同一個 stage,在執行時會并行執行這些 job。
script
這個 job 執行的指令,此處是進入的項目倉庫目錄,并且執行了一個 shell 腳本,這個腳本定義了執行項目的所有單元測試。一般建議如果要執行的指令過多,就把這些指令寫成腳本放在項目内。CICD 流程直接執行這個腳本。
artifacts
這個對象用來定義 job 的産出,比如我們讓 test_stage 産出一個 html 格式的報告,顯示每個單元測試的執行情況(報告生成相關代碼寫在項目内)。 數組内 paths 和 when 分别定義報告的路徑和産出場景。此處表示報告放置于根目錄下,任何時候都要提供報告。設定正确後,就可以 Gitlab 的 pipline 頁面上可以下載下傳相關檔案。
allow_failure
見名知意,如果值為 true,那麼即使沒通過測試,也可以執行後續的 job.
build_stage
該步驟在測試通過的基礎上,把項目編譯打包,友善後續部署。
when
此處的 when 定義在 job 内的頂層,值為 manual 表示其需要在 Gitlab 上手動觸發(頁面上點選按鈕即可)。
only
only 指明了 job 的執行場景,可以是分支名,表明隻有 master 分支可以執行 build,如果要用排除法反向指定,可以用 except。
deploy_stage
所有的 key 現在你應該都了解了,這裡不再贅述。這一步驟主要是将部署産品的伺服器上的内容更新。