Gitlab CI&CD 實戰經驗分享

引言

現在大部分的公司都搭建了自己的Gitlab,除了Git的代碼管理能力,Gitlab的CI&CD在項目的持續集成和部署上也儘力提高大家的工作效率。下面用我們項目的例子為大家引薦一下這套工具帶來的便利。

Gitlab CI&CD是什麼

如上官方圖示,可以理解為Gitlab給開發者提供了一項功能,在代碼提交後自動觸發一段開發者自定義的腳本,以此來完成諸如但不限於構建部署的工作。

為什麼我們需要使用

1. 項目業務較多,多個業務並行聯調或測試(不要問我分支怎麼管理的,後面說);

2. 不斷有新人進入;

3. 測試機器時常有被更換的風險;

4. 項目依賴包時常會更新,每個人環境的依賴包小版本可能不一致。

因此我們迫切的需要一個新人低成本或零成本的、快速自動化的構建部署方案。

解決方案

1. 為環境指定不同的分支,如dev1 代表聯調環境1,test2 代表測試環境

2. testN 代表測試環境N。如下圖,各分支與環境的關係

3. 利用Gitlab CI&CD工具執行自動化構建,並根據分支部署到不同機器,如上圖,發布到個環境前都經過了CI階段的自動化構建等操作,線下測試和聯調還可以在CD階段自動部署到對應伺服器

執行步驟

1. 在倉庫裡面配置.gitlab-ci.yml

2. 在可以訪問git倉庫的伺服器部署Runner

3. 在git倉庫網頁上配置對應的Runner

項目配置

配置文件 .gitlab-ci.yml

在項目的根目錄下創建文件.gitlab-ci.yml

查看其他可配置屬性

# 執行job的階段 按順序串列執行
stages:
- build
- cleanup
- deploy

# 自定義階段build的job流程
build: # 自定義名字
stage: build # 指定這階段操作的名稱
only: # 指定那些分支會進入該處理流程
- master # 正式環境
- pre # 預發環境
- testN # 測試環境 test1 test2 ... testN
- devN # 聯調環境 dev1 dev2 ... devN
variables:
VERSION: 1.0.10 # 除了後面會說到的私密變數 還可以在這裡定義變數
before_script:
# 一些特殊情況需要SSH key的場景,該部分見下文
# - ...
# 定義變數 如NODE環境變數
- NODE_ENV=`if [[ ${CI_COMMIT_REF_NAME:0:3} = "dev" || ${CI_COMMIT_REF_NAME:0:4} = "test" ]]; then echo "development"; else echo "production"; fi`;
script:
# 為node modules做緩存, 有緩存用緩存,沒有則你npm install並添加緩存
- PACKAGE_HASH=$(md5sum package.json | awk {print $1});
- mkdir -p ~/builds/cache/node_modules # 使用docker模式時需要配置volume 保證緩存起作用 在後面runner部分會提到。
- NPM_CACHE=~/builds/cache/node_modules/${PACKAGE_HASH}.tar
- if [ -f $NPM_CACHE ];
then
echo "Use Cache";
tar xf $NPM_CACHE;
else
npm install;
tar cf - ./node_modules > $NPM_CACHE;
fi
# npm build
- echo "NODE_ENV=$NODE_ENV node build/build.js"
- NODE_ENV=$NODE_ENV node build/build.js
# upload to CDN
# - ...
# docker build
- echo `docker build -t "$CI_PIPELINE_ID" . | awk -F "Successfully built " {print $2}`
# docker push
- if [ $NODE_ENV = "development" ]; # 如果需要部署的server的runner在同一個機器則可不必push到倉庫
then
docker login dev.hub.xxx.com -u$USERNAME -p$PASSWORD;
docker tag $CI_PIPELINE_ID dev.hub.xxx.com/namespace/webapp:$CI_COMMIT_REF_NAME;
docker push dev.hub.xxx.com/namespace/webapp:$CI_COMMIT_REF_NAME;
docker rmi dev.hub.xxx.com/namespace/webapp:$CI_COMMIT_REF_NAME;
echo "--------------------------------------------------------------------------";
echo "dev.hub.xxx.com/namespace/webapp:$CI_COMMIT_REF_NAME";
else
# 參考上面then中腳本
"--------------------------------------------------------------------------";
echo "hub.prd.xxx.com/namespace/webapp:$DATE.$CI_BUILD_ID";
fi

# 開發和測試機部署
clean_testN:
stage: cleanup
only:
- testN
tags:
- dc2fe-deploy-testN
script:
- docker stop webapp
- docker rm webapp
allow_failure: true

deploy_testN:
stage: deploy
only:
- testN
tags:
- dc2fe-deploy-testN
script:
# - ssh root@IP "docker stop webapp; docker rm webapp; docker run --name webapp -d -p 8000:8000 dev.hub.xxx.com/namespace/webapp-testN:latest"
# 或者
- docker pull dev.hub.xxx.com/namespace/webapp:testN
- docker run --name webapp -d -p 8000:8000 dev.hub.xxx.com/namespace/webapp:testN

# clean_dev: # dev或其他環境部署配置與上面test環境配置類似
# deploy_dev:

如果

– 你的CI Runner的執行環境沒有許可權訪問你們公司的Gitlab倉庫(一般使用docker模式的Runner或者項目底下有子模塊submodule,且需要在Runner中構建的時候checkout)

– 當前項目構建完後需要部署到其他伺服器,或者需要執行sshrsync等需要認證命令時

你需要

– 給你的git倉庫賬戶下添加Runner宿主的SSH Key公鑰。注宿主機中創建如何生成我的SSH密鑰

– 【推薦】使用ssh-agent來管理你的SSH Key私鑰(同上,如公鑰id_rsa.pub;對應私鑰id_rsa), $SSH_PRIVATE_KEY是在 https://git.xx公司.com/當前倉庫/settings/ci_cd下添加Secret variables

在本文中你可以認為ssh-agent是一個用來在ssh會話過程中管理你的ssh私鑰,並在git倉庫或伺服器需要ssh key認證的時候自動提供與對應公鑰匹配認證的工具

before-script:
- eval $(ssh-agent -s)
# 清除一些系統中複製出現的換行符
,並重定向到/dev/null防止泄露
- echo "$SSH_PRIVATE_KEY" | tr -d
| ssh-add - > /dev/null
# 創建~/.ssh目錄,並配置許可權(非root運行的runner)
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh

除了自己配置的變數,Runner也提供了一些 預置變數

shell模式的Runner需要添加

- ssh-keyscan Runner宿主機需要訪問的伺服器hostname(git。xxx.com或IP) >> ~/.ssh/known_hosts

docker模式的Runner可直接關閉ssh登錄目標host key檢查

- echo -e "Host *
StrictHostKeyChecking no

" > ~/.ssh/config

CI Runner

安裝

Runner的安裝比較簡單,根據官方流程即可, 以Linux x86-64為例

# 下載gitlab-runner並安裝
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

# 2. 授執行權
sudo chmod +x /usr/local/bin/gitlab-runner

# 創建GitLab CI用戶:
sudo useradd --comment GitLab Runner --create-home gitlab-runner --shell /bin/bash

# 安裝並啟動:
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start

配置

註冊項目

1. 配置項目ci的倉庫地址 如下圖灰色mask部分2

2. 配置項目唯一標識Token 如下圖灰色mask部分3

3. 給當前Runner一個描述,或者命名

4. 配置當前Runner的Tag, 可以多個,tag可以用來管理和關聯項目和Runner,以實現部署到不同伺服器等

5. Runner的其他屬性配置, 也可以在界面配置如下圖

6. 配置當前Runner的模式

成功

如圖,配置成功後當你提交代碼到對應配置了CI&CD stage的分支,Gitlab就會自動觸發執行腳本,當然如圖所示,你也可以直接在界面上重試或新建pipelines

一次提交觸發一次CI&CD即執行一次腳本對應一個pipeline;一個pipeline對應stages下的所有job;一個stage對應一個job;一個job可以允許失敗,比如我們的例子中,每次清除就得docker容器的時候可能失敗,因為新機器上沒有對應的容器或者其他一些不影響主流程的操作可以添加容錯配置。

結語

1. 除了給Gitlab倉庫配置CI&CD,同時他也支持其他倉庫如Github等;

2. Gitlab也定義了一下API可以結合其他工具來執行CI&CD任務;

3. 如果使用gitlab>=v11的版本還可以根據需要配置Auto DevOps等

這是我們使用的例子,如有其他需求和問題可以評論討論或回復不及時時請查看docs.gitlab.com/ee/ci/R

本文是滴滴雲開源工具教程系列文章的一篇,作者 石聯樂

滴滴雲官網:didiyun.com/?

滴滴雲瘋狂雙十一,伺服器最低35折起

推薦閱讀:

TAG:前端開發 | Git | 持續集成(CI) |