一、gitlab 實現的 auto devops
1. DevOps中的一些概念與原則
(1) 什麼是持續集成
持續集成(Continuous integration,簡稱CI)指的是,頻繁地(一天多次)將代碼集成到主幹。
它的好處主要有兩個。
- 快速發現錯誤。每完成一點更新,就集成到主幹,可以快速發現錯誤,定位錯誤也比較容易。
- 防止分支大幅偏離主幹。如果不是經常集成,主幹又在不斷更新,會導致以後集成的難度變大,甚至難以集成。
持續集成的目的,就是讓產品可以快速迭代,同時還能保持高質量。它的核心措施是,代碼集成到主幹之前,必須通過自動化測試。只要有一個測試用例失敗,就不能集成。
(2) 持續交付、持續部署的概念
持續交付(Continuous delivery)指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。如果評審通過,代碼就進入生產階段。
持續部署(continuous deployment)是持續交付的下一步,指的是代碼通過評審以後,自動部署到生產環境。
(3) 持續集成系統的組成
- 一個自動構建過程,包括自動編譯、分發、部署和測試等。
- 一個代碼存儲庫,即需要版本控制軟件來保障代碼的可維護性,同時作爲構建過程的素材庫。
- 一個持續集成服務器。
(4) 爲什麼要引入auto devops
部署的環境問題 ;
Dev, QA, Ops的進度問題 ;
持續集成的好處 :
編譯問題與Bug可以在push或合併之後第一時間發現並解決;
Devops使持續交付成爲可能,使產品隨時可交。過去公司做測試可能需要十幾、二十幾個組件,集成一次往往要一兩個小時,費力費時,而且複雜容易出錯,而一旦配置出錯的話耗時會更久。因此,一次集成測試一週纔會做一次,測出Bug要到下一週才能更新,再做測試,這個週期會非常漫長。而持續集成的意義就在於減少風險,和重複的過程,最終提高工作效率。
關於devops的其他一些介紹 http://www.gzhphb.com/article/20/201544.html
2. GitLab CI中的一些概念
(1) Pipeline
- 一次 Pipeline 其實相當於一次構建任務,裏面可以包含多個流程,比如自動構建、自動進行單元測試、自動進行代碼檢查等流程 ;
- 任何提交或者 Merge Request 的合併都可以觸發 Pipeline ;
(2) stages
- stages 表示構建階段,就是上面提到的流程 ;
- 可以在一次 Pipeline 中定義多個 stage ;
- stages有如下特點 :
- 所有 stages 會按照順序運行,即當一個 stage 完成後,下一個 stage 纔會開始
- 只有當所有 stages 成功完成後,該構建任務 (Pipeline) 纔算成功
- 如果任何一個 stage 失敗,那麼後面的 stages 不會執行,該構建任務 (Pipeline) 失敗
(3) jobs
- job表示構建工作,表示某個stage裏面執行的工作 ;
- 一個stage裏面可以定義多個job ;
- jobs有如下特點 :
- 相同 stage 中的jobs 會並行執行
- 相同 stage 中的 jobs 都執行成功時,該 stage 纔會成功
- 如果任何一個job 失敗,那麼該 stage 失敗,即該構建任務 (Pipeline) 失敗
(4) gitlab runner
- 執行構建任務的一個服務 ;
- 把構建任務放到runner裏面而不是在CI裏面做是不想把”構建”這個重任(通常較大的工程構建都比較小號資源) 放到gitlab上而影響gitlab性能。通過把gitlab runner安裝到不同機器上,讓這臺單獨的機器來執行構建任務
- 關於 gitlab server 與 gitlab runner 之間的關係以及信息交互可以通過下面這個鏈接看到 : https://xiaozhuanlan.com/topic/3529176084
二、使用 Gitlab 實現一個簡單的流水線 (Pipeline)
1. 準備工作
(1) 從docker hub下載gitlab/gitlab-runner鏡像
root# docker pull gitlab/gitlab-runner
(2) 準備一個用來完成stage的鏡像
多個步驟使用同一個鏡像來創建容器,也可以根據不同stage準備多個特定的鏡像。
這裏只是介紹一個使用docker
來完成多個簡單stage
的demo
,就拿一個最簡單的能完成任務的鏡像,一個簡單的Dockerfile如下:
FROM docker.io/ubuntu
MAINTAINER user.name user.email
# install tools
USER root
RUN apt-get update
RUN apt-get install -y git cmake g++ gcovr
ENTERPOINT /bin/bash
這篇文章介紹的流水線有兩個步驟,第一個步驟完成構建,第二個步驟完成單元測試以及單元測試覆蓋率的計算。其實兩個stage完全可以放到一個容器中來進行。
爲模擬真實的流水線,每個環節做特定的工作。這裏假設兩個stage完全不同,需要使用不同的容器來完成。
下面是我們根據需要創建的兩個不同鏡像 :
具體docker的基本操作請自行Google,也可以參考《每天五分鐘玩轉Docker容器技術》這本書。
(3) 安裝docker-compose
root# sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
如果上面的源下不了,使用下面的方式 :
yum install -y epel-release
yum install -y python-pip
pip install --upgrade pip
pip install docker-compose
(4) 編寫docker-compose.yml
一個簡單的docker-compose.yml文件:
runner:
image: gitlab/gitlab-runner
restart: always
container_name: gitlab-runner
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /srv/gitlab-runner/config:/etc/gitlab-runner
解釋一下:
- /var/run/docker.sock:Docker 守護進程 (Docker daemon) 默認監聽的 Unix 域套接字(Unix domain socket),容器中的進程可以通過它與 Docker 守護進程進行通信。
- /srv/gitlab-runner/config:
runner
的配置文件,可以通過修改這個目錄下的config.toml文件來修改runner
配置。host主機中的/srv/gitlab-runner/config/config.toml這個文件被映射到runner中的/etc/gitlab-runner/config.toml文件中,主機上的/srv/gitlab-runner/config/config.toml的修改,會導致runner內部的/etc/gitlab-runner/config.toml做同步修改。 - 下面通過docker-compose啓動的容器就是流水線的
runner
,流水線在這個runner
裏面觸發並開始執行,之後runner
會接着創建另外的docker容器,來完成流水線中的構建和單元測試任務。-v
表示掛載,runner
通過與主機通信,看似在runner
中創建容器,其實是在host主機中創建的. 這個也比較好驗證,因爲runner中並沒有並沒有安裝docker,如何啓動容器;另外流水線完成後在host主機中通過docker ps -a
可以看到中間生成的臨時容器。
1. 使用docker-compose啓動容器
root# docker-compose up -d
2. 上面使用docker-compose的方式啓動容器,完全可以換成使用docker run來啓動容器
docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
gitlab/gitlab-runner
(5) 在工程中開啓 auto devops 選項
項目設置 –> CI/CD –> General pipelines settings –> Enable Auto DevOps
使用一個具體的 runner
如果這個項目打開了shared runner
,裏面可能有多個 runner,我們不想用別人的 runner,只想用自己剛註冊的 runner,可以把 shared runner 選項關閉,或者也可以在.gitlab-ci.yml裏面的 stage
裏面,使用 tags
關鍵字指定特定的 runner 。關閉共享 runner 如下圖:
(6) 編寫 .gitlab-ci.yml 文件
.gitlab-ci.yml 這個文件以
yaml
的格式描述了整個流水線有哪些流程,應該做哪些事。具體語法就不說了,可以Google下。編寫完成以後,這個文件需要放到倉庫的根目錄,受Git版本控制。yaml
格式在編寫時容易出錯,可以在 “Gitlab 側邊欄 CI/CD –> Pipelines”頁面,右上角有個 “CI Lint” 按鈕,進去後輸入編寫的 .gitlab-ci.yml 文件內容,點擊左下角 “Validate” 按鈕。
下面是工程中需要用到的 .gitlab-ci.yml:
2. 註冊runner
root# docker exec -it gitlab-runner gitlab-runner register
3. runner的配置文件
配置文件路徑: /srv/gitlab-runner/config/config.toml
concurrent = 1
check_interval = 0
[[runners]]
name = "docker_runner"
url = "https://gitlab.com/"
token = "xxxxxxxxxxxxxxxxxxxxxx"
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
pull_policy = "never"
[runners.cache]
Insecure = false
正常情況下,註冊完畢後是沒有 pull_policy = "never"
這一行的,可以先手動加上。這放到下面的”docker鏡像的拉取策略“來說。
4. 一次Pipeline的體驗
提交代碼
流水線在執行的時候
流水線運行完畢
流水線總體概況
5. 其他一些需要注意的地方
(1) 如何節省因爲特定容器配置的時間
在.gitlab-ci.yml裏面,一個stage可能需要一個特定的容器來做任務,這樣的話,默認會首先從 docker hub 裏面 pull,並且如果使用剛 pull 下來的鏡像生成容器,還需要更新源以安裝配置所需環境,這時候可以考慮使用Dockerfile來配置特定的鏡像來做特定任務,在一個 stage 中使用本地鏡像來創建容器(容器可以在秒級啓動,這個時間跟整個構建流程來說是可以接受的)。使用本地鏡像,需要在
/srv/gitlab-runner/config/config.toml
裏面添加pull-policy策略,策略有多個可選,可以設置爲優先使用本地鏡像,如果本地不存在鏡像,再從docker hub裏面pull,pull-policy的使用語法是pull _policy = "if_not_present"
,if_not_present
這個關鍵字好像不能用了,可以直接換成never
,不使用遠程鏡像。
(2) docker 鏡像的拉取策略有三種
- never 任何情況下都不從 docker hub 拉取鏡像
- always 任何情況下都不使用本地鏡像
- if-not-present 優先使用本地鏡像,如果本地不存在該鏡像,會從 docker hub 拉取
拉取策略可以轉到官網文檔:https://docs.gitlab.com/runner/executors/docker.html