« Nous devons migrer des centaines d'images de conteneurs d'Amazon Elastic Container Registry (ECR) vers GitLab. Pouvez-vous nous aider ? » Cette question revenait sans cesse lors de nos échanges avec des ingénieurs de plateforme. En pleine modernisation de leur chaîne d'outils DevSecOps avec GitLab, ils se retrouvaient bloqués au moment de déplacer leurs images de conteneurs. D’un point de vue technique, chaque transfert est simple. Mais, l'opération était longue et fastidieuse en raison du volume considérable d'images.
Un ingénieur de plateforme a parfaitement résumé la situation : « Je connais parfaitement le processus : effectuer un pull, retagger, effectuer un push. Le problème, c'est que je gère 200 microservices, chacun contenant plusieurs tags. Je ne peux pas passer plusieurs semaines sur cette migration alors que j'ai des tâches critiques à effectuer au niveau de l'infrastructure. »
Le défi
Cette conversation nous a fait réfléchir et a donné naissance à une idée. Et si nous pouvions automatiser l'ensemble du processus ? Lorsqu'une équipe de plateforme DevOps transfère ses pipelines CI/CD vers GitLab, la migration des images de conteneurs ne devrait pas poser de difficulté particulière. Le processus manuel est rudimentaire, mais répétitif : il s'agit d'effectuer un pull de chaque image, de la retagger et d'effectuer un push pour la migrer vers le registre de conteneurs de GitLab. Réaliser cette même opération pour des dizaines de dépôts et plusieurs tags par image requiert des jours ou des semaines de travail chronophage.
La solution
Nous avons donc entrepris de créer un pipeline GitLab qui effectuerait automatiquement cette lourde tâche. L'objectif était clair : fournir aux ingénieurs de plateforme un outil qu'ils pourraient configurer en quelques minutes et qui, en une seule nuit, parviendrait à migrer toutes leurs images.
Configuration des accès
Commençons par l'essentiel : les aspects liés à la sécurité. Nous voulions nous assurer que les équipes puissent exécuter cette migration avec un minimum d'autorisations sur AWS. Voici la politique de gestion des identités et des accès (IAM) en lecture seule dont vous avez besoin :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage"
],
"Resource": "*"
}
]
}
Configuration de GitLab
Une fois la sécurité en place, l'étape suivante consiste à configurer GitLab. Nous avons volontairement réduit cela au strict minimum : il vous suffit de configurer les variables suivantes dans les paramètres CI/CD de votre projet :
AWS_ACCOUNT_ID: Your AWS account number
AWS_DEFAULT_REGION: Your ECR region
AWS_ACCESS_KEY_ID: [Masked]
AWS_SECRET_ACCESS_KEY: [Masked]
BULK_MIGRATE: true
Le pipeline de migration
Passons maintenant à la partie la plus intéressante. Nous avons créé le pipeline en utilisant Docker-in-Docker pour gérer toutes les opérations liées aux images de manière fiable :
image: docker:20.10
services:
- docker:20.10-dind
before_script:
- apk add --no-cache aws-cli jq
- aws sts get-caller-identity
- aws ecr get-login-password | docker login --username AWS --password-stdin
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
Le pipeline fonctionne en trois phases, chacune s'appuyant sur la précédente :
- Identification
Dans un premier temps, il détecte l'ensemble de vos dépôts :
REPOS=$(aws ecr describe-repositories --query 'repositories[*].repositoryName' --output text)
- Énumération des tags
Ensuite, pour chaque dépôt, il récupère l'ensemble des tags :
TAGS=$(aws ecr describe-images --repository-name $repo --query 'imageDetails[*].imageTags[]' --output text)
- Transfert
Enfin, il gère la migration proprement dite :
docker pull ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag}
docker tag ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${repo}:${tag} ${CI_REGISTRY_IMAGE}/${repo}:${tag}
docker push ${CI_REGISTRY_IMAGE}/${repo}:${tag}
Résultats
Voici ce que cette solution offre comme avantages aux ingénieurs de plateforme qui ne veulent pas passer plusieurs semaines sur la migration :
- Identification et migration automatisées de l'ensemble des dépôts et tags
- Dénomination cohérente des images entre ECR et GitLab
- Gestion des échecs de transferts
- Journalisation claire pour suivre la progression
Au lieu d'écrire des scripts et de surveiller la migration, l'ingénieur de plateforme peut se concentrer sur des tâches à plus grande valeur ajoutée.
Utilisation
La première étape est très simple :
- Copiez le fichier
.gitlab-ci.yml
dans votre dépôt. - Configurez les variables AWS et GitLab.
- Définissez
BULK_MIGRATE
sur « true » pour déclencher la migration.
Bonnes pratiques
En accompagnant plusieurs équipes dans leur migration, nous avons tiré quelques enseignements pratiques :
- Exécutez la migration en dehors des heures de pointe pour réduire au maximum l'impact sur votre équipe.
- Consultez les logs de pipeline qui vous indiqueront si un élément nécessite votre attention.
- Ne désactivez pas votre registre ECR avant d'avoir vérifié que toutes les images ont bien été transférées.
- Pour les migrations à grande échelle, envisagez d'ajouter une limite de débit pour éviter de saturer votre réseau.
Nous mettons ce pipeline à disposition en open source dans notre dépôt GitLab public, car nous sommes convaincus que les ingénieurs de plateforme devraient passer leur temps à créer de la valeur, plutôt qu'à copier des images de conteneurs. N'hésitez pas à l'adapter à vos besoins ou à poser vos questions sur sa mise en œuvre. Consultez notre documentation pour en savoir plus sur les catalogues CI/CD.