如何使用彼此独立的不同运行器运行 Gitlab CI 作业?

Posted

技术标签:

【中文标题】如何使用彼此独立的不同运行器运行 Gitlab CI 作业?【英文标题】:How to run the Gitlab CI jobs with different runners independent from each other? 【发布时间】:2021-11-17 08:14:41 【问题描述】:

说明

正如我从 this *** question 和 Gitlab-CI official documentation 中发现的那样,通过使用 tags 关键字,可以为单个项目触发不同的运行器。所以我在我的服务器上注册了不同的运行器(每个(暂存和生产)服务器一个运行器),带有dashboard_stagingdashboard_production 标签名称。

一切正常,为了正确启动 gitlab-runner,我执行了以下命令:

sudo gitlab-runner verify  # Everything was ok
sudo gitlab-runner start  # It was started successfully on both servers

然后我已经提交了更改并将它们推送到 Gitlab 上并成功触发。

问题

    我已执行上述命令,但其中一条管道仍在等待运行器。

    由于build 阶段尚未完全完成,因此其工作已完成的标签不会继续。

代码

stages:
  - test
  - build
  - deploy

cache:
  untracked: true
  key:
    files:
      - yarn.lock
  paths:
    - node_modules/
    - .yarn

dashboard:test:staging:
  stage: test
  tags:
    - dashboard_staging
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:test:production:
  stage: test
  tags:
    - dashboard_production
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:build:staging:
  stage: build
  tags:
    - dashboard_staging
  only:
    - staging
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"

dashboard:build:production:
  stage: build
  tags:
    - dashboard_production
  only:
    - staging
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"


dashboard:deploy:staging:
  stage: deploy
  tags:
    - dashboard_staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"


dashboard:deploy:production:
  stage: deploy
  tags:
    - dashboard_production
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"

问题

如何在Deploy 阶段解决这个待处理的问题?

有没有办法让定义的标签彼此独立运行?

【问题讨论】:

【参考方案1】:

如果我正确理解了您的需求,您希望“暂存”作业独立于“生产”作业运行,并忽略同一阶段的其他作业可能尚未完成的事实。

这就是 needs 关键字的用途 (reference)。由于您尚未在作业中定义任何 needs 关键字,因此每个作业将等待整个先前的 stage 完成后再开始。 GitLab CI 的默认行为是并行运行一个阶段内的所有作业,然后依次运行每个阶段。然后,您可以使用 needs 关键字覆盖它,以独立于它们所处的阶段启动作业。

尝试以下方法:

stages:
  - test
  - build
  - deploy

cache:
  untracked: true
  key:
    files:
      - yarn.lock
  paths:
    - node_modules/
    - .yarn

dashboard:test:staging:
  stage: test
  tags:
    - dashboard_staging
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:test:production:
  stage: test
  tags:
    - dashboard_production
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:build:staging:
  stage: build
  tags:
    - dashboard_staging
  only:
    - staging
  needs: ["dashboard:test:staging"]
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"

dashboard:build:production:
  stage: build
  tags:
    - dashboard_production
  only:
    - staging
  needs: ["dashboard:test:production"]
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"


dashboard:deploy:staging:
  stage: deploy
  tags:
    - dashboard_staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  needs: ["dashboard:build:staging"]
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"


dashboard:deploy:production:
  stage: deploy
  tags:
    - dashboard_production
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  needs: ["dashboard:build:production"]
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"

【讨论】:

你知道为什么我的一个跑步者不能正常工作吗?所有步骤都一样。 除了“工作不正常”之外,您还有更多信息吗?您看到什么错误消息?它应该根据您显示两个跑步者的绿色状态的屏幕截图以及与您在 CI 中拥有的标签匹配的标签来挑选工作。我也不知道您要使用哪种类型的跑步者-他们是码头跑步者吗?壳跑者? Shell runners.There没有任何错误但它没有被触发。 当您单击这些作业时,它们是否只是处于待处理状态并被列为“卡住”?如果是这样,您将需要通读运行器输出的日志。如果您可以发布跑步者日志的样子,我可能会提供更多帮助。不过,它与这个问题无关 - 问题出在你的跑步者身上,而不是你的 CI 脚本。 我明白了,所以这不是关卡完成的问题,而是其中一项工作从未接手的问题。假设它被列为“卡住”,则其中一个跑步者配置不正确。如果您可以发布运行器日志,那么我可以帮助解决更多问题。【参考方案2】:

我将发布有关我的问题和疑问如何解决的详细信息,以供未来的读者阅读。

问题 1:如何在 Deploy 阶段解决这个待解决的问题?

答案 1

执行以下三个命令后,这个问题就解决了:

sudo gitlab-runner verify
sudo gitlab-runner start
sudo gitlab-runner run

PS如果你是非root用户并且想在不使用sudo的情况下执行gitlab-runner(使用你的用户权限,你可以通过usermod -aG sudo gitlab-runner命令轻松地将gitlab-runner添加到sudoers。)

更多详情,您可以访问以下链接:

Gitlab CI/CD: New runner has not been connected yet GitLab CI builds remains pending

问题 2:有没有办法让定义的标签彼此独立运行?

答案 2: 正如@Patrick 所提到的,在 gitlab-ci yaml 文件中存在一个名为 needs 的标签,它完全可以按预期工作。

stages:
  - test
  - build
  - deploy

cache:
  untracked: true
  key:
    files:
      - yarn.lock
  paths:
    - node_modules/
    - .yarn

dashboard:test:staging:
  stage: test
  tags:
    - dashboard_staging
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:test:production:
  stage: test
  tags:
    - dashboard_production
  when: manual
  before_script:
    - echo "do sth"
  only:
    - staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  script:
    - echo "do sth"

dashboard:build:staging:
  stage: build
  tags:
    - dashboard_staging
  only:
    - staging
  needs: ["dashboard:test:staging"]
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"

dashboard:build:production:
  stage: build
  tags:
    - dashboard_production
  only:
    - staging
  needs: ["dashboard:test:production"]
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  
  script:
    - echo "do sth"


dashboard:deploy:staging:
  stage: deploy
  tags:
    - dashboard_staging
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  needs: ["dashboard:build:staging"]
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"


dashboard:deploy:production:
  stage: deploy
  tags:
    - dashboard_production
  except:
    changes:
      - 'docker/**/*'
      - '*.md'
  only:
    - staging
  needs: ["dashboard:build:production"]
  before_script:
    - echo "do sth"
  script:
    - echo "do sth"

有关更多信息,您可以阅读official documentation of Gitlab CI。

【讨论】:

以上是关于如何使用彼此独立的不同运行器运行 Gitlab CI 作业?的主要内容,如果未能解决你的问题,请参考以下文章

GitLab 多个运行器,交换工件

gitlab-ci 运行器中具有不同到期时间的多条路径

如何在 Gitlab CI shell 运行器上构建失败

如何为 Gitlab 运行器启用通过 SSH 克隆?

如何使用 docker executor 在同一个 gitlab 运行器上禁用并发作业?

如何为 GitLab CI 运行器启用 Maven 工件缓存?