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