CI/CD#
關於 CI/CD 的理念與解釋這裡就不說了,可以看這篇文章
為什麼選擇 gitlab 的流水線#
原因也很簡單,公司的代碼托管在 gitlab 上,且 gitlab 的 free 額度好像還挺高。
不選擇Jenkins的原因也很簡單,UI 過時,功能雖多但佔用也高。
如果是新手的話 Drone 可能也很好?畢竟有可視化界面,且佔用也很小。
註冊 runner#
如果你只是想測試或者嘗鮮,那不註冊而使用共享的 runner 也是可以的。
但如果是要部署在自己的伺服器上則一定要使用註冊的 runner。
runner 的註冊方式一般有 2 種
docker
docker run -d --name gitlab-runner --restart always \\n -v /home/jk/docker/gitlabRunner/config:/etc/gitlab-runner \\n -v /var/run/docker.sock:/var/run/docker.sock \\n gitlab/gitlab-runner:latest
注意 docker 方式註冊的 runner 無法在宿主機層面部署新的容器。dind (docker in docker) 相當於多嵌了一層,所以它只適合構建而不適合部署
shell
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
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
sudo gitlab-runner register --url https://gitlab.com/ --registration-token {gitlab註冊runner的token}
sudo gpasswd -a gitlab-runner docker
shell 模式可以在宿主機拉取並運行 docker 鏡像,適合部署服務
更詳細的安裝教程可以查看官方文檔
創建配置文件#
你可以在 gitlab 項目中的 構建 ---> 流水線編輯器 中新建配置文件,或使用官方的配置模板
配置文件的命名固定為 .gitlab-ci.yml
,且必須放在項目的根目錄下
.gitlab-ci.yml
有其指定的關鍵字與格式,你可以在此處查看官方的語法文檔
常用的關鍵字如下
關鍵字 | 說明 | 用法 |
---|---|---|
image | 指定流水線需要的 Docker 鏡像 | image: docker:latest |
services | 指定的附加鏡像 | services:- name: docker:dind |
variables | 定義全局參數 | variables:PORT: 9005 |
stages | 定義流水線階段 | stages:- build - docker-build |
tags | 指定此階段要使用的 runner | tags: - shell-node |
artifacts | 作業產物,使用 build 命令會產生文件,此關鍵字可保存構建後的文件 | artifacts:paths:- target/jk_testing-1.0-SNAPSHOT.jar |
script | 指定此階段要運行命令腳本 | script:- mvn clean install |
當然,gitlab 也提供了相當多的變量以供使用
如 $CI_COMMIT_SHORT_SHA
表示本次提交的特徵值,你也可以使用 variables
中的自定義變量
也可以在官方文檔查看全部的變量
我非常建議您使用 Dockerfile
將您的項目打包成 docker 鏡像,這將會使它比較容易管理及部署。
例子#
下面我將用一個 spring boot
項目來為您解釋配置文件。我會盡量增加註釋
# 指定流水線需要的 Docker 鏡像
image: docker:latest
# 指定的附加鏡像
services:
- name: docker:dind
# 參數定義
variables:
PORT: 9005
APPLICATION_NAME: test
# 定義流水線階段
stages:
- build
- docker-build
- deploy
- notify
# 構建階段:執行 Maven 構建
build:
image: maven:3.6.3-openjdk-8
stage: build
# 定義執行腳本
script:
- mvn clean install
artifacts:
paths:
- target/jk_testing-1.0-SNAPSHOT.jar
# Docker 構建階段:構建 Docker 鏡像並推送到鏡像庫
docker-build:
stage: docker-build
script:
- docker build -t $APPLICATION_NAME .
- docker tag $APPLICATION_NAME $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# 部署階段:滾動更新鏡像
deploy:
stage: deploy
# 指定註冊方式為shell的runner
tags:
- shell-node
script:
# 定義多段腳本
# 先停止name中包含test的容器,再刪除容器和鏡像
# 然後從鏡像庫拉取最新的鏡像並運行
- >
if [[ $(docker ps -q -f name=$APPLICATION_NAME) ]]; then
docker stop $APPLICATION_NAME 2>/dev/null;
docker rm $APPLICATION_NAME 2>/dev/null;
docker images | grep test | awk '{print $3}' | xargs -I {} docker rmi {};
fi
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker run -d -p $PORT:9004 --name $APPLICATION_NAME $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# 構建失敗時的通知消息
notifyFailWeChat:
stage: notify
script:
- apk add curl
- curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key= {微信機器人token}' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"小程序項目構建結果:<font color=\\"warning\\">失敗</font>\n>本次構建由:$GITLAB_USER_NAME 觸發\n>項目名稱:$CI_PROJECT_NAME\n>提交號:$CI_COMMIT_SHA\n>提交日誌:$CI_COMMIT_MESSAGE\n>構建分支:$CI_COMMIT_BRANCH\n>流水線地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
# 指定僅master分支運行
only:
- master
# 指定什麼時候執行,此處為流水線構建失敗時執行
when: on_failure
# 構建成功時的通知消息
notifySuccessWeChat:
stage: notify
script:
- apk add curl
- curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key= {微信機器人token}' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"小程序項目構建結果:<font color=\\"info\\">成功</font>\n>本次構建由:$GITLAB_USER_NAME 觸發\n>項目名稱:$CI_PROJECT_NAME\n>提交號:$CI_COMMIT_SHA\n>提交日誌:$CI_COMMIT_MESSAGE\n>構建分支:$CI_COMMIT_BRANCH\n>流水線地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
only:
- master
when: on_success