Gitlab

需要安装docker并启动

安装gitlab-ce

常用命令

配置Gitlab

浏览器输入 http://<节点 IP>/, 访问 Gitlab。用户名root,密码Pa55w@rd登录 Gitlab。

配置中文:右上角头像 -> settings -> preferences -> localization -> language -> 简体中文 -> Save Changes

创建 gitlab-runner-test 仓库,配置 ssh public key,推送本地仓库到gitlab

配置 ssh public key,用于推送仓库:右上角头像 -> 设置 -> SSH秘钥

配置 kubernetes kubeconfig,用于连接到kubernetes集群:请参考与Kubernetes集群交互

安装runner

注册runner

在Gitlab的左上角 🔧 设置 - Runnners界面,可以获取 registration-token。

注册shell executor类型的 runner

注册禁用 TLS 的 docker executor 类型的 runner

要在 CI/CD 作业中运行 Docker 命令,您必须配置 GitLab Runner 以支持 docker 命令。此方法需要 privileged 模式。参考官方文档

此任务启用--docker-privileged。当您这样做时,您实际上是在禁用容器的所有安全机制并将您的主机暴露给特权升级。这样做会导致 container breakout。有关更多信息,请参阅有关运行时权限和 Linux 功能 的官方 Docker 文档。

常用命令

问题解决

运行gitlab-ci任务报错

GitLab Runner 在默认情况下可能会进行浅克隆(git clone --depth=50),git版本太低会报错,yum阿里云源里面最新的版本是1.18.3,升级 Git 即可。

Helm Chart 安装

此图表已经在 Google Kubernetes Engine 和 Azure 容器服务上进行了测试。 将 GitLab Runner 实例部署到 Kubernetes 集群的官方方法是使用gitlab-runner Helm chart。 此chart将 GitLab Runner 配置为:

添加 GitLab Helm 存储库:

配置 values.yaml 在gitlab查看注册token:

修改 templates/configmap.yaml,在# Start the runner 之前加如下代码:

部署k8s的时候有两个问题,其一是就是要配置k8s的config文件,以此来获得部署的权限。其二是k8s部署模板。 两个问题我用了一种解决方法,通过在k8s中创建configMap并挂载到runner执行器中的方式。

安装

附加配置

在 Helm Chart 0.23.0 中引入了配置模板。请参阅弃用问题

您可以使用配置模板文件 来配置运行器。您可以使用配置模板配置运行器上的任何字段,而无需让 Helm 图表了解特定的运行器配置选项。

这是在图表存储库的文件中找到values.yaml的默认设置的片段。重要的是要注意,对于该config:部分,格式应该是toml(<parameter> = <value>而不是<parameter>: <value>),因为我们要嵌入config.tomlvalues.yaml.

其余配置记录在values.yaml.

迁移到新的配置模板

在 Helm Chart 0.23.0 中引入了配置模板。请参阅弃用问题

该文件接受的许多字段values.yaml将随着 Helm Chart 1.0 版的引入而被删除。我们建议尽快远离它们。这些字段上方标有DEPRECATED:注释。

Kubernetes 执行器支持的所有配置选项都列在Kubernetes 执行器文档中。对于许多字段,中的旧名称与关键字values.yaml相同。对于某些,您必须重命名它们。例如,如果您使用设置 CPU 限制: helpers

现在您可以将它们设置为helper_cpu_limit. 确保您在该部分中使用toml格式(=而不是:config:

确保从values.yaml文件中注释或删除旧的配置值以避免冲突。

启用 RBAC 支持

如果您的集群启用了 RBAC,您可以选择让图表创建自己的服务帐户或自己提供一个

要让图表为您创建服务帐户,请设置rbac.create为 true:

要使用已经存在的服务帐户,请使用:

控制最大 Runner 并发数

部署在 Kubernetes 上的单个 GitLab Runner 能够通过自动启动额外的 Runner pod 来并行执行多个作业。该 concurrent设置 控制一次允许的最大 pod 数量,默认为10

使用 GitLab Runner 运行 Docker-in-Docker 容器

请参阅为运行器运行特权容器以了解如何启用它,以及关于运行 dind 的GitLab 运行器文档。

为跑步者运行特权容器

您可以告诉 GitLab Runner 使用特权容器运行。如果您需要在 GitLab CI/CD 作业中使用 Docker 可执行文件,则可能需要启用此功能。

这会带来一些风险,您可以在GitLab CI/CD Runner 文档中了解到这些风险 。

如果您可以接受这些风险,并且您的 GitLab Runner 实例是针对 GitLab 中您信任其 CI 作业的特定项目注册的,则可以在以下位置启用特权模式values.yaml

在没有特权模式的情况下构建容器的最佳实践

使用 Docker-in-Docker 在容器内构建容器需要 Docker 特权模式。谷歌的Kaniko是一种无需特权模式即可工作的替代方案,它已经在 Kubernetes GitLab Runner 上进行了测试。

GitLab 视频中使用 Kaniko 构建最小权限容器是Kaniko Docker 构建 工作示例项目的演练。它使用了 使用 Kaniko 和 GitLab CI/CD 构建图像的文档。

可以将工作示例项目复制到您自己的组或实例中进行测试。有关演示了哪些其他 GitLab CI 模式的更多详细信息,请访问项目页面Kaniko Docker Build

使用来自私有注册表的镜像

使用来自私有 registry 的镜像需要配置 imagePullSecrets。有关如何创建 imagePullSecrets 的更多详细信息,请参阅文档

注意格式。该值没有像 Kubernetes 资源中的惯例那样以“名称”标签为前缀。

提供用于访问 GitLab 的自定义证书

您可以向 GitLab Runner Helm Chart 提供Kubernetes Secret ,它将用于填充容器的 /home/gitlab-runner/.gitlab-runner/certs目录。

Secret 中的每个密钥名称将用作目录中的文件名,文件内容是与密钥关联的值:

GitLab Runner Helm Chart 不会为您创建秘密。为了创建秘密,您告诉 Kubernetes 将证书存储为秘密并将其作为文件提供给 GitLab Runner 容器。为此,请运行以下命令:

然后,您需要将密钥的名称提供给 GitLab Runner 图表。将以下内容添加到您的values.yaml

将 pod 标签设置为 CI 环境变量键

目前无法在values.yaml文件中使用环境变量作为 pod 标签。我们正在解决这个问题:Can't set environment variable key as pod label。使用问题中描述的解决方法作为临时解决方案。

将注册令牌或跑步者令牌存储在秘密中

要注册一个新的跑步者,您可以 runnerRegistrationToken在中指定values.yml。要注册现有的跑步者,您可以使用runnerToken. 将令牌存储在其中可能存在安全风险values.yml,尤其是当您将这些令牌提交给git.

相反,您可以将这些令牌的值存储在 Kubernetes secret中,然后使用 secret 的名称 更新其中的runners.secret值。values.yml

如果您有现有的注册跑步者并想使用它,请 runner-token使用用于识别该跑步者的令牌进行设置。如果你想注册一个新的跑步者,你可以设置你想要 runner-registration-token注册令牌

例如:

此示例使用 secretgitlab-runner-secret并采用 的值 runner-registration-token来注册新的跑步者。

切换到基于 Ubuntu 的gitlab-runnerDocker 镜像

默认情况下,GitLab Runner Helm Chart 使用gitlab/gitlab-runner图像的 Alpine 版本,它使用musl libc. 在某些情况下,您可能希望切换到基于 Ubuntu 的映像,它使用glibc.

为此,请values.yaml使用以下值更新您的文件:

GitLab CI 持续集成

从 GitLab 8.0 开始,GitLab CI 就已经集成在 GitLab 中,我们只要在项目中添加一个 .gitlab-ci.yml 文件,然后添加一个 Runner,即可进行持续集成。 而且随着 GitLab 的升级,GitLab CI 变得越来越强大,本文将介绍如何使用 GitLab CI 进行持续集成。

在介绍 GitLab CI 之前,我们先看看一些持续集成相关的概念。

概念

Pipeline

一次 Pipeline 其实相当于一次构建任务,里面可以包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程。 任何提交或者 Merge Request 的合并都可以触发 Pipeline,如下图所示:

Stages

Stages 表示构建阶段,说白了就是上面提到的流程。 我们可以在一次 Pipeline 中定义多个 Stages,这些 Stages 会有以下特点:

因此,Stages 和 Pipeline 的关系就是:

Jobs

Jobs 表示构建工作,表示某个 Stage 里面执行的工作。 我们可以在 Stages 里面定义多个 Jobs,这些 Jobs 会有以下特点:

所以,Jobs 和 Stage 的关系图就是:

GitLab Runner

理解了上面的基本概念之后,有没有觉得少了些什么东西 —— 由谁来执行这些构建任务呢? 答案就是 GitLab Runner 了!

想问为什么不是 GitLab CI 来运行那些构建任务? 一般来说,构建任务都会占用很多的系统资源 (譬如编译代码),而 GitLab CI 又是 GitLab 的一部分,如果由 GitLab CI 来运行构建任务的话,在执行构建任务的时候,GitLab 的性能会大幅下降。

GitLab CI 最大的作用是管理各个项目的构建状态,因此,运行构建任务这种浪费资源的事情就交给 GitLab Runner 来做拉! 因为 GitLab Runner 可以安装到不同的机器上,所以在构建任务运行期间并不会影响到 GitLab 的性能~

安装、注册 Runner

.gitlab-ci.yml

配置好 Runner 之后,我们要做的事情就是在项目根目录中添加 .gitlab-ci.yml 文件了。 当我们添加了 .gitlab-ci.yml 文件后,每次提交代码或者合并 MR 都会自动运行构建任务了。

还记得 Pipeline 是怎么触发的吗?Pipeline 也是通过提交代码或者合并 MR 来触发的! 那么 Pipeline 和 .gitlab-ci.yml 有什么关系呢? 其实 .gitlab-ci.yml 就是在定义 Pipeline 而已拉!

基本写法

我们先来看看 .gitlab-ci.yml 是怎么写的:

写起来很简单吧!用 stages 关键字来定义 Pipeline 中的各个构建阶段,然后用一些非关键字来定义 jobs。 每个 job 中可以可以再用 stage 关键字来指定该 job 对应哪个 stage。 job 里面的 script 关键字是最关键的地方了,也是每个 job 中必须要包含的,它表示每个 job 要执行的命令。

回想一下我们之前提到的 Stages 和 Jobs 的关系,然后猜猜上面例子的运行结果?

根据我们在 stages 中的定义,build 阶段要在 test 阶段之前运行,所以 stage:build 的 jobs 会先运行,之后才会运行 stage:test 的 jobs。

常用的关键字

下面介绍一些常用的关键字,想要更加详尽的内容请前往 官方文档

stages

定义 Stages,默认有三个 Stages,分别是 build, test, deploy

types

stages 的别名。

before_script

定义任何 Jobs 运行前都会执行的命令。

after_script

要求 GitLab 8.7+ 和 GitLab Runner 1.2+

定义任何 Jobs 运行完后都会执行的命令。

variables && Job.variables

要求 GitLab Runner 0.5.0+

定义环境变量。 如果定义了 Job 级别的环境变量的话,该 Job 会优先使用 Job 级别的环境变量。

cache && Job.cache

要求 GitLab Runner 0.7.0+

定义需要缓存的文件。 每个 Job 开始的时候,Runner 都会删掉 .gitignore 里面的文件。 如果有些文件 (如 node_modules/) 需要多个 Jobs 共用的话,我们只能让每个 Job 都先执行一遍 npm install。 这样很不方便,因此我们需要对这些文件进行缓存。缓存了的文件除了可以跨 Jobs 使用外,还可以跨 Pipeline 使用。

具体用法请查看 官方文档

Job.script

定义 Job 要运行的命令,必填项。

Job.stage

定义 Job 的 stage,默认为 test

Job.artifacts

定义 Job 中生成的附件。 当该 Job 运行成功后,生成的文件可以作为附件 (如生成的二进制文件) 保留下来,打包发送到 GitLab,之后我们可以在 GitLab 的项目页面下下载该附件。 注意,不要把 artifactscache 混淆了。

实用例子

下面给出一个我自己在用的例子:

上面的配置把一次 Pipeline 分成五个阶段:

设置 Job.only 后,只有当 develop 分支和 master 分支有提交的时候才会触发相关的 Jobs。 注意,我这里用 GitLab Runner 所在的服务器作为测试服务器。

参考资料

文章作者 scarletsky 上次更新 2019-04-30 (95a170d)

其他

.gitlab-ci 高级用法

语法详解

发布时间 2025-04-05 00:47:54

在GitLab CI中,Pipeline配置文件(.gitlab-ci.yml)是自动化构建与部署的核心。本文将深入讲解onlyexceptrulesworkflow的语法与使用场景,帮助开发者掌握Pipeline的创建规则与动态配置方法。


1. 限制分支与标签:onlyexcept

onlyexcept是GitLab CI中用于限制Pipeline作业运行的分支和标签的关键字。通过它们,可以精确控制Pipeline的触发条件。

1.1 only语法

only用于指定Pipeline作业仅在某些分支或标签上运行。例如:

上述配置表示该作业仅在master分支或任何标签上运行。

1.2 except语法

except用于排除某些分支或标签的运行。例如:

上述配置表示该作业在所有分支上运行,但排除develop分支。

1.3 示例:结合onlyexcept

以下示例展示了如何同时使用onlyexcept


2. 动态规则配置:rules

rules是GitLab CI中更灵活的规则配置方式,用于动态决定作业的运行条件。与onlyexcept相比,rules更加强大,支持条件判断、文件变化监听和文件存在检查。

2.1 if条件判断

if用于根据变量或环境条件决定作业的运行。例如:

上述配置表示,当提交分支为master时,作业为手动触发;否则,作业始终运行。

2.2 changes监听文件变化

changes用于监听特定文件或目录的变化。例如:

上述配置表示,当develop分支上的README.mdsrc目录下的.py文件发生变化时,作业将运行。

2.3 exists检查文件存在

exists用于检查特定文件是否存在。例如:

上述配置表示,当main分支上存在package.json文件时,作业将运行。

2.4 示例:综合使用rules

以下示例展示了如何综合使用ifchangesexists


3. 管道创建规则:workflow

workflow用于控制Pipeline的创建条件。通过rules中的ifwhen,可以灵活决定Pipeline的触发行为。

3.1 workflow语法

以下是一个简单的workflow配置示例:

上述配置表示,当提交分支为main时,Pipeline始终创建;否则,Pipeline不创建。

3.2 示例:结合workflowrules

以下示例展示了如何结合workflowrules实现更复杂的Pipeline控制:


4. 常见问题与解答(FAQ)

以下表格列出了关于onlyexceptrulesworkflow的常见问题及其解答:

问题答案
onlyexcept的区别是什么?only用于指定作业运行的分支或标签,except用于排除特定分支或标签的运行。
rules是否可以替代onlyexcept是的,rules功能更强大,可以完全替代onlyexcept
changesexists的区别是什么?changes用于监听文件变化,exists用于检查文件是否存在。
workflowwhen有哪些值?when支持alwaysnever两个值,分别表示始终创建和从不创建Pipeline。
如何实现手动触发的Pipeline?rules中设置when: manual即可实现手动触发。

5. onlyrules对比

以下表格对比了onlyrules的主要区别:

特性onlyrules
灵活性较低较高
条件判断不支持支持
文件变化监听不支持支持
文件存在检查不支持支持

6. 总结示例代码

以下是一个综合示例,展示了如何使用onlyexceptrulesworkflow配置Pipeline:

通过上述配置,可以实现灵活的Pipeline控制与动态作业触发。

trigger

显式调用

创建一个项目 manage_zz, 在里面写个 .gitlab-ci.yml 文件,内容如下

在另一个项目 LRUNWEB 的 .gitlab-ci.yml 里写上 trigger,内容如下

注意:如果是 trigger ,不需要加 tags 和 script。要不然会报错

运行 LRUNWEB 项目,查看流水线。可以看到,在运行 Deploy 阶段的时候,运行了下游的 manage_zz 项目。

当下游项目运行成功时, Deploy 阶段也就成功了。

img

点击下游的流水线 id (#27)跳转到下游项目,可以看到下游也触发了流水线

img

点击下游的流水线 id (#27)跳转到下游项目,可以看到下游也触发了流水线。

仅通过流水线触发

我们也可以在 manage_zz 项目里,加上 workflow,只有当上游触发的时候才会执行该 pipeline,其他情况下不会执行,加上下面的代码就可以了

触发同一项目

上面我们是触发不同项目之间的 ci,我们也可以在同一个项目下创建多个 ci 文件,然后去触发对应的 ci

创建两个目录,test1 和 test2,在两个目录下各创建一个 ci.yml 的文件

文件内容如下

在根项目的 .gitlab-ci.yml 里调用其他 ci 文件,如下

然后在去 test2 目录下新增一个文件,看会不会触发

我创建了一个 hello.go 文件

在去查看流水线

发现只有 build-test2 触发了 ci,因为我们只在 test2 目录下新增了 hello.go 文件,test1 目录下的文件没有改变,所以不会触发 build-test1 的 ci

与Kubernetes集群交互

1. 存储 kubeconfig

在 GitLab 管理中心 或项目的 Settings -> CI / CD -> Variables -> 展开 中,添加一个变量来存储你的 kubeconfig 文件。命名为 KUBECONFIG_CONTENT,这个变量存储你的 kubeconfig 的完整内容。

2. 配置 .gitlab-ci.yml

以下是一个 .gitlab-ci.yml 文件示例,展示如何使用 bitnami/kubectl 并加载 kubeconfig 来与 Kubernetes 集群进行交互:

docker-in-docker

使用 docker-dind 服务

挂载主机守护进程

在容器中使用docker命令,要在镜像内安装docker守护程序,要将主机的守护进程挂载到容器中。 例如,直接用户docker run方式启动的gitlab-runner可以这样挂载: -v /var/run/docker.sock:/var/run/docker.sock

在 Kubernetes 集群内的 gitlab CI 在构建镜像过程中,面临同样的问题。

gitlab-runner在Kubernetes里安装的方法可以通过官方提供的chart来用helm3安装。官方chart的仓库地址为:https://gitlab.com/gitlab-org/charts/gitlab-runner,但这里有个问题就是无法配置宿主机的挂载目录,

根据gitlab-runner在docker模式下挂载目录的方法,并且结合官方文档,做如下改动即可支持挂载目录,修改templates/configmap.yaml文件,在"# Start the runner"前面增加如下代码:

SonarQube

Helm Chart 安装

开发工具

python-gitlab

CLI examples

通过 gitlab 命令行访问

API examples

通过 python 访问

GitLab API

通过 curl 命令行访问