CI-CD之Gitlab-CI配置文件详解

5,273 阅读6分钟

一、什么是CI/CD/CD?

现代软件公司通常都使用工具将部署代码的流程自动化:

持续集成注重将各个开发者的工作集合到一个代码仓库中,通常每天会进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作,它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布。

持续部署是一种更高程度的自动化,无论何时代码有较大改动,都会自动进行构建/部署,其每一个阶段都称之为pipeline,引用一张版本帝的图片:

  • 持续集成(CI)

持续集成重要思想就是让开发人员更快、更频繁地做到能够频繁地将其代码集成到代码仓库的分支中,开发人员只需要关注开发这个模块,从而降低集成的开销。

要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建,强调的是分支代码的提交、构建与单元测试,这样有助于降低总体的构建成本并在开发周期的早期发现缺陷。

  • 持续交付(CD)

持续交付目的为存在一个永远可用的代码仓库。使用 CD 后每小时甚至每分钟都有可能发生版本发布,所谓小步快跑。

CD 集中依赖于部署流水线(pipeline),团队通过流水线自动化测试和部署过程(去过工厂的都知道流水线吧),在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。

这是一整套研发流程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。

  • 持续部署(CD)

持续部署为整个CI/CD 系统的最后阶段,它将在构建组件编译、打包,并在退出流水线时自动部署发布,此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。

得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷,在这样的流程中,不需要人为决定何时及如何投入生产环境。

二、举个栗子

范例为最为常见的JAVA Maven 的项目,具体 Gitlab-CI 的配置如下:

image: registry-vpc.cn-hangzhou.aliyuncs.com/kubernetes_hub/java_active:0.1

variables:
  # CONTAINER_TEST_IMAGE: $HARBOR_CI_REGISTRY/$CI_PROJECT_NAME

before_script:
 - docker login -u $GITLAB_CI_USER -p $GITLAB_CI_JOB_TOKEN $HARBOR_CI_REGISTRY
 - IMAGE_TAG=$HARBOR_CI_REGISTRY/$CI_PROJECT_NAME-common-backend:$CI_COMMIT_SHORT_SHA

stages:
  - maven_build
  - build_image
  - cleanup 

maven_build:
  stage: maven_build
  script:
   - mvn clean package
  artifacts:
    paths:
     - target/*.jar
  only:
    - master
  tags:
    - java

Build_Image:
  stage: build_image
  script:
    - sed -i "s/PROJECT_NAME/$CI_PROJECT_NAME/g" Dockerfile
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG
  only:
    - master
  tags:
    - java
  when: manual

cleanup_dist_file:
  stage: cleanup
  script:
    - rm -f target/*.jar
  only:
    - master
  tags:
    - java 
  when: always

具体效果如下:

三、Gitlab-CI 常用参数:

在上面的例子中,用到了不少常用的参数,下面我们来解释下各自的含义:

script:
设置Linux脚本命令,执行构建的操作

cache:
设置cache缓存文件,针对不同语言的特性,缓存各种当前目录的包文件,比如缓存前端的node_module依赖包,以此可提高构建效率,像composer、maven的缓存目录不在当前项目目录的,可以不设置;

stage:
设置项目若干个构建阶段,编译、打包、变量替换、发布,等等

artifacts:
驻留文件。在每一次构建的阶段都会清除当前生成的文件,比如:jar包、dist目录、vendor目录,这些都是我们需要的文件,所以如果需要上下两个构建需要关联到上层构建结果的,需要添加此变量:支持单/多个文件或者路径;

only:
设置触发构建的条件,可以指定分支名、tags;

tags(重要):
设置该构建所匹配的Runner环境,如:JAVA、IOS、.NET,不同的环境所用的Runner也不同!
# 值得注意的是:在tag不被指定的情况下,runner会自动匹配更全局的主机,故,如果设置了比较多的runner需要额外小心。底部有runner的优先级链接

when:
设置触发构建的时机,值可以为:on_success、always、manual(手动触发)等;

dependencies:
设置触发此构建的上一个构建;

environment:
设置当前构建所属的环境,对回滚操作非常有用;

3.1 使用 manual 这个参数后的自动构建的差别

使用后:

未启用:

大家可以看到使用 manual 这个参数后,build_image 的操作需用手动执行,这个对日后的发布有重大的作用。

四、Gitlab-CI 内置变量:

在之前的实例中细心的同学一定能发现有几个奇怪的变量,这些变量有些为自定义变量,有些为Gitlab-CI的内置变量方便用户调用,版本帝真良心!

下面是我这边常用的几个内置变量,其中的含义如下:

CI_COMMIT_SHORT_SHA="1ecfd275"
CI_COMMIT_REF_NAME="master"
CI_REPOSITORY_URL="https://gitlab-ci-token:abcde-1234ABCD5678ef@example.com/gitlab-org/gitlab-ce.git"
CI_COMMIT_TAG="1.0.0"
CI_JOB_NAME="spec:other"
CI_JOB_STAGE="test"
CI_JOB_MANUAL="true"
CI_JOB_TRIGGERED="true"
CI_JOB_TOKEN="abcde-1234ABCD5678ef"
CI_PROJECT_ID="34"
CI_PROJECT_DIR="/builds/gitlab-org/gitlab-ce"
CI_PROJECT_NAME="gitlab-ce"
CI_PROJECT_NAMESPACE="gitlab-org"
CI_PROJECT_URL="https://example.com/gitlab-org/gitlab-ce"
CI_RUNNER_ID="10"
CI_RUNNER_TAGS="docker, linux"
CI_SERVER="yes"
CI_SERVER_HOST="example.com"
GITLAB_USER_EMAIL="user@example.com"

上面的解释,按照字面意思已经很明白了,就不赘述了。

五、Gitlab-CI 自定义变量:

Gitlab-CI的变量与Gitlab-Runner息息相关,变量会有作用域的问题,分为群组变量、项目变量,其性质与Gitlab-Runner的作用域原理相同,不清楚的参考我上一篇文章。

5.1 群组变量

群组变量的作用域覆盖在群组之内,简单点来说,同一群组内的所有项目,在这里定义的变量在整个群组中都是共享的,比如,docker registry的地址、账号,密码,组内的数据库连接串,等等。

  • 在群组中设置:

5.2 项目变量

项目变量顾名思义就是作用域只限定与本项目,设置的变量无法作用在其他任何项目上。

  • 在具体项目中设置:

5.3 项目临时变量

项目临时变量,即,项目调试、试运行或需要临时覆盖原有变量的特殊参数,优先级最高,会直接覆盖原有的参数,此参数谨慎操作。

  • 在具体项目中设置:

六、结束语

Gitlab(版本帝)是一家很拉轰的公司,目前笔者也只是小试牛刀,用了一小部分功能而已,还有一些比如:自定义项目模版,gitlab-registry仓库,codereview等功能还没有真正的使用起来,大家一起加油努力吧,有啥好玩的功能欢迎大家一起交流!