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

如何仅启动一次服务并在多个GitLab CI/CD作业中复用

问题解答

你期望的那种直接把一个作业作为服务给其他测试作业复用的方式不可行,因为GitLab CI的每个作业都是独立运行在各自的执行环境中(比如独立的Docker容器或虚拟机),作业之间默认完全隔离,而且services字段仅支持指定Docker镜像,不能引用其他作业。

不过你可以通过以下几种方案实现“一次启动服务,多测试作业复用”的需求:

方案1:使用外部测试环境部署服务

把慢启动的服务部署到一个独立的外部环境(比如K8s集群、云虚拟机或专用测试服务器),启动作业负责部署/启动服务,测试作业通过环境变量获取服务地址并连接。这种方案最可靠,也能避免runner资源冲突。

示例配置:

stages:
  - deploy-service
  - test

# 部署慢启动服务到外部环境
deploy-slow-service:
  stage: deploy-service
  script:
    - # 执行部署命令,比如用kubectl部署到K8s,或启动云服务器上的服务
    - # 获取服务访问地址,例如:
    - SERVICE_URL=$(kubectl get svc slow-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}:8080')
    - echo "SERVICE_URL=$SERVICE_URL" > service.env
  artifacts:
    reports:
      dotenv: service.env
    expire_in: 1h # 工件有效期设为1小时,避免占用存储

# 测试套件1,可单独重跑
test-suite-1:
  stage: test
  needs: [deploy-slow-service]
  script:
    - # 运行测试套件1的命令,例如:
    - pytest tests/suite1/ --service-url $SERVICE_URL

# 测试套件2,可单独重跑
test-suite-2:
  stage: test
  needs: [deploy-slow-service]
  script:
    - pytest tests/suite2/ --service-url $SERVICE_URL

# 其余18个测试套件作业依此类推...

方案2:使用专用Runner复用本地服务

如果没有外部测试环境,可以指定一个专用的GitLab Runner(比如用Shell executor),让服务直接运行在Runner宿主机上,后续测试作业都用这个Runner连接本地服务。

示例配置:

stages:
  - start-service
  - test
  - stop-service

# 启动慢服务,指定专用Runner
start-slow-service:
  stage: start-service
  tags:
    - dedicated-slow-service-runner # 标记专用Runner
  script:
    - # 启动服务并后台运行
    - nohup ./path/to/slow-service --port 8080 > service.log 2>&1 &
    - # 记录服务进程ID,用于后续停止
    - echo $! > service.pid
  artifacts:
    paths:
      - service.pid
      - service.log
    expire_in: 1h

# 测试套件1,必须使用同一个专用Runner
test-suite-1:
  stage: test
  tags:
    - dedicated-slow-service-runner
  needs: [start-slow-service]
  script:
    - curl http://localhost:8080/health-check
    - pytest tests/suite1/

# 其余测试套件作业同样标记专用Runner...

# 无论测试成功/失败,都停止服务
stop-slow-service:
  stage: stop-service
  tags:
    - dedicated-slow-service-runner
  needs: [test-suite-1, test-suite-2, ...] # 依赖所有测试作业
  when: always
  script:
    - kill $(cat service.pid) || true

注意事项

  • 方案2中,专用Runner必须设置为单并发,避免多个流水线同时启动服务导致端口冲突。
  • 如果服务有状态,建议每个测试套件运行前执行重置操作(比如调用服务的重置API),避免测试之间互相干扰。
  • 方案1的扩展性更好,适合团队协作,不会因为Runner资源限制影响流水线运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:55:26