gitlab cicd 实战

    111

一、什么是 CICD

软件开发与交付方式的进化史

瀑布模型

download_image (2)

image

敏捷开发

马丁·福勒 Martin Fowler (重构作者 微服务之父)

image (1)

  1. 敏捷开发的高适应性,以人为本的特性。
  2. 更加的灵活并且更加充分的利用了每个开发者的优势,调动了每个人的工作热情。

image (2)

DevOps

DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

通俗点来说,DevOps的目的在保证高质量的同时减少发布流程的总耗时

image (3)

image (4)

image (5)

在敏捷开发中,对产品进行快速迭代,抢占市场以验证产品的可行性,提供更多的功能给用户使用。快速迭代意味着产品平凡部署上线,研发、测试、运维必须要克服这种平凡上线带来的诸多问题:研发质量低;测试不充分,上线后Bug层出不穷;运维上线部署慢、跟不上研发的节奏,经常由于环境、配置等问题导致应用不能正常提供服务等等等等。

一方面希望快速将产品交付给用户使用,另一方面技术人员又害怕这种快速交付,毕竟越快越容易出问题,而且压力大(身上背了很多锅)。正是在这种背景下,DevOps应运而生。为研发、测试、运维团队提供了理论性指导。

字面意思上说 DevOps 是指“开发运维一体化”,即通过工具辅助开发完成运维的部分工作,减少成本。但深入理解了 DevOps 之后,你会发现 DevOps 其实是一种软件研发管理的思想,方法论,他追求的是一种没有隔阂的理想的研发协作的状态。

Google 提出的 5 个 DevOps 原则 这套原则中必须依赖于工具辅助的部分只有后两点,更多的则是对于开发组织形式的内省:

  1. 精简组织架构;(扁平化)
  2. 愿意承担一部分试错带来的损失;(bate版)
  3. 分阶段地一小步一小步地进行转型;(渐进式)
  4. 最大化地利用工具和自动化流程;(CICD 自动化测试 docker)
  5. 对所有的过程和结果进行记录和分析。(ELK)

通常公司内部可能存在几百个微服务,每个部署如果都让运维去维护,人力成本与沟通成本都是无法计量的,所以运维将部署的功能抽象化,研发按一定规则进行提交,进行自动化部署。如果出现异常也可以通过日志采集等工具对生产环境的异常及时去处理,减少双方的割裂。

持续集成(CI)

重点是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。

持续交付(CD)

目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。

持续部署(CD)

是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署。但最终是否需要发布仍然需要人工操作。

小步快跑

二、CICD 工具选择

Jenkins?gitlab CICD?等

选择一个工具的前提是你要清楚使用的场景,开发一个前端,肯定是 js ;做高并发首选应该是 java 或者 Go。

功能JENKINSGITLAB CI/CD开源 / 商业性开源开源产品类型自托管 / 本地部署自托管 / 本地部署内置 CI/ CDJenkins 根据需求支持 CI/CD我们不需要为了 CI/CD 而安装任何东西,这是一个内置功能独特功能插件自动化 DevOps/ 允许持续集成和代码管理在同一个地方进行。安装配置简单简单自托管选项开源软件和自托管是使用它的唯一方法Yes构建 Pipelines通过 Jenkins Pipeline DSL 自定义 pipelineYes应用程序性能监控没有提供用于分析性能的功能展示所有部署的应用程序的性能指标生态系统1000 个社区插件Yes全面的 API提供了全面的 API 功能提供了在软件项目中进行深层集成的 API特定语言支持:JavaScriptYesYes集成允许与其它工具集成(例如:Slack、GitHub)很多第三方集成都可以访问,最著名的是 GitHub 和 Kubernetes。CI/ CD 部署面板部分支持项目中的 CI 和 CD 功能可以根据项目中的 pipeline 历史和最近状态为每一个用户更改一个单独的面板APIYesYes, 提供了一个 REST API & 一个(新的)GraphQL API代码质量通过 Sonarqube 插件以及其它可以用来验证代码质量的不同插件来提供代码质量检查。GitLab 也提供了一个功能来仔细检查代码的质量。

Jenkins

作为一个老牌 CICD 工具无疑是非常成熟的,牛顿曾经说过:如果说我看得比别人更远些,那是因为我站在巨人的肩膀上,Jenkins 拥有的插件量是惊人的,超过 1600 个。

7a02ad8a-127a-451f-b975-ab55a3dd9a77

彩蛋 (我来组成头部)

c054b811-738a-46bd-9cc0-0b1820017031

Jenkins 也有 java 项目的特点,非常重,能做到的功能非常多,但概念复杂,插件良莠不齐,也导致在前期编写 CICD 脚本的工作非常痛苦,那么有没有一款轻量化,对开发友好的 CICD 工具呢?

Gitlab CICD

为何选型 gitlab

  1. 轻量化

Gitlab 并不像 jenkins 需要安装 java 环境,或者是安装插件,仅需要下载二进制运行文件到相应的系统中,注册到 gitlab 中即可。这也决定了 gitlab 很好拓展,可以注册很多台机器做负载均衡,容错等。

  1. 和 git 仓库不割裂
  2. 学习成本低(概念简单)

流水线 pipelines ,一次完整的 CICD 就是一条流水线

作业 Jobs, 一次流水线作业中的每个 stages 就是一个作业,可以失败,可以重试

  1. 迁移成本低

这点也是我最终选择 gitlab CICD 的原因,在 jenkins 中你可能需要先创建一个流水线,又要安装 gitlab (代码仓库插件),又要监听 webhooks 代码推送到指定分支事件,又要配置环境变量(maven 的私有仓库之类的)。

三、CICD 怎么工作

一个Runner可以是一个虚拟机、物理机、docker容器,或者一个容器集群

GitLab与Runner之间通过API进行通信,因此只需要Runner所在的机器有网络并且可以访问GitLab服务器即可

fa9edc96-e9a4-4f06-b18b-aa023b420aeb

29d52932-ed44-40a2-974d-5f0b9bb961d8

af4e917e-bbf8-4b6c-a517-94202129c8e4

Gitlab 在 register 可以选择多种形式,其中bash 模式中则完全依赖当前安装 gitlab 服务器的环境(目标机器)。如果想分布式扩展 gitlab ,那么 docker 下配置 gitlab 也是很好的选择。那么你在服务器执行的运维脚本,无成本的都可以迁移到 gitlab 中完成。gitlab 也无需创建一个流水线,仅需要一个 .gitlab-ci.yml 的文件放到根目录即可触发 gitlab 的流水线作业。

  1. 定义 .gitlab-ci.yml
  2. 推送提交到指定分支
  3. Runner 运行
  4. 自动或手动部署
variables:
  # 是否允许 gitlab 自动拉代码 ,自动拉代码 gitlab 采用的是 https 的协议,云创部分仓库会无法拉取成功(https 文件大小与数量的问题)
  GIT_STRATEGY: none

# 执行前脚本
before_script:
  - echo "CI Build Start"

# 执行后脚本
after_script:
  - echo "CI Build Finish"

# 自己定义阶段
stages:
  - build
  - deploy
  - rollback

# job 名字
test-build:
  # 和 stages 对应的名字
  stage: build 
  only:
    # 分支
    - develop
  script:
    # 执行脚本
    - rm -rf ./java-demo-server
    - git clone git@git.xxxxxx.cn:project/server/java-demo-server.git
    - cd java-demo-server
    - git branch -a
    - git checkout -b develop origin/develop
    - git pull
    - mvn dependency:purge-local-repository
    - mvn clean package
    - cp ./target/java-demo-server.war /webroot/log/deploy/temp/
  tags:
    # gitlab runner 目标及其
    - inficloud

test-deploy:
  stage: deploy
  only:
    - develop
  script:
    - mv /usr/local/apache-tomcat-8.5.42/webapps/java-demo-server.war /webroot/log/deploy/
    - mv /webroot/log/deploy/temp/java-demo-server.war /usr/local/apache-tomcat-8.5.42/webapps/
  tags:
    - inficloud

tess-rollback:
  stage: rollback
  only:
    - develop
  script:
    - cp /webroot/log/deploy/java-demo-server.war /usr/local/apache-tomcat-8.5.42/webapps/
  tags:
    - inficloud
  # 是否必须要手动触发
  when: manual
before_script:
  - echo "CI Build Start"

after_script:
  - echo "CI Build Finish"

stages:
  - build
  - deploy
  - rollback

test-build:
  stage: build
  only:
    - develop
  script:
    - mvn dependency:purge-local-repository
    - mvn clean package
    - mv /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth/inficloud-auth.jar /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth/old-inficloud-auth.jar
    - cp ./target/inficloud-auth.jar /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth/
  tags:
    - inficloud

test-deploy:
  stage: deploy
  only:
    - develop
  script:
    - bash /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth/restart-inficloud-auth.sh
  tags:
    - inficloud

tess-rollback:
  stage: rollback
  only:
    - develop
  script:
    - cd /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth
    - mv inficloud-auth.jar error-inficloud-auth.jar
    - mv old-inficloud-auth.jar inficloud-auth.jar
    - bash /usr/local/apache-tomcat-8.5.42/webapps/inficloud-auth/restart-inficloud-auth.sh
  tags:
    - inficloud
  when: manual

name 说明
script 由Runner执行的Shell脚本。
image 使用docker镜像。也可用:image:name和image:entrypoint。image: centos:7
services 使用docker services图像。也可用:services:name,services:alias,services:entrypoint,和services:command。
before_script 覆盖在作业之前执行的一组命令。
after_script 覆盖作业后执行的一组命令。
stages 定义管道中的阶段。列表
stage 定义作业阶段(默认值:) test。
only 创建作业时限制(常用于分支选择)。也可用:only:refs,only:kubernetes,only:variables,和only:changes。常见用法:only: - branches #所有分支 - tags - /^issue-.*$/ #正则匹配issue-的分支 - master #master分支
except 在未创建作业时限制(常用于排除分支)。也可用:except:refs,except:kubernetes,except:variables,和except:changes。
tags 用于选择Runner的标签列表常用范例:tags: - runner - dev
allow_failure 让工作失败。失败的作业无助于提交状态。
when 什么时候开始工作。参数: on_success:只有当前一个阶段的所有工作都成功时(或者因为它们被标记而被认为是成功的allow_failure)才执行工作 。这是默认值。 on_failure:仅当前一阶段的至少一个作业失败时才执行作业。 always:无论先前阶段的工作状态如何,都可以执行工作。 manual:手动执行作业(在GitLab 8.10中添加)。
environment 作业部署到的环境的名称。也可用:environment:name,environment:url,environment:on_stop,和environment:action。
cache 后续运行之间应缓存的文件列表。也可用:cache:paths,cache:key,cache:untracked,和cache:policy。
artifacts (构建产物交给下一个阶段)成功附加到作业的文件和目录列表。也可用:artifacts:paths,artifacts:name,artifacts:untracked,artifacts:when,artifacts:expire_in,artifacts:reports,和artifacts:reports:junit。在GitLab 企业版,这些都是可供选择:artifacts:reports:codequality,artifacts:reports:sast,artifacts:reports:dependency_scanning,artifacts:reports:container_scanning,artifacts:reports:dast,artifacts:reports:license_management,artifacts:reports:performance和artifacts:reports:metrics。常用范例: artifacts: #构建完成后,构建的产物(目录或者文件),丢给后面的步骤 paths: - .nuxt/ - .
dependencies 作业所依赖的其他作业,以便您可以在它们之间传递工件。
coverage 给定作业的代码覆盖率设置。
retry 在发生故障的情况下,可以自动重试作业的次数和次数。
parallel 应该并行运行多少个作业实例。
trigger 定义下游管道触发器。
include 允许此作业包含外部YAML文件。也可用:include:local,include:file,include:template,和include:remote。
extends 此作业将继承的配置条目。
pages 上传作业结果以用于GitLab Pages。
variables 在作业级别定义作业变量。

参考资料

  1. 什么是DevOps https://aws.amazon.com/cn/devops/what-is-devops/
  2. 如何安装 Gitlab runner https://docs.gitlab.com/runner/install/linux-manually.html
  3. 如何配置 Gitlab runner https://git.ideamake.cn/help/ci/runners/index
  4. Gitlab CICD 脚本编写指南 https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/ci/yaml/index.md
消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息