名词概念解释

持续集成

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

自动化构建 举例来说 我们提交代码后,只要满足某个条件,就会触发自动合并代码,自动编译代码,自动测试代码,以及自动发布到 相应 部署环境中。

持续集成指的是,频繁地(一天多次)将代码集成到主干。

它的好处主要有两个。

(1)快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。

(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。

Martin Fowler说过,“持续集成并不能消除Bug,而是让它们非常容易发现和改正。”

想要做到持续集成,就需要 做到自动化构建,能够实现自动化构建的软件很多,比如Jenkins,而我们用来保存代码的gitlab本身也提供了自动化构建的功能 gitlab-ci。

ci/cd

ci/cd主要完成以下两个工作.

ci(持续构建)
代码提交后触发自动化的单元测试,代码预编译,构建镜像,上传镜像等.

cd(持续发布)
持续发布则指将构建好的程序发布到各种环境,如预发布环境,正式环境.

Gitlab

GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。
它拥有与GitHub类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

Gitlab-CI

Gitlab-CI是GitLab Continuous Integration(Gitlab持续集成)的简称。
从Gitlab的8.0版本开始,gitlab就全面集成了Gitlab-CI,并且对所有项目默认开启。
只要在项目仓库的根目录添加.gitlab-ci.yml文件,并且配置了Runner(运行器),那么每一次合并请求(MR)或者push都会触发CI pipeline。

Gitlab-runner

Gitlab-runner是.gitlab-ci.yml脚本的运行器,Gitlab-runner是基于Gitlab-CI的API进行构建的相互隔离的机器(或虚拟机)或者k8s中的pod。GitLab Runner 不需要和Gitlab安装在同一台机器上,但是考虑到GitLab Runner的资源消耗问题和安全问题,也不建议这两者安装在同一台机器上。

Gitlab Runner分为两种,Shared runners和Specific runners。
Specific runners只能被指定的项目使用,Shared runners则可以运行所有开启 Allow shared runners选项的项目。

Pipelines

Pipelines是定义于.gitlab-ci.yml中的不同阶段的不同任务。
我把Pipelines理解为流水线,流水线包含有多个阶段(stages),每个阶段包含有一个或多个工序(jobs),比如先购料、组装、测试、包装再上线销售,每一次push或者MR都要经过流水线之后才可以合格出厂。而.gitlab-ci.yml正是定义了这条流水线有哪些阶段,每个阶段要做什么事。

Badges

徽章,当Pipelines执行完成,会生成徽章,你可以将这些徽章加入到你的README.md文件或者你的网站。

特点

gitlab ci/cd具有以下特性:

跨平台支持
只要支持go语言的平台均可以在上面进行ci,目前基本涵盖了大部分的操作系统

多语言支持
构建时是通过脚本触发,因此基本上支持所有的语言

Pipeline
可以通过不同的阶段形成工作流

支持docker
可以构建docker镜像,同时也支持触发在Kubernetes允许

安装配置

前提—安装gitlab

对于安装gitlab有一点提醒,就是建议使用官方推荐的集成安装包的方式安装,通过源码安装会有很多坑踩不完。

参考链接:

https://blog.csdn.net/duyusean/article/details/80011540

https://www.jianshu.com/p/ade38a53b1ac

https://zhuanlan.zhihu.com/p/62042884

安装和配置gitlab-ci-multi-runner

添加Gitlab的官方源并安装:

# For Debian/Ubuntu
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash

# For CentOS
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash



# For Debian/Ubuntu
sudo apt-get install gitlab-ci-multi-runner

# For CentOS
sudo yum install gitlab-ci-multi-runner

注册Runner

Runner需要注册到Gitlab才可以被项目所使用,一个gitlab-ci-multi-runner服务可以注册多个Runner。

根据相应提示输入 对应我们起的名称 和 给的域名即可。

注意:
如果想要使用docker runner,则需要安装docker。(可选)

curl -sSL https://get.docker.com/ | sh

因为docker需要linux内核在3.10或以上,安装前可以通过uname -r查看Linux内核版本。

$ sudo gitlab-ci-multi-runner register

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://mygitlab.com/ci
Please enter the gitlab-ci token for this runner
xxx-xxx-xxx
Please enter the gitlab-ci description for this runner
my-runner
INFO[0034] fcf5c619 Registering runner… succeeded
Please enter the executor: shell, docker, docker-ssh, ssh?
docker
Please enter the Docker image (eg. ruby:2.1):
maven:3-jdk-8
INFO[0037] Runner registered successfully. Feel free to start it, but if it’s
running already the config should be automatically reloaded!

说明:
1、gitlab ci的地址以及token,从你要配置该runner到哪个项目,就去gitlab下该项目首页右侧设置—》CI/CD Pipelines—》Specific Runners下可以找到,也可以注册称共享runner。
2、gitlab-ci tags这个很重要,在项目构建流程yaml文件里面指定tag,就是匹配使用哪个tag的runner,这里我定义了hwy,回头再配置文件里面就指定这个tag。
3、executor:执行者可以有很多种,这里我们使用docker,方便构建执行。
4、Docker image:构建Docker image时填写的image名称,根据项目代码语言不同,指定不同的镜像。我这里项目是java语言的,所以我使用官方maven:3-jdk-8镜像。

若是runner注册成功,此时到我们项目首页右侧设置—》CI/CD Pipelines—》Runners activated for this project就可以看到我们刚注册的runner了。如图:
在这里插入图片描述

紧接着最后一步,启动我们刚注册的Runner

sudo  gitlab-ci-multi-runner start

更新Runner
如果需要更新Runner,只需要执行以下脚本:

# For Debian/Ubuntu
sudo apt-get update
sudo apt-get install gitlab-ci-multi-runner

# For CentOS
sudo yum update
sudo yum install gitlab-ci-multi-runner

Runner高级配置

通过gitlab-ci-multi-runner register注册的Runner配置会存储在/etc/gitlab-runner/config.toml中,如果需要修改可直接编辑该文件。

更多配置参数参考官网: advanced-configuration.md

concurrent = 4
check_interval = 0

[[runners]]
name = “test”
url = “http://your-domain.com/ci“
token = “your-token”
executor = “docker”
[runners.docker]
  tls_verify = false
  image = “node:4.5.0”
  privileged = false
  disable_cache = false
  volumes = [“/cache”]
[runners.cache]
[runners.kubernetes]
  host = “”
  cert_file = “”
  key_file = “”
  ca_file = “”
  image = “”
  namespace = “”
  privileged = false
  cpus = “”
  memory = “”
  service_cpus = “”
  service_memory = “”

到这里我们的Runner就安装配置好了,接下来是对项目根目录中.gitlab-ci.yml进行配置。

配置构建任务

在项目根目录添加.gitlab-ci.yml文件
关于.gitlab-ci.yml文件的各项配置和格式参考官网 GitLab CI/CD pipeline configuration reference

示例:

variables:
  # This will supress any download for dependencies and plugins or upload messages which would clutter the console log.
  # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
  # when running from the command line.
  # `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins.
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
  IMAGE_NAME: 123.dkr.ecr.cn-northwest-1.amazonaws.com.cn/myimages/web
  
  
  
stages:
  - package
  - build
  - deploy



# Cache downloaded dependencies and plugins between builds.
# To keep cache across branches add 'key: "$CI_JOB_NAME"'
cache:
  paths:
    - .m2/repository

# Validate merge requests using JDK8
package:
  image: maven:3-jdk-8
  stage: package
  script:
    - 'mvn $MAVEN_CLI_OPTS package'
  artifacts:
    paths:
      - target/*.jar
      
      
build-sit:
  stage: build
  tags:
    - common
  only:
    - dev
  image: 123.cn-beijing.aliyuncs.com/public/docker-with-awscli:latest
  script:
    - eval $(aws ecr get-login --no-include-email --region cn-northwest-1)
    - docker build -t $IMAGE_NAME:sit .
    - docker push $IMAGE_NAME:sit
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_DEFAULT_REGION: ${AWS_REGION}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}



build-beta:
  stage: build
  tags:
    - common
  only:
    - master
  image: 123.cn-beijing.aliyuncs.com/public/docker-with-awscli:latest
  script:
    - eval $(aws ecr get-login --no-include-email --region cn-northwest-1)
    - docker build -t $IMAGE_NAME:beta .
    - docker push $IMAGE_NAME:beta
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_DEFAULT_REGION: ${AWS_REGION}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}

build-prod:
  image: 123.cn-beijing.aliyuncs.com/public/docker-with-awscli:latest
  tags:
    - common
  stage: build
  only:
    - tags
  script:
    - eval $(aws ecr get-login --no-include-email --region cn-northwest-1)
    - docker pull $IMAGE_NAME:beta
    - docker tag $IMAGE_NAME:beta $IMAGE_NAME:$CI_COMMIT_TAG
    - docker push $IMAGE_NAME:$CI_COMMIT_TAG
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_DEFAULT_REGION: ${AWS_REGION}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}



deploy:
  image:
    name: 123/k8s-kubectl:v1.14.4
    entrypoint: [""]
  stage: deploy
  only:
    - tags
  script:
    - sed -i "s/_TAG_/${CI_COMMIT_TAG}/" deploy.yml
    - kubectl apply -f deploy.yml --record
  tags:
    - aws-online-k8s
    
    
    
deploy-test:
  image:
    name: 123/k8s-kubectl:v1.9.9
    entrypoint: [""]
  stage: deploy
  only:
    - test
  tags:
    - aws-test-new-k8s
  script:
    - kubectl   delete  --ignore-not-found=true  -f deploy-test.yml --namespace=sit
    - kubectl   create -f deploy-test.yml   --namespace=sit


    
    
    
deploy-beta:
  image:
    name: 123/k8s-kubectl:v1.14.4
    entrypoint: [""]
  stage: deploy
  only:
    - beta
    - master
  tags:
    - eks-beta-k8s
  script:
    - kubectl  delete  --ignore-not-found=true -f deploy-beta.yml
    - kubectl  create -f deploy-beta.yml




说明:

一、variables 中可以放一些相关的参数,在下面的配置中复用,比如IMAGE_NAME,使用时如下:

  script:
    - eval $(aws ecr get-login --no-include-email --region cn-northwest-1)
    - docker pull $IMAGE_NAME:beta

二、关于文件的路径
在安装Runner时,我们说到工作目录,在工作目录下有一个builds目录,Runner的一切工作都在这个目录下面进行。

每次提交代码Runner就会自己fetch下代码, 当前目录 跟我们项目代码的路径一致,比如 我的项目中 有deploy.yml这个文件,则使用时,直接用当前目录即可。

如下:

sed -i "s/_TAG_/${CI_COMMIT_TAG}/" deploy.yml
也可以是

sed -i "s/_TAG_/${CI_COMMIT_TAG}/" ./deploy.yml

三、关于GitLab CI中的stages,有如下几个特点:

1、所有 Stages 会按照顺序运行,即当一个 Stage 完成后,下一个 Stage 才会开始
2、只有当所有 Stages 完成后,该构建任务 (Pipeline) 才会成功
3、如果任何一个 Stage 失败,那么后面的 Stages 不会执行,该构建任务 (Pipeline) 失败
4、stages的名字我们可以根据自己的需求进行定义,只要与后面的步骤stage字段对应就会运行

四、tags

tags用于指定使用哪一个runner进行运行

五、image

image指定在这个runner上使用什么镜像进行运行

六、only

only用于指定 分支和tag版本的操作,只有对应上分支的命名或者 打tag的操作时 才会触发运行

七、script

具体运行的脚本

八、variables

variables是 运行ci操作时 环境变量中注入的 参数,比如 aws的key,这样可以保证 我们的runner运行ci的环境有 操作s3的权限。

参考资料

https://www.jianshu.com/p/705428ca1410

https://segmentfault.com/a/1190000007180257

http://choerodon.io/zh/docs/installation-configuration/steps/gitlab-runner/

https://juejin.im/entry/5ad8627d6fb9a045d639b043

https://www.jianshu.com/p/705428ca1410

https://blog.csdn.net/aixiaoyang168/article/details/72168834

https://blog.csdn.net/aixiaoyang168/article/details/72168834

https://lvwenhan.com/many/484.html

https://juejin.im/post/5ad47bddf265da23945ff4c8

https://juejin.im/post/5adb655c518825673123c8ea

https://www.jianshu.com/p/b1e098cdb46b

https://segmentfault.com/a/1190000012989919

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐