GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 GitLab CI 配置文件(.gitlab-ci.yml)定义的任务。无论是简单的测试脚本还是复杂的部署流程,GitLab Runner 都能高效地完成相关工作。本文将详细介绍 GitLab Runner 的基本概念、功能特点、使用方法,并深入探讨其在流水线缓存(以 Python 项目为例)和构建镜像方面的应用,特别是在 Kubernetes(K8s)环境中的使用。
一、什么是 GitLab Runner
GitLab Runner 是一个开源项目,用于在不同的环境中运行 GitLab CI/CD 管道中的作业。它可以安装在多种操作系统上,并支持多种执行方式,如 Shell、Docker、Kubernetes 等。通过配置不同的执行器,用户可以根据项目需求灵活选择最合适的运行环境。
二、流水线缓存(Pipeline Cache)
在 CI/CD 流水线中,频繁的下载依赖和构建步骤可能会消耗大量时间。GitLab Runner 提供了缓存机制,能够缓存某些文件或目录,供后续作业使用,从而加快流水线的执行速度。以下以 Python 项目构建为例,展示如何配置流水线缓存。
需要注意的是:在一个代码项目中,构建容器会产生两个挂载目录。
一个是存储仓库项目源码与构建产生的文件,一个是设置的缓存目录 key/cache.zip,就是产生的缓存文件,那么对于重复可利用的文件,就可放入到你设置的目录中,在后续的作业中引用该目录即可。
1. 为什么使用缓存
在没有缓存的情况下,每次流水线运行都会重新创建虚拟环境并安装所有依赖,这不仅耗时还增加了构建失败的风险。通过缓存 venv/
和 .cache/pip/
目录,可以显著减少依赖安装的时间,因为这些文件在第一次构建后会被保存并在后续构建中重用。
2. 使用与不使用缓存的时间对比
为了直观展示缓存的效果,假设有一个中等规模的 Python 项目,包含多个依赖包。以下是使用缓存与不使用缓存的构建时间对比:
场景 |
依赖安装时间 |
总构建时间 |
不使用缓存 |
120 秒 |
180 秒 |
使用缓存 |
30 秒 |
90 秒 |
时间节省 |
75% |
50% |
3. 配置缓存
在 .gitlab-ci.yml
中,通过 cache
关键字配置需要缓存的路径。例如,缓存 Python 项目的 venv
目录和 pip 缓存:以下为gitlab官方示例
image: python:latest # Change pip's cache directory to be inside the project directory since we can # only cache local items. variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" ##https://pip.pypa.io/en/stable/topics/caching/ cache: paths: - .cache/pip before_script: - python --version ; pip --version # For debugging - pip install virtualenv - virtualenv venv run: script: - pip install . # run the command here a artifacts: paths: - build/* deploy: stage: deploy script: echo "Define your deployment script!" environment: production
2. 解释
- key:使用
$CI_COMMIT_REF_SLUG
作为缓存键,确保不同分支或标签有独立的缓存,防止依赖冲突。 - paths:指定需要缓存的目录,如
venv/
和.cache/pip/
,以加快后续作业的依赖安装速度。
3. 缓存策略
GitLab 提供多种缓存策略,可以根据项目需求和基础设施选择最合适的方案:
- local:缓存存储在 Runner 本地,对于单 Runner 或低频次的流水线适用。
- s3:使用 Amazon S3 作为缓存存储,适合分布式 Runner 环境。也可使用阿里云OSS作为缓存
- gcs:使用 Google Cloud Storage 作为缓存存储,适合云环境的 CI/CD 流水线。
在 Kubernetes 环境中,可以结合对象存储服务(如 S3、GCS)配置缓存,提升缓存的可用性和访问速度。
4. 示例:Python 项目构建
完整的 .gitlab-ci.yml
示例:
stages: - setup - test - build variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" cache: key: "$CI_COMMIT_REF_SLUG" paths: - venv/ - .cache/pip/ setup_job: stage: setup image: python:3.9 script: - python3 -m venv venv - source venv/bin/activate - pip install --upgrade pip - pip install -r requirements.txt test_job: stage: test image: python:3.9 script: - source venv/bin/activate - pytest build_job: stage: build image: python:3.9 script: - source venv/bin/activate - python setup.py sdist bdist_wheel artifacts: paths: - dist/
在这个示例中:
- setup_job:创建虚拟环境并安装依赖,缓存
venv/
和 pip 缓存目录.cache/pip/
。 - test_job:使用缓存的虚拟环境运行测试,避免重复安装依赖。
- build_job:构建 Python 包,并使用
artifacts
存储构建产物。
三、构建镜像(Building Images)
在现代应用开发中,容器化已成为主流趋势。GitLab Runner 支持在流水线中构建 Docker 镜像,并将其推送到镜像仓库。通常在集群中构建镜像有两种方式,Docker in Docker或者Kaniko,而后者更加高效,故以下步骤展示如何在 Gitlab runner的Kubernetes 环境中使用Kaniko构建和推送 Docker 镜像。
1. 使用 k8s 执行器
要在流水线中使用 集群,首先需要将 Runner 的执行器类型设置为 kubernates。在 Kubernetes 环境中,推荐使用 kaniko方式,允许在 Runner Pod 中运行 Docker 服务。
2. 配置 Runner
在 GitLab Runner 的 config.toml
文件中,配置 Docker 执行器和 DinD 服务。例如:
[[runners]] name = "k8s-runner" token = "YOUR_REGISTRATION_TOKEN" executor = "kubernetes" [runners.kubernetes] namespace = "{{.Release.Namespace}}" cpu_limit = "2" cpu_request = "2" memory_limit = "4Gi" memory_request = "4Gi" pod_labels_overwrite_allowed = ".*" [runners.kubernetes.pod_labels] "alibabacloud.com/compute-qos" = "best-effort" "alibabacloud.com/compute-class" = "general-purpose" "alibabacloud.com/eci" = "true"
- cpu_request:Job调度时申请的Pod的CPU核数
- memory_request:Job调度时申请的Pod的内存限制
- runners.kubernetes.pod_labels:Pod上具有的一些标签,如在阿里云ACK中运行时可申请性价比最高的Pod。
3. 编写构建镜像的作业
在 .gitlab-ci.yml
中定义构建和推送 Docker 镜像的作业。例如:
stages: # List of stages for jobs, and their order of execution - build - test - deploy variables: KUBERNETES_POD_LABELS_1: "alibabacloud.com/compute-class=general-purpose" KUBERNETES_POD_LABELS_2: "alibabacloud.com/compute-qos=best-effort" build-job: # This job runs in the build stage, which runs first. stage: build cache: key: test paths: - target/ image: name: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/kaniko-executor:v1.21.0-amd64-debug entrypoint: [""] script: - echo "{\"auths\":{\"${ACR_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - /kaniko/executor --context "$CI_PROJECT_DIR" --dockerfile "$CI_PROJECT_DIR/Dockerfile" --destination ${ACR_REGISTRY}:latest --cache=true
4. 安全认证
为了确保镜像推送的安全性,需要在 GitLab 的项目设置中配置以下变量:
- CI_REGISTRY_USER:镜像仓库的用户名。
- CI_REGISTRY_PASSWORD:镜像仓库的密码或访问令牌。
- ACR_REGISTRY:仓库地址
这些变量可在项目的 Settings > CI/CD > Variables 中配置,并确保设置为 Protected,避免在非受保护分支泄露。
5. 详细解释
- variables:定义镜像名称变量,便于重复使用。里面可定义Pod的标签
- build-job:
- 从项目中取出变量进行替换,如CI_REGISTRY_USER等
- 基于替换后的变量登录到阿里云镜像仓库。
- /kaniko/executor:调用Kaniko进行镜像构建,并使用层缓存
- 如果这个时候是通过Maven构建,那么同样可以将相关的Jar包依赖缓存下来,减少流水线执行时间。
- 以下是使用了Kaniko层级缓存和未使用缓存的对比效果图。
- 使用了缓存后,构建时间缩短为不足原来的一半,这个是个小项目,如果是更大型镜像的构建,那么可优化的时间则会更多。
7. 完整示例
完整的 .gitlab-ci.yml
配置如下:
stages: # List of stages for jobs, and their order of execution - build - test - deploy variables: KUBERNETES_POD_LABELS_1: "alibabacloud.com/compute-class=general-purpose" KUBERNETES_POD_LABELS_2: "alibabacloud.com/compute-qos=best-effort" build-job: # This job runs in the build stage, which runs first. stage: build cache: key: test paths: - target/ image: name: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/kaniko-executor:v1.21.0-amd64-debug entrypoint: [""] script: - echo "{\"auths\":{\"${ACR_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - /kaniko/executor --context "$CI_PROJECT_DIR" --dockerfile "$CI_PROJECT_DIR/Dockerfile" --destination ${ACR_REGISTRY}:latest --cache=true unit-test-job: # This job runs in the test stage. stage: test # It only starts when the job in the build stage completes successfully. script: - echo "Running unit tests... This will take about 60 seconds." - sleep 60 - echo "Code coverage is 90%" lint-test-job: # This job also runs in the test stage. stage: test # It can run at the same time as unit-test-job (in parallel). script: - echo "Linting code... This will take about 10 seconds." - sleep 10 - echo "No lint issues found." deploy-job: # This job runs in the deploy stage. stage: deploy # It only runs when *both* jobs in the test stage complete successfully. environment: production script: - echo "Deploying application..." - echo "Application successfully deployed."
四、总结
GitLab Runner 是 GitLab CI/CD 流水线的执行引擎,具备强大的功能和灵活的配置能力。在 Kubernetes 环境下部署 GitLab Runner,可以充分利用 Kubernetes 的扩展性和管理能力,实现 Runner 的自动伸缩和高可用性。通过合理配置流水线缓存(以 Python 项目为例)和构建镜像,能够显著提升 CI/CD 流水线的效率和可靠性。无论是小型项目还是大型企业级应用,GitLab Runner 在 Kubernetes 上的应用都能提供稳健的支持,助力开发团队实现持续集成与持续交付的目标。
五、一键部署
部署流程
- 访问计算巢 部署链接,按提示填写部署参数
- 填写是否新建或选择已有的集群
- 填写Helm配置
- 第一个参数为该Helm应用运行的命名空间,默认值为gitlab runner
- 第二个参数为Chart values,即Helm应用运行是要的参数。注意此处必须将内部参数的GitlabUrl和GitlabRunnerToken进行替换。
- GitlabUrl是您的Gitlab对外暴露的地址,GitlabRunnerToken为Gitlab处注册的runner的token,用于Gitlab和Runner进行认证,获取Token可参考下两图所示:
新建Runner
- 注册在Gitlab处成功创建好Runner的示意图如图所示,注意当前界面关闭后则无法再次查看Token:
- 默认配置的值中,concurrent为并发作业数量,如当前并未部署自己的Gitlab可以采用官方的地址,即填写:https://gitlab.com。
- 注意:Gitlab Runner的manager节点和被调度的job节点都工作在{{.Release.Namespace}}下,请不要对此项配置进行修改,否则会出现权限问题。
- 其他参数的调整可参考官方文档。
- 点击立即创建,等待服务实例部署完成
- 服务实例部署完成后,点击实例ID进入到详情界面,如图所示,提示已经部署成功
- 接下来就可以在原Gitlab中创建流水线和执行了
更多有意思,又好玩又有深度的服务,请访问计算巢网址