qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github
email
telegram

gitlab 的CI/CD 流水线初体验

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 项目中的 构建 ---> 流水线编辑器 中新建配置文件,或使用官方的配置模板

image
配置文件的命名固定为 .gitlab-ci.yml, 且必须放在项目的根目录下

image
.gitlab-ci.yml有其指定的关键字与格式,你可以在此处查看官方的语法文档
常用的关键字如下

关键字说明用法
image指定流水线需要的 Docker 镜像image: docker:latest
services指定的附加镜像services:- name: docker:dind
variables定义全局参数variables:PORT: 9005
stages定义流水线阶段stages:- build - docker-build
tags指定此阶段要使用的 runnertags: - 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

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。