如何在同一实例中运行Gitlab CI作业



我已经在AWS点实例上自动缩放了gitlab-runner。它工作得很好。

在运行作业时我有一个问题。下面是我的.gitlab-ci.yml,它有两个阶段。

stages:
- build
- dev1:build
build:
stage: build
script: 
- docker build --rm -t broker-connect-dev1-${CI_COMMIT_SHORT_SHA} -f BrokerConnect/Dockerfile .
only:
- dev1/release
tags:
- itela-spot-runner     
build-dev1:
stage: dev1:build
script: 
- docker tag broker-connect-dev1-${CI_COMMIT_SHORT_SHA}:latest 19950818/broker-connect:${DEV1_TAG} 
only:
- dev1/release
tags:
- itela-spot-runner  

问题来了,因为我使用现场实例来运行作业,有时build阶段发生在一个现场实例中,dev1:build阶段发生在另一个现场实例中。当发生这种情况时,dev1:build会失败,因为它找不到映像broker-connect-dev1-${CI_COMMIT_SHORT_SHA},因为它是在单独的spot实例中构建的。在gitlab,或在gitlab-runner,有没有一种方法来控制这种行为,并运行这两个作业builddev1:build在同一个点实例?

我和你有同样的问题。在gitlabci中没有真正的解决方案来满足这种需求,因为解决方案被设计为与"perennial"一起工作。跑步者并不是"短暂的";例如AWS SPOT。对于一个常年跑步者来说,这个问题不会出现,因为"阶段"。接下来的步骤可以重用前面"阶段"所做的配置。在同一台机器上

在我的情况下,我发现了两种可能的解决方法

  1. 重现步骤(在我公司实施)这种方法包括再现我们在以前的"课程"中已经做过的动作。优点:团队不会迷失在管道GUI中,并且可以看到每个"阶段"。作为一项单独的工作缺点:我们在部署期间花费了更多的时间,因为最后一个"阶段"的最后一个工作;在它使用的运行器上重新执行前一个作业的所有操作下面是一个代码示例来说明解决方案(使用!reference系统)
.scriptCheckHelm: 
script: 
- 'helm dependency build'
- 'helm lint .'

stages: 
- lint
- build
Check_Conf: 
stage: 'lint' 
script:
- !reference [.scriptCheckHelm, script]
rules: 
- if: '($CI_PIPELINE_SOURCE == "push")'
when: 'always'
allow_failure: false
extends: .tags
Build_Package:
stage: 'build'
script:
- !reference [.scriptCheckHelm, script]
- 'helm package .'
rules:
- if: '($CI_PIPELINE_SOURCE == "push")&&($CI_COMMIT_TITLE == "DEPLOYMENT")'
when: 'on_success'
allow_failure: false
extends: .tags

在这种情况下,当我们以标题"DEPLOYMENT"提交时,我们有:具有多个作业的PIPELINE

  1. 运行单个作业此方法包括将单个作业中的所有操作分组优点:在部署期间没有时间损失,运行程序一个接一个地执行所有操作缺点:用户只能看到一个作业,并且必须查看作业日志来识别错误
.scriptCheckHelm: 
script: 
- 'helm dependency build'
- 'helm lint .'

stages: 
- lint
- build
Check_Conf: 
stage: 'lint' 
script:
- !reference [.scriptCheckHelm, script]
rules: 
- if: '($CI_PIPELINE_SOURCE == "push")&&($CI_COMMIT_TITLE != "DEPLOYMENT")'
when: 'always'
allow_failure: false
extends: .tags
Build_Package:
stage: 'build'
script:
- !reference [.scriptCheckHelm, script]
- 'helm package .'
rules:
- if: '($CI_PIPELINE_SOURCE == "push")&&($CI_COMMIT_TITLE == "DEPLOYMENT")'
when: 'on_success'
allow_failure: false
extends: .tags

在这种情况下,当我们以标题"DEPLOYMENT"提交时,我们有:有1个作业的PIPELINE

控制哪些作业在哪些运行器上运行的最佳方法是使用标记。您可以将运行器标记为builds-images,然后在构建映像的任何作业上,或者需要使用前一步构建的映像,使用相同的标记。

例如:

stages:
- build
- dev1:build
build:
stage: build
script: 
- docker build --rm -t broker-connect-dev1-${CI_COMMIT_SHORT_SHA} -f BrokerConnect/Dockerfile .
only:
- dev1/release
tags:
- itela-spot-runner
- builds-images   
build-dev1:
stage: dev1:build
script: 
- docker tag broker-connect-dev1-${CI_COMMIT_SHORT_SHA}:latest 19950818/broker-connect:${DEV1_TAG} 
only:
- dev1/release
tags:
- itela-spot-runner
- builds-images

现在你只需要一个(或多个)带有builds-images标签的跑步者。如果你正在使用gitlab.com或者是自托管的,并且至少有Gitlab 13.2版本,你可以在项目的跑步者页面编辑跑步者的详细信息(详细信息在这里:https://docs.gitlab.com/ee/ci/runners/#view-and-manage-group-runners)。否则,可以在注册跑步者时设置标签。对于您的用例,无需进一步更改.gitlab-ci。在yml文件中,我只标记一个跑步者。

另一种选择是将构建的映像推送到docker hub (https://docs.docker.com/docker-hub/), Gitlab的注册表(https://docs.gitlab.com/ee/user/packages/container_registry/)或其他可以支持docker映像的注册表(https://aws.amazon.com/ecr/)。然后在任何需要该映像的作业中,将其从注册表中拉下来并使用它。

例如:

stages:
- build
- dev1:build
build:
stage: build
before_script:
- docker login [registry_url] #...
script: 
- docker build --rm -t broker-connect-dev1-${CI_COMMIT_SHORT_SHA} -f BrokerConnect/Dockerfile .
- docker push broker-connect-dev1-${CI_COMMIT_SHORT_SHA}
only:
- dev1/release
tags:
- itela-spot-runner     
build-dev1:
stage: dev1:build
before_script:
- docker login [registry_url] #...
script: 
- docker pull broker-connect-dev1-${CI_COMMIT_SHORT_SHA}
- docker tag broker-connect-dev1-${CI_COMMIT_SHORT_SHA}:latest 19950818/broker-connect:${DEV1_TAG} 
only:
- dev1/release
tags:
- itela-spot-runner