„Wir müssen Hunderte von Container-Images von Amazon Elastic Container Registry (ECR) zu GitLab migrieren. Könnt ihr uns helfen?“ Diese Frage taucht immer wieder in Gesprächen mit Platform Engineers auf. Sie modernisierten also ihre DevSecOps-Toolchain mit GitLab, kamen aber beim Verschieben ihrer Container-Images nicht weiter. Während ein einzelner Image-Transfer einfach ist, erscheint das schiere Volumen überwältigend.
Ein Platform Engineer brachte es auf den Punkt: „Ich weiß genau, was zu tun ist – pullen, neu kennzeichnen, pushen. Aber ich habe 200 Microservices mit jeweils mehreren Tags. Ich kann es nicht rechtfertigen, Wochen für diese Migration aufzuwenden, während wichtige Infrastrukturarbeiten anstehen.“
Die Herausforderung
Dieses Gespräch führte zu einer Idee. Was wäre, wenn wir den gesamten Prozess automatisieren könnten? Wenn Plattformteams ihre CI/CD zu GitLab verschieben, sollte die Migration von Container-Images kein Engpass sein. Der manuelle Prozess ist einfach, aber repetitiv: Jedes Image pullen, neu kennzeichnen und in die Container-Registry von GitLab pushen. Angesichts dutzender Repositories und mehrerer Tags pro Image, bedeutet dies Tage oder Wochen langwieriger Arbeit.
Die Lösung
Wir haben uns daran gemacht, eine GitLab-Pipeline zu erstellen, die all diese schwierigen Aufgaben automatisch erledigt. Das Ziel war einfach: Wir wollten Platform Engineers ein Tool zur Verfügung stellen, das sie in wenigen Minuten einrichten und über Nacht ausführen können, sodass am nächsten Morgen alle ihre Images erfolgreich migriert wurden.
Einrichten des Zugriffs
Das Wichtigste zuerst: die Sicherheit. Teams sollen diese Migration mit minimalen AWS-Berechtigungen durchführen können. Hier ist die schreibgeschützte Identitäts- und Zugriffsmanagement (IAM)-Richtlinie dafür:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage"
],
"Resource": "*"
}
]
}
GitLab-Konfiguration
Nachdem die Sicherheit gewährleistet ist, ist der nächste Schritt die Einrichtung von GitLab. Wir haben uns auf das Wesentliche beschränkt. Du musst diese Variablen in deinen CI/CD-Einstellungen konfigurieren:
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
Die Migrationspipeline
Jetzt wird es interessant. Wir haben die Pipeline mit Docker-in-Docker erstellt, um alle Image-Vorgänge zuverlässig zu verarbeiten:
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}
Die Pipeline hat drei Phasen, die jeweils auf der letzten aufbauen:
- Entdeckung
Zuerst findet sie alle deine Repositories:
REPOS=$(aws ecr describe-repositories --query 'repositories[*].repositoryName' --output text)
- Tag-Auflistung
Dann ruft sie für jedes Repository alle Tags ab:
TAGS=$(aws ecr describe-images --repository-name $repo --query 'imageDetails[*].imageTags[]' --output text)
- Übertragung
Schließlich übernimmt sie die eigentliche Migration:
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}
Das Ergebnis
Erinnerst du dich an den Platform Engineer, der nicht wochenlang mit der Migration verbringen wollte? Diese Lösung bietet Folgendes:
- automatisierte Erkennung und Migration aller Repositories und Tags
- konsistente Image-Benennung zwischen ECR und GitLab
- Fehlerbehandlung für fehlgeschlagene Übertragungen
- klare Protokollierung zur Verfolgung des Fortschritts
Anstatt Skripte zu schreiben und die Migration zu überwachen, konnte sich der Plattform Engineer auf wertvollere Arbeit konzentrieren.
Verwendung
Die ersten Schritte sind einfach:
- Kopiere die Datei
.gitlab-ci.yml
in dein Repository. - Konfiguriere die AWS- und GitLab-Variablen.
- Setze
BULK_MIGRATE
auf „true“, um die Migration zu starten.
Best Practices
Bei der Unterstützung von Teams bei ihren Migrationen haben wir einige Dinge gelernt:
- Der Prozess sollte außerhalb der Stoßzeiten durchgeführt werden, um die Auswirkungen auf dein Team zu minimieren.
- Die Pipeline-Protokolle sind wichtig – darin findest du Informationen, wenn es ein Problem gibt.
- Die Elastic Container Registry (ECR) sollte erst deaktiviert werden, wenn du überprüft hast, dass alle Images erfolgreich übertragen wurden.
- Bei sehr großen Migrationen solltest du eine Ratenbegrenzung in Betracht ziehen, um eine Überlastung deines Netzwerks zu vermeiden.
Wir haben diese Pipeline in unserem öffentlichen GitLab-Repository quelloffen verfügbar gemacht, weil wir der Meinung sind, dass Plattform Engineers Zeit damit verbringen sollten, wertvolle Infrastrukturen aufzubauen, anstatt Container-Images zu kopieren. Passe sie an deine Bedürfnisse an und stelle Fragen zur Implementierung, wenn etwas unklar ist.
Informationen dazu und zu anderen Paketkomponenten findest du in unserer CI/CD-Katalog-Dokumentation.