doc-locale/fr-fr/ci/resource_groups/_index.md
{{< details >}}
{{< /details >}}
Par défaut, les pipelines dans GitLab CI/CD s'exécutent de façon simultanée. La simultanéité est un facteur important pour améliorer la boucle de rétroaction dans les merge requests. Cependant, dans certaines situations, vous pouvez souhaiter limiter la simultanéité des jobs de déploiement afin de les exécuter un par un. Utilisez des groupes de ressources pour contrôler de façon stratégique la simultanéité des jobs et optimiser votre workflow de déploiement continu en toute sécurité.
Vous ne pouvez ajouter qu'une seule ressource à un groupe de ressources.
À condition que vous disposiez de la configuration de pipeline suivante (fichier .gitlab-ci.yml dans votre dépôt) :
build:
stage: build
script: echo "Your build script"
deploy:
stage: deploy
script: echo "Your deployment script"
environment: production
Chaque fois que vous poussez un nouveau commit vers une branche, un nouveau pipeline est exécuté avec deux jobs build et deploy. Mais si vous poussez plusieurs commits dans un court intervalle de temps, plusieurs pipelines commencent à s'exécuter simultanément, par exemple :
build -> deploybuild -> deployDans ce cas, les jobs deploy de différents pipelines pourraient s'exécuter simultanément dans l'environnement production. L'exécution de plusieurs scripts de déploiement sur la même infrastructure pourrait endommager ou perturber l'instance et la laisser dans un état corrompu dans le pire des cas.
Pour vous assurer qu'un job deploy s'exécute une seule fois à la fois, vous pouvez spécifier le mot-clé resource_group pour le job sensible à la simultanéité :
deploy:
# ...
resource_group: production
Avec cette configuration, la sécurité des déploiements est garantie, tout en vous permettant d'exécuter les jobs build de façon simultanée pour maximiser l'efficacité du pipeline.
Vous pouvez sélectionner un mode de traitement pour contrôler la simultanéité des jobs selon vos préférences de déploiement. Les modes suivants sont pris en charge :
| Mode de traitement | Description | Quand l'utiliser |
|---|---|---|
unordered | Le mode de traitement par défaut. Traite les jobs dès qu'un job est prêt à s'exécuter. | L'ordre d'exécution des jobs n'a pas d'importance. L'option la plus simple à utiliser. |
oldest_first | Lorsqu'une ressource est libre, sélectionne le premier job dans la liste des jobs à venir, triée par ID de pipeline dans l'ordre croissant. | Vous souhaitez exécuter les jobs du pipeline le plus ancien en premier. Moins efficace que le mode unordered, mais plus sûr pour les déploiements continus. |
newest_first | Lorsqu'une ressource est libre, sélectionne le premier job dans la liste des jobs à venir, triée par ID de pipeline dans l'ordre décroissant. | Vous souhaitez exécuter les jobs du pipeline le plus récent et empêcher les jobs de déploiement obsolètes. Chaque job doit être idempotent. |
newest_ready_first | Lorsqu'une ressource est libre, sélectionne le premier job dans la liste des jobs à venir en attente de cette ressource. Les jobs sont triés par ID de pipeline dans l'ordre décroissant. | Vous souhaitez empêcher newest_first de prioriser les nouveaux pipelines avant de déployer le pipeline actuel. Plus rapide que newest_first. Chaque job doit être idempotent. |
Pour modifier le mode de traitement d'un groupe de ressources, vous devez utiliser l'API et envoyer une requête pour modifier un groupe de ressources existant en spécifiant le paramètre process_mode :
unorderedoldest_firstnewest_firstnewest_ready_firstConsidérez le fichier .gitlab-ci.yml suivant, qui contient un job build et un job deploy. Chaque job s'exécute dans sa propre étape, et le job deploy dispose d'un groupe de ressources défini sur production :
build:
stage: build
script: echo "Your build script"
deploy:
stage: deploy
script: echo "Your deployment script"
environment: production
resource_group: production
Si trois commits sont poussés vers le projet dans un court intervalle de temps, cela signifie que trois pipelines s'exécutent presque simultanément :
build -> deploy. Appelons ce job de déploiement deploy-1.build -> deploy. Appelons ce job de déploiement deploy-2.build -> deploy. Appelons ce job de déploiement deploy-3.Selon le mode de traitement du groupe de ressources :
unordered :
deploy-1, deploy-2 et deploy-3 ne s'exécutent pas simultanément.deploy-1 pourrait s'exécuter avant ou après deploy-3.oldest_first :
deploy-1, deploy-2 et deploy-3 ne s'exécutent pas simultanément.deploy-1 s'exécute en premier, deploy-2 s'exécute en deuxième et deploy-3 s'exécute en dernier.newest_first :
deploy-1, deploy-2 et deploy-3 ne s'exécutent pas simultanément.deploy-3 s'exécute en premier, deploy-2 s'exécute en deuxième et deploy-1 s'exécute en dernier.Vous pouvez définir resource_group pour les pipelines downstream sensibles aux exécutions simultanées. Le mot-clé trigger peut déclencher des pipelines downstream et le mot-clé resource_group peut coexister avec lui. resource_group est efficace pour contrôler la simultanéité des pipelines de déploiement, tandis que les autres jobs peuvent continuer à s'exécuter de façon simultanée.
L'exemple suivant présente deux configurations de pipeline dans un projet. Lorsqu'un pipeline commence à s'exécuter, les jobs non sensibles sont exécutés en premier et ne sont pas affectés par les exécutions simultanées dans d'autres pipelines. Cependant, GitLab s'assure qu'aucun autre pipeline de déploiement n'est en cours d'exécution avant de déclencher un pipeline de déploiement (enfant). Si d'autres pipelines de déploiement sont en cours d'exécution, GitLab attend que ces pipelines se terminent avant d'en exécuter un autre.
# .gitlab-ci.yml (parent pipeline)
build:
stage: build
script: echo "Building..."
test:
stage: test
script: echo "Testing..."
deploy:
stage: deploy
trigger:
include: deploy.gitlab-ci.yml
strategy: mirror
resource_group: AWS-production
# deploy.gitlab-ci.yml (child pipeline)
stages:
- provision
- deploy
provision:
stage: provision
script: echo "Provisioning..."
deployment:
stage: deploy
script: echo "Deploying..."
environment: production
Vous devez définir trigger:strategy pour vous assurer que le verrou n'est pas libéré avant la fin du pipeline downstream.
Étant donné que le mode de traitement oldest_first impose l'exécution des jobs dans l'ordre du pipeline, il existe des cas où il ne fonctionne pas correctement avec d'autres fonctionnalités CI.
Par exemple, lorsque vous exécutez un pipeline enfant qui nécessite le même groupe de ressources que le pipeline parent, un interblocage peut se produire. Voici un exemple de configuration incorrecte :
# BAD
test:
stage: test
trigger:
include: child-pipeline-requires-production-resource-group.yml
strategy: mirror
deploy:
stage: deploy
script: echo
resource_group: production
environment: production
Dans un pipeline parent, le job test est exécuté, ce qui déclenche ensuite un pipeline enfant. L'option strategy: mirror fait attendre le job test jusqu'à ce que le pipeline enfant se soit terminé. Le pipeline parent exécute le job deploy dans l'étape suivante, qui nécessite une ressource du groupe de ressources production. Si le mode de traitement est oldest_first, les jobs des pipelines les plus anciens sont exécutés en premier, ce qui signifie que le job deploy est exécuté ensuite.
Cependant, un pipeline enfant nécessite également une ressource du groupe de ressources production. Étant donné que le pipeline enfant est plus récent que le pipeline parent, le pipeline enfant attend que le job deploy se termine, ce qui n'arrive jamais.
Dans ce cas, vous devriez plutôt spécifier le mot-clé resource_group dans la configuration du pipeline parent :
# GOOD
test:
stage: test
trigger:
include: child-pipeline.yml
strategy: mirror
resource_group: production # Specify the resource group in the parent pipeline
deploy:
stage: deploy
script: echo
resource_group: production
environment: production
Waiting for resource {#jobs-get-stuck-in-waiting-for-resource}Parfois, un job se bloque avec le message Waiting for resource: <resource_group>. Pour résoudre ce problème, vérifiez d'abord que le groupe de ressources fonctionne correctement :
Accédez à la page des détails du job.
Si la ressource est attribuée à un job, sélectionnez Voir le job qui utilise actuellement la ressource et vérifiez le statut du job.
running ou pending, la fonctionnalité fonctionne correctement. Attendez que le job se termine et libère la ressource.created et que le mode de traitement est Plus ancien en premier ou Plus récent en premier, la fonctionnalité fonctionne correctement. Visitez la page du pipeline du job et vérifiez quelle étape ou quel job en amont bloque l'exécution.Si Voir le job qui utilise actuellement la ressource n'est pas disponible, la ressource n'est pas attribuée à un job. Vérifiez plutôt les jobs à venir de la ressource.
Si vous ne parvenez pas à résoudre votre problème avec les solutions ci-dessus, vous rencontrez peut-être un problème de condition de concurrence connu. La condition de concurrence se produit dans les pipelines complexes ou très sollicités. Par exemple, vous pourriez rencontrer la condition de concurrence si vous avez :
Si vous pensez rencontrer ce problème, signalez le ticket à GitLab et laissez un commentaire sur le ticket 436988 avec un lien vers votre nouveau ticket. Pour confirmer le problème, GitLab peut demander des informations complémentaires, telles que la configuration complète de votre pipeline.
En guise de solution temporaire, vous pouvez :
Démarrer un nouveau pipeline.
Réexécuter un job terminé qui appartient au même groupe de ressources que le job bloqué.
Par exemple, si vous avez un setup_job et un deploy_job avec le même groupe de ressources, le setup_job peut se terminer alors que le deploy_job est bloqué waiting for resource. Réexécutez le setup_job pour redémarrer l'ensemble du processus et permettre à deploy_job de se terminer.
Vous pouvez obtenir des informations sur les jobs depuis l'API GraphQL. Vous devriez utiliser l'API GraphQL si vous utilisez le contrôle de la simultanéité au niveau du pipeline avec les pipelines interprojets/parent-enfant, car les jobs de déclenchement ne sont pas accessibles depuis l'interface utilisateur.
Pour obtenir des informations sur les jobs depuis l'API GraphQL :
Accédez à la page des détails du pipeline.
Sélectionnez l'onglet Jobs et trouvez l'ID du job bloqué.
Accédez à l'explorateur GraphQL interactif.
Exécutez la requête suivante :
{
project(fullPath: "<fullpath-to-your-project>") {
name
job(id: "gid://gitlab/Ci::Build/<job-id>") {
name
status
detailedStatus {
action {
path
buttonTitle
}
}
}
}
}
Le champ job.detailedStatus.action.path contient l'ID du job utilisant la ressource.
Exécutez la requête suivante et vérifiez le champ job.status selon les critères ci-dessus. Vous pouvez également visiter la page du pipeline depuis le champ pipeline.path.
{
project(fullPath: "<fullpath-to-your-project>") {
name
job(id: "gid://gitlab/Ci::Build/<job-id-currently-using-the-resource>") {
name
status
pipeline {
path
}
}
}
}
Ouvrez un nouveau ticket avec les informations suivantes :
L'ID du job concerné.
Le statut du job.
La fréquence à laquelle le problème se produit.
Les étapes pour reproduire le problème.
Vous pouvez également contacter le support pour obtenir une assistance supplémentaire ou pour prendre contact avec l'équipe de développement.