Jak powiedział @Connor McCarthy, czekając, aż Amazon wymyśli lepsze rozwiązanie dla bardziej trwałych kluczy, tymczasem musieliśmy sami wygenerować klucze na serwerze Jenkins.
Moim rozwiązaniem jest okresowe zadanie, które automatycznie aktualizuje poświadczenia Jenkins dla ECR co 12 godzin automatycznie, przy użyciu Groovy API. Jest to oparte na tej bardzo szczegółowej odpowiedzi , chociaż zrobiłem kilka rzeczy inaczej i musiałem zmodyfikować skrypt.
Kroki:
- Upewnij się, że twój mistrz Jenkins ma dostęp do wymaganego AWS API. W mojej konfiguracji mistrz Jenkins działa na EC2 z rolą IAM, więc musiałem tylko dodać uprawnienie
ecr:GetAuthorizationToken
do roli serwera. [ Aktualizacja ] Aby uzyskać wszelkie popycha zakończy się pomyślnie, to trzeba także przyznać te uprawnienia: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
. Amazon ma wbudowane zasady, które oferują te możliwości, zwane AmazonEC2ContainerRegistryPowerUser
.
- Upewnij się, że interfejs AWS CLI jest zainstalowany w systemie głównym. W moim ustawieniu, gdy master działa w kontenerze dokera Debiana, właśnie dodałem ten krok kompilacji powłoki do zadania generowania klucza:
dpkg -l python-pip >/dev/null 2>&1 || sudo apt-get install python-pip -y; pip list 2>/dev/null | grep -q awscli || pip install awscli
- Zainstaluj wtyczkę Groovy, która pozwala na uruchomienie skryptu Groovy jako części systemu Jenkins.
- Na ekranie poświadczeń znajdź klucz AWS ECR, kliknij „Zaawansowane” i zapisz jego „ID”. W tym przykładzie założę, że jest to „12345”.
- Utwórz nowe zadanie z okresowym uruchamianiem 12 godzin i dodaj krok kompilacji „systemowy skrypt Groovy” za pomocą następującego skryptu:
import jenkins.model.*
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
def changePassword = { username, new_password ->
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance)
def c = creds.findResult { it.username == username ? it : null }
if ( c ) {
println "found credential ${c.id} for username ${c.username}"
def credentials_store = Jenkins.instance.getExtensionList(
'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
)[0].getStore()
def result = credentials_store.updateCredentials(
com.cloudbees.plugins.credentials.domains.Domain.global(),
c,
new UsernamePasswordCredentialsImpl(c.scope, "12345", c.description, c.username, new_password))
if (result) {
println "password changed for ${username}"
} else {
println "failed to change password for ${username}"
}
} else {
println "could not find credential for ${username}"
}
}
println "calling AWS for docker login"
def prs = "/usr/local/bin/aws --region us-east-1 ecr get-login".execute()
prs.waitFor()
def logintext = prs.text
if (prs.exitValue()) {
println "Got error from aws cli"
throw new Exception()
} else {
def password = logintext.split(" ")[5]
println "Updating password"
changePassword('AWS', password)
}
Proszę zanotować:
- użycie ciągu zakodowanego na stałe
"AWS"
jako nazwy użytkownika dla poświadczeń ECR - tak działa ECR, ale jeśli masz wiele poświadczeń z nazwą użytkownika „AWS”, musisz zaktualizować skrypt, aby zlokalizować poświadczenia na podstawie pole opisu czy coś takiego.
- Musisz użyć prawdziwego identyfikatora swojego prawdziwego klucza ECR w skrypcie, ponieważ interfejs API dla poświadczeń zastępuje obiekt poświadczeń nowym obiektem zamiast po prostu go aktualizować, a powiązanie między krokiem kompilacji Dockera a kluczem odbywa się według tego identyfikatora. Jeśli użyjesz wartości
null
identyfikatora (jak w odpowiedzi, którą wcześniej podłączyłem), zostanie utworzony nowy identyfikator i ustawienie poświadczeń w kroku kompilacji dokera zostanie utracone.
I to wszystko - skrypt powinien być w stanie uruchamiać się co 12 godzin i odświeżać poświadczenia ECR, a my możemy nadal korzystać z wtyczek Docker.
Korzystanie z https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR z wtyczką Docker Build and Publish działa dobrze.
źródło