Я пытаюсь интегрировать новый Elastic Container Registry (ECR) Amazon с моей службой сборки Jenkins. Я использую плагин Cloudbees Docker Build & Publish для создания образов контейнеров и их публикации в реестре.
Чтобы использовать ECR вместо моего частного реестра, я выполнил команду AWS CLI aws --region us-east-1 ecr get-login
который извергает docker login
команду для запуска, но я просто скопировал пароль и создал учетные данные Jenkins типа «Имя пользователя с паролем» из этого пароля (имя пользователя всегда «AWS»).
И это прекрасно работает! Проблема в том, что пароль ECR, созданный с помощью интерфейса командной строки AWS, действителен только в течение 12 часов. Итак, прямо сейчас мне нужно вручную повторно создавать пароль два раза в день и вручную обновлять экран учетных данных Jenkins, иначе мои сборки начнут давать сбой.
Есть ли способ сгенерировать постоянные токены входа в систему ECR или как-то автоматизировать генерацию токенов?
Теперь это возможно с помощью amazon-ecr-учетный помощник как описано в https://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/.
Вкратце:
{"credsStore": "ecr-login"}
Как сказал @Connor McCarthy, ожидая, пока Amazon предложит лучшее решение для более постоянных ключей, тем временем нам нужно было бы каким-то образом сгенерировать ключи на сервере Jenkins.
Мое решение состоит в том, чтобы периодически выполнять задание, которое автоматически обновляет учетные данные Jenkins для ECR каждые 12 часов с помощью Groovy API. Это основано на этот очень подробный ответ, хотя я сделал несколько вещей по-другому, и мне пришлось изменить сценарий.
Шаги:
ecr:GetAuthorizationToken
к роли сервера. [Обновить] Для успешного завершения любых push-уведомлений вам также необходимо предоставить следующие разрешения: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
. У Amazon есть встроенная политика, которая предлагает эти возможности, которая называется AmazonEC2ContainerRegistryPowerUser
.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
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)
}
Пожалуйста, обратите внимание:
"AWS"
в качестве имени пользователя для учетных данных ECR - так работает ECR, но если у вас есть несколько учетных данных с именем пользователя «AWS», вам необходимо обновить скрипт, чтобы найти учетные данные на основе поля описания или чего-то еще.null
для идентификатора (как в ответе, который я связал ранее), тогда будет создан новый идентификатор, и настройка учетных данных на этапе сборки докера будет потеряна.И все - скрипт должен запускаться каждые 12 часов и обновлять учетные данные ECR, и мы можем продолжать использовать плагины Docker.
Я тоже занимался этой же проблемой. Я не нашел ответа, который искал кто-либо из нас, но я смог создать обходной путь с помощью сценариев оболочки. Пока AWS не предложит лучшее решение для учетных данных ECR, я планирую делать что-то в этом направлении.
Я заменил этап Docker Build and Publish задания Jenkins на этап Execute Shell. Я использовал следующий сценарий (возможно, его можно было бы написать лучше) для создания и публикации моего контейнера в ECR. При необходимости замените переменные в скобках <>:
#!/bin/bash
#Variables
REG_ADDRESS="<your ECR Registry Address>"
REPO="<your ECR Repository>"
IMAGE_VERSION="v_"${BUILD_NUMBER}
WORKSPACE_PATH="<path to the workspace directory of the Jenkins job>"
#Login to ECR Repository
LOGIN_STRING=`aws ecr get-login --region us-east-1`
${LOGIN_STRING}
#Build the containerexit
cd ${WORKSPACE_PATH}
docker build -t ${REPO}:${IMAGE_VERSION} .
#Tag the build with BUILD_NUMBER version and Latests
docker tag ${REPO}:${IMAGE_VERSION} ${REPO_ADDRESS}/${REPO}:${IMAGE_VERSION}
#Push builds
docker push ${REG_ADDRESS}/${REPO}:${IMAGE_VERSION}
С помощью https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR с плагином Docker Build and Publish работает нормально.