赞
踩
GitLab CI (Continuous Integration)是GitLab内置的进行持续集成的工具。基于特征分支开发后,需要发起Merge Requests合并共享代码库。Merge Requests总是频繁发生,合并请求过来后,可以触发流水线自动去构建、测试、验证新代码功能,及早发现错误,减少集成问题。我们也总是希望在任何时候都能发布稳定版本的软件,自动推送功能变更到演示环境,甚至是生产环境,完成持续地交付(Continuous Delivery)和部署(Continuous Deployment),以减少部署带来的风险和及时得到客户的反馈。通过Gitlab CI减少了人为错误的机会和跨团队沟通成本,提高整个团队的效率。
GitLab CI/CD作为Gitlab整个DevOps生命周期的重要组成部分,对应用的构建、测试、部署和监控都起到重要作用。对于Docker、Kubernetes等容器化技术有着天然的集成,简直就是为云原生而生。
对于Gitlab项目集成CI/CD很容易上手,像之前【Gitlab概览】提到过的那样,只需两个步骤:1、安装Gitlab-Runner及配置,2、工程目录下创建和编写.gitlab-ci.yaml文件。
GitLab-Runner是一个Go语言编写的开源项目,用于运行Job并将结果发送回GitLab,它与GitLab CI/CD一起,协调持续集成服务。它能部署到任何一个地方、任何一个平台,只要它能ping通Gitlab。多个项目可以使用同一个Gitlab-Runner,一个项目也可以使用多个Gitlab-Runner,而Gitlab-Runner还可以并发地执行多个Job,它是灵活的,减轻了Gitlab构建项目的负担。Gitlab-Runner对Docker、Kubernetes的等天然支持,使得项目与容器云服务有很好的集成。
主要有三种类型的Runner: Shared、Group 、Specific。
我们可以用管理员账号登录,注册Shared Runner
安装Gitlab-Runner的版本要注意与Gitlab的版本一致。可能由于新版本引入新功能特性或者Bug,存在版本差异,版本不一致可能造成无法预知的后果。
以CentOS7,Shell执行器为例,可以利用官方的一键脚本安装最新版本的Gitlab-Runner
# For RHEL/CentOS/Fedoracurl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
也可以使用软件源,安装特定版本,注意修改软件源
# For RHEL/CentOS/Fedorasudo yum install gitlab-runner
# for RPM based systems
yum list gitlab-runner --showduplicates | sort -r
sudo yum install gitlab-runner-10.0.0-1
安装时会自动创建Gitlab-Runner的用户,并用这个用户账号运行CI任务。需要注意权限问题。对应Linux root用户,Runner使用的默认配置路径/etc/gitlab-runner/config.toml,对于修改配置,如,并发数参数等,大多数选项,可以不需要重启。默认每5分钟检查一次文件,自动获取所有更改。
Gitlab-Runner拉取Gitlab代码需要授权,这时需要注册URL和Token。以CentOS7,Shell执行器为例,键入命令
#sudo gitlab-ci-multi-runner registersudo gitlab-runner register
按步骤,交互式访问需要依次输入GitLab URL、Gitlab token、Description for the Runner、、等等。非容器化项目,Executor这里选Shell,如果想将项目部署到容器,可以选择相应的Docker、Kubernetes执行器。而利用Tags可以指定项目运行的Gitlab-Runner。URL和Token可以在Gitlab上分配,以Specitic Runner为例
注册成功后,运行Gitlab-Runner
gitlab-runner run
当出现绿色实心圈则表示Gitlab-Runner注册成功,而且正在运行。这时,只要在项目下编写.gitlab-ci.yaml文件就可以啦
GitLab CI使用YAML文件(.gitlab-ci.yml)来管理项目配置。默认存放于项目仓库的根目录,它包含了项目如何被编译的描述语句。YAML文件使用一系列约束定义了Job启动时所要做的事情。
如果.gitlab-ci.yml未指定Runner的tag,可能一直处于Pending状态,这时,可以编辑Runner配置,勾上Run untagged jobs。
Pipelines是整个Gitlab CI最顶层的组件,是一个分成不同阶段(Stage)的作业(Job)的集合。每个推送到 Gitlab 的提交都会产生一个与该提交关联的Pipeline,若一次推送包含了多个提交,则Pipeline与最后那个提交相关联。我们很容易利用每个Pipeline的ID标识做资源隔离,或者作为镜像的版本等等。根据配置可以展现出不同类型的Pipeline,可能是有向无环图(DAG)的,可能是父子结构的等等。
以Java Maven Jar项目为例,通常包含package、test、deploy这三个步骤。先上效果图:
Gitlab CI Pipeline定义了Stage这个阶段概念,对批量的作业进行了一个逻辑上划分。多个Stage间是顺序执行的,一个 Stage失败,后续的 Stage不会被执行,整个 CI 过程会被认为失败。
stages:
- build
- test
- deploy
上述Maven样例中整个 CI 环节包含三个Stage:build、test 和deploy。分别对应maven的打包、测试、部署阶段。其中一个阶段失败,都会导致后面的阶段不可用。
Job是Runner要执行的指令集合,Job 可以被关联到一个Stage,一个Stage可能包含多个Job 。当一个Stage执行的时候,与其关联的所有Job都会被执行。同一个Stage下的Job是可以并发执行的,至于并发能力,这取决于Runner配置的并发数和服务器并行能力。
从官网截了一个图出来,比较直观,Stage间是串行的,同个Stage下Job间是并行的。
我们可以先看下deploy Job的描述片段:
deploy:
stage: deploy
script:
- mvn $MAVEN_CLI_OPTS deploy
only:
- master
Job包含script,一段由Runner执行的shell脚本。在script中,对于直接定义|、>等管道和重定向的shell复合命令,有可能会出现莫名问题,需要甄别。我们可以定义before_script,after_script来辅助Job执行script前后需要准备或者收尾的事情。
#定义全局 before_script:
default:
before_script:
- global before script
#覆盖全局before_script
job:
before_script:
- execute this instead of global before script
script:
- my command
after_script:
- execute this after my script
对于多个Job,有些步骤可能是重复的,如Maven的打包和测试阶段都需要寻找依赖,这时,可以利用缓存机制,将依赖缓存下来,加快Job的执行时间。
variables:
MAVEN_CLI_OPTS: "-s ci_settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
很多时候我们并不希望每次push都触发Pipeline,希望定义触发规则还触发Pineline,我们可能希望指定某个分支,或者以分支名正则关联,或者排除某些分支,或者某个变量的值,或者某个commit的信息,或者某一类代码的变化,或者希望手动触发,或者定时触发,甚至是自定义触发规则等等。这时我们可以利用only和except定义怎么触发Pineline。
only:
refs:
- branches
variables:
- $ENABLE_VERIFY == "true"
changes:
- "**/*.java"
在编辑.gitlab-ci.yaml文件中可以使用预置的变量,如:$CI_PIPELINE_ID表示正在构建的PipelineID,可以在script中使用这个变量。将预置变量CI_DEBUG_TRACE值设为true,则进入debug模式,将打印更多的CI日志。
variables:
CI_DEBUG_TRACE: "true"
我们有可能需要Gitlab-Runner生成的结果回传给Gitlab,提供下载。
artifacts:
#expire_in: 1 week
paths:
- target/*.jar
如果上传打包太大会报错:
ERROR: Uploading artifacts to coordinator... too large archive id=407 responseStatus=413 Request Entity Too Large status=413 Request Entity Too Large token=EQ-TLvUS
FATAL: too large
需要调整允许上传附件的最大大小
修改/etc/gitlab/gitlab.rbGitlab配置,将client_max_body_size值设为0,表示不限制大小
nginx['client_max_body_size'] = 0
我们有可能引入手动,以便更好的控制部署,有时候会只希望负责人手动批准,触发任务部署。
when: mannual
allow_failure: false
对于微服务这种项目,我们可能还要打通上下游项目,需要触发多项目的Pineline。而且多个项目间权限不同,有可能还需要引入批准步骤等等,这些高级特性还有待挖掘。语法中还有模板的功能,这些就详见官方文档了。
以Shell为执行器的Gitlab Runner服务器,在运行Maven Job时,需要提前准备JDK。万事俱备之后,Push代码后,直接自动触发Pipeline。
值得注意的是,Gitlab Runner跑Pineline拉取代码到仓库构建目录,存在一定规则:
{builds_dir}/CONCURRENT_ID/PROJECT_NAME
我们也很容易从Pipeline的日志里看出端倪:/etc/profile.d/builds/53GgNRQd/0/wenqy/simple-maven-dep
配置邮箱后,构建失败会发起邮箱通知:
此外YAML格式文件编写还是易出错的,Gitlab嵌入了校验.gitlab-ci.yml内容格式的调试工具,还是比较人性化的。
总之,Gitlab项目要启用CI/CD还是相当容易,.gitlab-c.yaml文件提供了很大的灵活度,可以根据具体项目的需要定制属于自己团队特殊的CI/CD,Gitlab CI/CD无疑为团队的整个效益提供一大助力,为敏捷开发提供了支持。
https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/
https://docs.gitlab.com/ee/ci/quick_start/
https://docs.gitlab.com/runner/install/linux-repository.html
https://docs.gitlab.com/runner/install/kubernetes.html
https://docs.gitlab.com/runner/commands/README.html
https://docs.gitlab.com/ee/ci/runners/#using-tags
https://docs.gitlab.com/ee/ci/yaml/README.html
https://docs.gitlab.com/ee/ci/examples/artifactory_and_gitlab/
https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Maven.gitlab-ci.yml
https://gitlab.com/gitlab-org/gitlab/-/pipelines/177402875
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。