纵观 GitLab 持续集成
持续集成和持续交付 (CI/CD) 是实现 DevOps 的一种方法。它不仅是一种能让开发人员以增量的方式快速构建和交付软件更新的流程,还包括了支撑此流程的基础设施。在本文中,我们先从宏观角度了解持续集成,探讨 CI 如何提高软件质量和快速交付。为了更好地了解此流程,我们将在每个步骤中使用一个具体示例来说明该流程,并演示 DevOps 和 CI 如何改进软件开发流程。
下面我以浅显易懂的语言解释一下什么是持续集成。我们可以想象成这样:DevOps 注重测试、增量更新和频繁发布,而 CI 是一种实现 DevOps 实践的软件开发流程。CI 通常被描述为管道,代码在该管道中经过提交、构建、测试以及一系列的迭代阶段最终得以发布。每个阶段都是实现软件交付的一步。代码更改通过管道自动构建和测试。如果代码更改导致某个阶段失败或引发回归,则该阶段会检测到错误并停止流程,待问题得到解决后才会继续。修复错误后,代码将进入下一阶段。管道确保了软件质量,因为当软件不能满足某个阶段的条件时,流程就会停止。在 DevOps 实践中,代码的更改小而频繁,便于实现迅速发布。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/pipeline.cc2043ac3b24c42eeaa1751d5a5c94a5316b4d4e.png)
上图展示了一个简单的管道,其中可以根据业务需求添加阶段。例如,一个管道可能有一个单元测试阶段,用于测试特定的功能,也可能有一个集成测试阶段,用于对整个应用程序进行测试。各个阶段还有助于明确团队责任的分界点:从哪里开始,到哪里结束。
GitLab
市面上有许多 CI/CD 解决方案,在本文中,我们将使用 GitLab,它是一个 DevOps 软件包。GitLab 包含用于交付软件的必备 DevOps 工具,如存储库、测试、打包和发布软件。此外,还提供了对配置、监控和治理的额外支持。我们将逐步完成持续集成流程,首先构建一个项目,然后在一个简单的管道中运行各个阶段。该管道包含以下阶段:
- 构建 - 使用 Python Flask 应用程序创建一个测试容器
- 测试 - 对容器执行单元测试
- 发布 - 对测试容器设置标签,进行发布
注意:该示例演示了持续集成的概念,并在处理诸如外部服务 API 密钥等敏感信息时采取了简化流程。最佳做法是将密钥存储在保管库或密钥库中,并配置 GitLab 以在构建过程中检索密钥。建立和添加密钥库不在本示例涵盖范围内。
术语
存储库 - 用于存储代码并跟踪代码更改。
管道 - 以软件的形式实现持续集成,分为多个阶段来交付软件。
作业 - 一个任务,例如编译代码或运行测试
阶段 - 管道中的一个逻辑划分,用于定义作业和执行作业的顺序。
运行器 - 执行管道中作业的软件。每个作业都独立于其他作业运行,只有在上一个作业成功完成后,运行器才会继续运行下一个作业。
.gitlab-ci.yml - GitLab 用于定义管道、阶段和要运行的作业的配置文件。要使用 GitLab CI/CD,需要:
示例管道
示例应用程序可从 GitHub 获取。如果您只是想阅读,可以选择在公共 GitLab 服务上部署。
在本例中,需要:
- GitHub 账户和个人访问令牌
- 按调用量付费 API 密钥,可从 openweather.org 订阅
- 经过验证的公共 GitLab 账户*
*注意:要使用共享运行器上提供的免费时段 CI/CD,您需要使用信用卡验证您的账户。如果您不愿意提供,可以为项目提供自己的运行器并禁用共享运行器,以这种方式运行管道。这是为了遏制和减少滥用 GitLab 基础设施。GitLab 不会从您的信用卡中扣费,仅用于进行账户验证。
让我们开始吧!
步骤 1:在 GitLab 中导入存储库
应用程序存储库位于 GitHub 上。我们将通过在您的 GitHub 账户下复刻存储库,来将存储库导入 GitLab。点击 New Project(新建项目)开始。
提醒:请使用公共 GitLab 服务,以确保用于构建和测试容器的 docker:dind 服务处于可用状态。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/0-gitlab10k.c0c941542ea8a6a852f3b8d2f05b4fd5b79feb7a.png)
如果您没有个人访问令牌,请创建令牌。
步骤 2:将存储库导入 GitLab
点击 Create a project(创建项目)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/1-gitlab10k.724b2129d2c2128ad0e7916103e5221a9e6b3d69.png)
然后点击 Import project(导入项目)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/2-gitlab10k.b712ac95748d0408fd82fba4bca1f9cfa4436725.png)
选择 GitHub。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/3-gitlab10k.609d34aa2b1ce34c64464fa6b17afa9a6dacbb04.png)
使用您的个人访问令牌向 GitHub 进行身份验证。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/4-gitlab10k.1d40d8e53f044419041047d65db59ad0c25abb31.png)
从 GitHub 导入存储库(使用 user_name/continuous-integration-weather-app 进行搜索)。点击 Import(导入)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/5-gitlab10k.9c52f1d0fc4dc4fd0da8a6dfdf3e0713dd83acf3.png)
导入完成后,您将收到通知。点击链接,进入存储库。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/6-gitlab10k.ac8e0cdfb1761648a8cf1a353369395a6627ccde.png)
步骤 3:启动管道
提交新代码或更新时会触发管道。您可以通过在 app.py 文件中添加 Openweather API 密钥来触发管道。选择 app.py 以打开该文件。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/7-gitlab10k.519e26be354670a26eab871b1c7f42e6380e4580.png)
要编辑 app.py 文件,请点击 Open in Web IDE(在 Web IDE 中打开)旁边的向下箭头;选择 Edit - Edit this file only(编辑 - 仅编辑此文件)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/8.da90861591804e96c3d23ad4081889ec1590281a.png)
点击 Edit(编辑)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/8(1).acae6faab37bbcd173c6aefa69daf50d173b3328.png)
在添加 OpenWeather API 密钥之前,请确认该项目为私有。在侧边菜单中,选择 Settings > General(设置 > 常规)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/9.3b7b7cd09fcbb7863970941b4d726e4b8709d0fb.png)
将 OpenWeather api_key 替换为您的密钥。请注意,如果应用程序每天调用 API 的次数超过 1000,将会产生费用。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/9(1).fc6ef34c1c619234f81f41a9732992d9deb3aad7.png)
添加您的 API 密钥后,点击 Commit changes(提交更改)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/9(2).f4bdb71b62ceee9d174138257afccf88ec0e9485.png)
步骤 4:逐步运行管道
点击 Commit changes(提交更改)后,将启动管道,以构建、测试和发布应用程序。我们来看一下用于定义管道的 .gitlab-ci.yml 文件。
在侧栏中选择 CI/CD,然后选择 Pipelines(管道)以查看管道的运行情况。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/10-gitlab10k.fe1a1a92c8d92ccca6ece3bdc4f07818dded22ab.png)
.gitlab-ci.yml 的第一部分定义阶段和阶段的执行顺序。管道将构建 Docker 镜像,对其执行单元测试,并在通过测试后发布镜像。
stages:
- build
- test
- release
构建阶段使用应用程序创建容器镜像。为此,管道在 Docker 容器中运行 Docker 来创建镜像。这是 Docker-in-Docker 服务 (dind)。
image: docker:latest
services:
- docker:dind
build_job 脚本定义任务:
- 登录 GitLab 注册表
- 从 Docker 文件构建镜像
- 设置镜像标签为 test
- 将镜像推送到 GitLab 镜像存储库
build_job:
stage: build
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker build --tag $CI_REGISTRY_IMAGE:test .
- docker push $CI_REGISTRY_IMAGE:test
请注意,脚本使用 GitLab 预定义的变量,其中包含触发管道时脚本所需的管道或作业的值。GitLab 提供了预定义变量的引用。
您可以点击 Stages(阶段)下的蓝色图标,查看阶段的进度。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/11-gitlab10k.cd1baa40863edbc542de3bd5b8f75a989ea1bb51.png)
选择 build_job,查看构建日志。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/12-gitlab10k.1177fdb7b6873306a89e82b0734f90116e7253b2.png)
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/13-gitlab10k.d05bec75cf0e339407c9259e1e12ebecca98cc35.png)
管道完成构建测试容器时,将其推送到 GitLab 容器注册表。
构建阶段完成后,管道对测试容器运行单元测试。在该阶段,从容器注册表拉取测试镜像并运行测试脚本。
test_job:
stage: test
script:
- docker pull $CI_REGISTRY_IMAGE:test
- docker run $CI_REGISTRY_IMAGE:test /app/test.py
如果容器通过单元测试,运行器将记录测试结果和任何其他输出。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/14-gitlab10k.e6f37601204050bda87d7551bd8de0c395bb1ebb.png)
管道中的最后一个阶段是发布阶段。在该阶段,从容器注册表中拉取测试镜像并设置标签为 latest。
release_job:
stage: release
script:
- docker login -u "GITLAB-CI-TOKEN" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:test
- docker tag $CI_REGISTRY_IMAGE:test $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
发布镜像将推送到 Container Registry(容器注册表)。
![](https://d1.awsstatic.com/guoheng/continuous-integration-with-gitlab-at-10000-feet/15-gitlab10k.5206d6d9cd4ee81d157f8c0fb608b3322ea742f2.png)
管道的 CI 部分已经完成,可以将发布构件部署到生产环境中了。
总结
通过展示管道中的每个阶段,我们了解了持续集成如何自动实现软件交付流程。开发人员可以通过提交更改来启动流程,代码在通过各个阶段时会自动进行构建和测试。在构建过程中整合测试环节,有助于在将软件确认为发布候选版本之前,检测出潜在的错误和回归。持续集成是 DevOps 的一个重要工具,有助于组织快速交付高质量的软件。
如果您想了解有关 DevOps 的更多信息,请查看什么是 DevOps;如果您想设置 GitLab,可以动手试试一个 DevOps 现代化研讨会。