配置复杂的 Gitlab CI/CD Pipeline

2 持续集成:GitLab CI/CD 与 Jenkins CI/CD 的全面剖析 GitLab CI/CDGitLab 平台自带的持续集成和持续部署解决方案。GitLab 作为一个功能强大的代码托管平台,集成了版本控制、代码审查、问题跟踪等多种功能。GitLab CI/CD 紧密结合这些特性,用户只需在项目根目录下创建一个文件,即可定义项目的 CI/CD 流水线。该文件使用 YAML 格式,清晰地描述了从代码拉取、构建、测试到部署的各个阶段和步骤。同时,GitLab 提供了可视化的界面,方便用户监控和管理流水线的执行情况。Pipeline 是持续集成和持续部署过程中的核心概念, 阅读详情

假设您需要部署多个复杂环境,并且计划使用 Gitlab 流水线,该如何操作?在 Padok,我们已经遇到过这个问题,并通过结合多项目动态流水线、工件以及 Gitlab 作业之间的依赖关系解决了这个问题。

本文介绍了我们针对该问题的解决方案、我们开发的组件以及如何安排它们协同工作。目标是创建以下管道结构:

Gitlab是一个基于 Git 的 Web 源代码控制存储库,专为团队协作和生产力而设计。它是一款非常强大的开发工具,可让您的团队掌控全局,优化工作流程以符合部署 SLA,并提供大量选项来创建复杂的 CI/CD 流水线。

最后一部分确实让我们考虑将 Gitlab CI 作为当前问题的解决方案。此外,它已经非常流行,文献中有很多关于自动化 DevOps 生命周期、在 Kubernetes 中部署应用程序、实施 GitOps 最佳实践等等的示例!

如何设置动态 Gitlab 管道?

首先,我们需要一个能够动态运行下游管道的主作业。我们希望根据用户在输入参数中的选择创建任意数量的环境:可以是 1 个,也可以是像本例中那样的 3 个,或者更多。问题是:如何create-env多次触发该作业?答案是:使用动态 Gitlab 管道。

GitLab CI 中的动态管道是根据某些条件或参数以编程方式生成的。这意味着管道中的步骤和任务不是固定的,而是可以根据输入或上下文进行更改。

例如,您可以使用它们自动运行一个需要执行数百次相同任务的作业,每个实例几乎完全相同,但只有细微的差别。编写同一作业的每个变体将非常繁琐,几乎不可能。您无需编写数千行代码,而是可以使用Gitlab CI中的动态管道生成它们。

动态管道有助于管理复杂或大型的CI/CD 管道,其中的任务和依赖关系可能因上下文而异。它们允许团队自动化和定制其 CI/CD 流程,从而提高效率和效果。

# bootstrap-env/.gitlab-ci.yml
# boostrap-env
# ├── .gitlab-ci.yml   <--
# ├── generate_templates.py
# └── requirements.txt

variables:
ENVIRONMENTS:
description:"User input: comma-separated list of environments"
value:"dev,prod,staging"

stages:
-templating
-deployment

generate-templates:
stage:templating
image:python:3.10
before_script:
    -pipinstall-rrequirements.txt
script:
    -pythongenerate_templates.py--env$ENVIRONMENTS
artifacts:
    paths:
      -environments.yml

deploy-envs:
stage:deployment
trigger:
    include:
      -artifact:environments.yml
        job:generate-templates
strategy:depend

在此示例中,我们使用自定义 Python 脚本为 Gitlab CI/CD 作业生成 YAML 配置文件。这是流水线的第一阶段:templating。在第二阶段deployment,我们使用生成的文件来部署用户最初在ENVIRONMENTS变量中请求的每个环境。

因此,environments.yml 配置文件将包含 3 个作业,每个作业负责创建一个环境:dev、prod 和 staging。

用户可以输入他们需要的环境,模板阶段将创建与需要引导的环境一样多的作业。

瞧!我们有了 3 个子作业,分别对应我们要求的 3 个环境,但是如何让它们真正创建新的环境呢?


如何设置多项目下游 Gitlab 管道?

其次,我们希望目标流水线架构的每个步骤都位于一个专门的 Gitlab 项目中。问题在于告诉 Gitlab:“您能否触发另一个项目的流水线来为我创建一个新环境?” Gitlab 实际上提供了两种不同的方法来实现这一点:使用trigger或调用 API。

在这个例子中,我们需要两者,因为可以触发的下游管道的最大深度为 2,但在这里我们至少需要 3!希望使用 API 触发它们会重置计数器,这样您就可以使用此技术向下移动任意层级。这是一个很酷的技巧,但需要权衡利弊。

好的一面是,这两种方法在父子表示方面具有类似的行为。正如您在trigger作业中所期望的那样,您可以看到父项目中运行的管道,以及子项目中运行的管道,并带有指向原始项目的链接。

然而,不利的一面是,当涉及大量变量并需要传递给子管道时,POST 命令语法会变得有点难以理解。

此外,使用 API 调用子管道的父作业不会等待其子管道终止。相反,只要 curl 命令正确执行,它们就会成功退出。当你需要后续阶段的其他作业执行这些步骤时,这可能会成为一个问题。一种解决方法是在 API 调用后添加一个等待循环。

我们研究了多种解决方案,主要是 Shell 脚本中的循环,这些循环调用 Gitlab API 之一来列出项目作业、列出管道作业或列出管道桥,具体取决于您的需要。

# bootstrap-env/generated-template.yml

deploy-staging:
environment:staging
variables:
    GITLAB_PROJECT_ID:123456789# the project ID of 'create-env'
    GITLAB_REF:main
script:
    - > 
      curl --request POST
      --form "token=$CI_JOB_TOKEN"
      --form "ref=$GITLAB_REF"
      --form "variables[ENVIRONMENT]=$CI_ENVIRONMENT_NAME"
      "https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/trigger/pipeline"

这样,每个生成的作业都会触发create-env管道。我们使用curl调用Gitlab API,并指定token触发多项目管道所需的重要参数,例如 。此外,我们传递相关变量:在此示例中,我们需要一个ENVIRONMENT用于后续阶段的变量。

反过来,create-env使用以下方式触发add-resources

# create-env/.gitlab-ci.yml

stages:
-resources

add-env-resources:
stage:resources
rules:
    -if:$CI_PIPELINE_SOURCE=="pipeline"
trigger:
    project:"$GITLAB_GROUP/add-resources"
    branch:main
    strategy:depend

# [ ... ]

对于多项目管道,该trigger关键字接受 Gitlab project 作为参数,可以是简单字符串,也可以是 project 关键字。此外,值得一提的是,该trigger:project语法仅适用于 Gitlab Premium 帐户。该strategy: depend选项使父管道的状态取决于其子管道的状态。

另外,请注意,rules只有当另一个管道触发时,作业才会运行。这有助于避免在代码推送和合并请求时意外创建环境……这些环境可能会迅速演变成非常严重的问题!

在架构的更深处,多项目下游管道将以相同的方式工作:resource1使用trigger逻辑调用add-resource1,依此类推。

问题解决了。然而,当涉及到文物时,事情就变得棘手了。


如何在 Gitlab 作业之间传递工件?

最后是工件。我们使用它们来传达有关在整个过程中创建的资源的信息。在此示例中,resource2需要有关 resource1的信息,而resource3需要有关resource1resource2的信息。每个管道的末尾都会创建一个工件add-resource#,我们在父级获取它们,以便在创建新资源时将变量传递给其他子级。

请毫不犹豫地查看本文顶部的第一个图表:在本节中,我们将重点关注最右侧,包括所有与资源相关的存储库和管道。

主要挑战之一是作业之间的依赖关系图:父作业必须等待子作业成功退出。然后它们才能获取生成的工件。stages对于同一项目中的作业,使用依赖策略实现起来相对容易:

# add-resources/.gitlab-ci.yml
# add-resources
# ├── .gitlab-ci.yml   <--
# ├── resource1.yml
# ├── resource2.yml
# └── resource3.yml

variables:
ARTIFACT_RESOURCE3:"resource3-outputs.zip"
ARTIFACT_RESOURCE2:"resource2-outputs.zip"
ARTIFACT_RESOURCE1:"resource1-outputs.zip"

stages:
-resource1
-resource2
-resource3

add-resource1:
stage:resource1
trigger:
    include:
      -local:"resource1.yml"
    strategy:depend

add-resource2:
stage:resource2
trigger:
    include:
      -local:"resource2.yml"
    strategy:depend

add-resource3:
stage:resource3
trigger:
    include:
      -local:"resource3.yml"
    strategy:depend

默认情况下,GitLab 中所有来自先前阶段的工件都会传递到后续阶段。这会导致存储、安全性和流水线速度方面的问题。为了缓解这个问题,您还可以考虑dependencies使用字段来精确指定作业所需的工件。

另一方面,当工作是多项目下游管道中不同项目的一部分时,这种stage方法是不够的,您将不得不使用needs关键字。

# add-resources/resource2.yml
# add-resources
# ├── .gitlab-ci.yml
# ├── resource1.yml
# ├── resource2.yml   <--
# └── resource3.yml

variables:
GITLAB_PROJECT:add-resource2
GITLAB_REF:main

# Parse artifacts to get information needed for resource2 pipeline
parse-resource1-artifact:
before_script:
    -apt-getupdate&&apt-getinstall-yzipjq
needs:
    -project:"$GITLAB_GROUP/add-resource1"
      job:add-resource1
      ref:main
      artifacts:true
script:
    -echo"Parsing resource1 artifact from \"$ARTIFACT_RESOURCE1\"..."
    ->
      RESOURCE1_ID=$(unzip -p $ARTIFACT_RESOURCE1 resource1_information.json | jq -r '.id') &&
      echo $RESOURCE1_ID

# Triggers the creation of a new resource2 resource
trigger-resource2-pipeline:
variables:
    RESOURCE1_ID:$RESOURCE1_ID
trigger:
    project:"$GITLAB_GROUP/$GITLAB_PROJECT"
    branch:$GITLAB_REF
    strategy:depend
    forward:
      pipeline_variables:true
needs:
    -parse-resource1-artifact

逻辑needs优先于stage逻辑:这意味着如果同时设置了两个字段,管道将忽略阶段顺序,只关注需求。根据官方文档,对于工件也是如此:

“当一项工作使用时needs,它不再默认下载来自先前阶段的所有工件,因为带有的作业 needs可以在先前阶段完成之前开始”。

在这个例子中,我们确保第一个作业在运行实际管道之前从上一步检索工件:在中parse-resource1-artifact,我们下载工件,然后提取一些信息。

为了举例,我们实现了一个简单的解析逻辑,但输出可以是自定义 JSON 文件、日志、Terraform 状态、Kubernetes API 调用……您明白了。

结论

好了,各位!希望大家今天学到了一些有用的东西。欢迎随时联系我们,我们非常乐意与您讨论并学习。谢谢🤍。

什么是devops,基于Gitlab从零开始搭建自己的持续集成流水线(Pipeline) 持续集成 devops pipeline CI/CD Gitlab 运维 阅读详情

相关推荐

全栈开发持续交付实战:GitLab CI/CD与Jenkins Pipeline

持续交付是一种软件开发实践,它强调将代码频繁地集成、构建、测试和部署到生产环境,以确保软件始终处于可发布的状态。缩短交付周期:通过自动化流程减少手动操作,加快软件交付速度。降低部署风险:通过频繁的测试和验证,确保软件质量,降低部署失败的风险。提高协作效率:通过统一的流程和工具,促进开发、测试、运维等团队之间的协作。GitLab CI/CDGitLab内置的持续集成和持续交付工具,它允许开发团队在代码仓库中定义和管理自动化的流水线,以实现自动化构建、测试和部署应用程序的过程。

shejizuopin的博客 815

Jenkins集成GitlabPipeline实现自动化部署(高级篇)

目录一、前言二、为什么使用 Pipeline?三、Pipeline 基本概念1.Stage2.Node3.Step五、Pipeline 语法概述1.声明式流水线基础六、使用 pipeline1.创建一个流水线任务2.配置流水线(1)配置构建触发器(2)配置流水线(Pipeline script)(3)配置流水线(Pipeline script from SCM)3.生成 Pipeline Script4.配置 Gitlab Webhook5.测试 一、前言 本博在 Jenkins集成Gitlab实现自动化

邓邓子的博客 8793

GitLab CI/CD Pipeline失败?别慌!手把手教你排查.gitlab-ci.yaml配置问题

本文系统化地指导开发者如何排查和修复GitLab CI/CD Pipeline失败问题。文章深入解析了.gitlab-ci.yaml配置文件,重点讲解了如何利用CI_PIPELINE_SOURCE等关键变量控制Pipeline触发条件,并提供了从检查作业日志、验证语法到分析Runner状态与执行环境的完整排查路径,帮助读者从容应对CI/CD挑战。

b9c0d的博客 566

gitlab动态流水线

我们希望如果研发在提交代码的时候,如果commit message中有x86_64关键字,则创建一个Release_x86_64的job,如果commit message中有aarch64关键字,则创建一个Release_aarch64的job。该案例使用了include的嵌套方式,也是另类的一种高级用法。ci-test 是公共项目variables.yml 里面存放了群组级下的所有的常用的变量。

最美dee时光的博客 3799

【基于 GitLabCI/CD 实践】03、GitLab Pipeline 实践(上)

GitLab Pipeline 实践(上)

GG Bond 的博客 3565

GitLab CI 驱动禅道自动化部署:从零构建企业级 CI/CD 流水线

本文介绍了如何通过GitLab CI实现禅道项目管理系统的自动化部署,构建企业级CI/CD流水线。主要内容包括: 架构设计:展示了GitLab与禅道双向集成的数据流向,实现从代码提交到任务状态更新的闭环。 环境准备:详细说明了所需组件及配置要求,包括GitLab、禅道、GitLab Runner和Docker的版本建议。 集成配置:分步骤指导如何生成GitLab访问令牌、关联代码库、实现任务与提交的双向链接,以及配置Webhook触发机制。 Runner部署:提供基于Docker的GitLab Runner

无论云泥意贯一 707

DevOps系列之GitlabCI 流水线-01GitLabPipeline组成和开发工具

GitLabPipeline组成和开发工具

lee_yanyi的博客 5004

gitlab配置pipeline学习备忘录

或者在文件/etc/gitlab-runner/config.toml的[[runners]]中新增条目使之主动接收job并执行。我这里生成的是自签名证书,更标准的做法是先生成根证书,再用根证书签发gitlab证书。按照上述配置配置完成即可正常进行自动化测试,如有疑问或错误请联系我。我用的是centos7.9系统,所以下载的是rpm包。

weixin_38700215的博客 1708

GitLab CI/CD学习教程(第三章Pipeline

GitLab CI/CD 中,Pipeline是自动化的构建、测试和部署过程的集合。它是的核心概念之一,帮助开发者通过配置文件定义一系列的工作流,并自动执行这些流程。一个Pipeline通常由多个Stage(阶段)和Job(任务)组成,它们按照一定的顺序执行。每个Job执行一个具体的任务。比如运行单元测试、构建代码或部署应用等。

qq_41898196的博客 2309

lazydocker CI/CD:Jenkins GitLab集成方案

在当今云原生和容器化快速发展的时代,Docker已成为应用部署的标准方式。然而,随着容器数量的增加,传统的命令行管理方式显得力不从心。开发团队经常面临以下痛点: - **可视化监控缺失**:无法直观查看容器状态、资源使用情况和日志 - **操作复杂度高**:需要记忆大量docker命令,容易出错 - **CI/CD集成困难**:缺乏统一的容器管理界面与自动化流程集成 - **多环境管理混乱**:...

gitblog_00978的博客 1036

手把手教学编写gitlab-ci.yml文件以及应用(最简单易懂实践)

编写gitlab-ci.yml文件以及应用

qq_27759825的博客 1万+

gitlab CI/CD :创建一个复杂pipeline流水线

本教程通过小的迭代步骤引导您配置一个日益复杂CI/CD 管道管道始终具有完整的功能,但是每一步都会获得更多的功能。当你完成这个教程,你就可以在gitlab.com中拥有自己的新项目,并且可以在Docusarus中让你的文档网站运行起来。Docusaurus 是 Facebook 专门为开源项目开发者提供的一款易于维护的静态网站创建工具,使用 Markdown 即可更新网站。构建一个带有主页、文档、API、帮助以及博客页面的静态网站,只需5分钟。

qq_44869043的博客 3950

GitLab CI/CDpipeline相关)

GitLab 一个基于Git的在线代码仓库托管软件。 1.YAML YAML(“YAML Ain`t a Markup Language”),YAML不是一种标记语言。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。这种语言以数据做为中心. 1.1 基本语法 大小写敏感 使用缩进表示层级关系(类似python) 缩进不允许使用tab,只允许空格 缩进的空格数不重要,只要相同的层级元素左对齐即可 '#'表示注释 1.2 数据类

weixin_44128977的博客 1738

GitLab CI 配置

GitLab CI 是 GitLab 提供的内置 CI/CD 工具,用户可以通过配置项目根目录的 .gitlab-ci.yml。文件来定义自动化的构建、测试、部署等流程。以下是详细的配置说明、文件路径和具体操作步骤。通过实践逐步熟悉 GitLab CI 的功能,你可以构建出适合团队需求的高效自动化流水线!:定义作业生成的文件以供后续作业使用。:限制作业运行的分支。:定义流水线的阶段。

pumpkin84514的博客 3307

如何做到精通GitLab CI/CD

前言 最近有几个朋友总是问我,博主,你帮我看一看我的流水线,写的规范不规范,符不符合最佳实践。博主该这么学习GitLab CI/CD,有没有什么学习路线?博主这个东西学多久才能像你一样优秀?大家都比较关心这个东西的学习成本,以及学习后的效益如何。本篇文章就来为大家解答一下这些问题。 如何做到精通GitLab CI/CD? 效益很多读者关心的一个问题,虽然他们没有直接问效益这个问题,但从他们的问题中我可以得出这个的一个结论。如果这个东西需要学一个月才能真正把CI/CD整套流程搞定,那我就觉还是尽早放弃比较好。

知无涯 1万+

GitLab CI/CD Pipeline卡在Pending?试试这些高效的Runner配置技巧

本文深入分析了GitLab CI/CD Pipeline卡在Pending状态的常见原因,并提供了高效的Runner配置技巧。从标签管理、Executor选择到高级调优和监控维护,帮助开发者优化CI/CD流程,显著减少Pending时间,提升构建效率。特别适合面临Pipeline延迟问题的GitLab用户。

weixin_30832143的博客 390

【基于 GitLabCI/CD 实践】05、GitLab Pipeline 实践(下)

GitLab Pipeline 实践(下)

GG Bond 的博客 1411

Gitlab 配置自动化Pipeline

GitLab配置CI/CD流水线(pipeline)以实现自动化构建和测试,你需要遵循以下步骤:1. 创建 .gitlab-ci.yml 文件:在项目的根目录或子目录中创建一个名为 .gitlab-ci.yml 的文件,这是定义GitLab CI/CD流水线的配置文件。2. 定义stages:在.gitlab-ci.yml 文件中定义流水线的各个阶段(stages),例如build, test, deploy等。3. 定义jobs:在每个阶段中定义一个或多个作业(jobs),这些作业将按顺序执行。

2301_78843735的博客 1651
上一篇: <span class=“js_title_inner“>15个学习 DevOps 的最佳 GitHub 代码库</span>
下一篇: Jenkins Pipeline Graph View重大更新-完全重新设计的页面
DevOps云学堂
博客等级 码龄9年 477粉丝 120原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值