You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止单个GitLab项目的CI流水线并发执行?

解决GitLab单项目流水线并发冲突的方案

刚好碰到过类似的场景,针对你说的这个项目CI不能容忍流水线并发(存在Kubernetes外部副作用),但全局设置Runner的concurrent=1会影响其他项目的问题,这里有几个实用的解决方案,完全不影响其他项目的正常运行:

1. 项目级流水线并发限制(最省心的官方方案)

GitLab本身就支持在单个项目层面限制同时运行的流水线数量,步骤很简单:

  • 进入项目的 Settings > CI/CD > General pipelines 页面
  • 找到「Maximum concurrent pipelines」选项,把数值设为1
  • 保存之后,这个项目同一时间只会有一条流水线在执行,新推送触发的流水线会自动排队,等当前的跑完再启动

这个方法是官方推荐的,零脚本改动,对其他项目完全无干扰,优先推荐用这个。

2. 用resource_group控制特定Job的并发(更精细的控制)

如果不需要限制整个流水线,只是特定的阶段(比如部署Job)不能并发,可以用GitLab的resource_group功能,在.gitlab-ci.yml里给需要锁的Job加上这个配置:

deploy-to-k8s:
  stage: deploy
  script:
    - # 你的K8s部署脚本
  resource_group: project-deployment-lock

这样所有标记了resource_group: project-deployment-lock的Job,同一时间只会有一个在跑,其他同组的Job会进入等待队列,其他不涉及这个资源组的Job不受影响。

3. 自定义脚本实现排队逻辑(适配旧版本GitLab)

如果你的GitLab版本比较老,不支持上面两个功能,可以用自定义脚本结合CI变量来实现简单的排队机制:

  • 先在项目的CI/CD变量里创建一个PIPELINE_RUNNING变量,初始值设为false
  • 在流水线的第一个Job里加检查逻辑:
# 循环等待,直到没有正在运行的流水线
while [[ "$PIPELINE_RUNNING" == "true" ]]; do
  echo "当前有流水线在运行,等待30秒后重试..."
  sleep 30
  # 调用GitLab API拉取最新的变量值(需要CI_JOB_TOKEN有API权限)
  PIPELINE_RUNNING=$(curl --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/variables/PIPELINE_RUNNING" | jq -r '.value')
done

# 标记当前流水线为运行中
curl --request PUT \
  --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"value": "true"}' \
  "$CI_API_V4_URL/projects/$CI_PROJECT_ID/variables/PIPELINE_RUNNING"
  • 然后在流水线的最后一个Job(不管成功还是失败)里,把PIPELINE_RUNNING重置回false:
curl --request PUT \
  --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"value": "false"}' \
  "$CI_API_V4_URL/projects/$CI_PROJECT_ID/variables/PIPELINE_RUNNING"

注意:这个方法要确保CI Job有访问GitLab API的权限,还要处理好异常情况(比如流水线意外中断时,手动重置变量)。


内容的提问来源于stack exchange,提问作者Tobias Hermann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:58:56