Amazonの新しいElastic Container Registry(ECR)をJenkinsビルドサービスと統合しようとしています。 Cloudbees Docker Build&Publishプラグインを使用して、コンテナーイメージをビルドし、レジストリに公開しています。
プライベートレジストリの代わりにECRを使用するために、AWS CLIコマンドaws --region us-east-1 ecr get-login
を実行してdocker login
コマンドを実行しましたが、パスワードをコピーして、「ユーザー名」タイプのJenkins認証情報を作成しましたパスワード付き」(そのユーザー名は常に「AWS」です)。
そしてそれはうまくいきます!問題は、AWS CLIによって生成されるECRパスワードが12時間のみ有効であることです。現在、1日2回手動でパスワードを再生成し、Jenkinsの認証情報画面を手動で更新する必要があります。更新しないと、ビルドが失敗します。
永続的なECRログイントークンを生成する方法、またはトークンの生成を自動化する方法はありますか?
@Connor McCarthyが言ったように、Amazonがより永続的なキーのためのより良いソリューションを考え出すのを待つ間、当面はJenkinsサーバーでキーを自分で生成する必要があります。
私の解決策は、Groovy APIを使用して、12時間ごとにECRのJenkins資格情報を自動的に更新する定期的なジョブを持つことです。これは この非常に詳細な回答 に基づいていますが、いくつか異なることを行い、スクリプトを変更する必要がありました。
手順:
ecr:GetAuthorizationToken
権限を追加する必要がありました。 [update]プッシュを正常に完了するには、次の権限も付与する必要があります: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の仕組みですが、ユーザー名「AWS」の資格情報が複数ある場合は、スクリプトを更新して検索する必要があります。説明フィールドなどに基づく資格情報。null
を使用すると(前にリンクした回答のように)、新しいIDが作成され、Dockerビルドステップでの資格情報の設定が失われます。これで完了です。スクリプトは12時間ごとに実行され、ECR資格情報を更新できる必要があります。Dockerプラグインを引き続き使用できます。
これは、 Amazon-ecr-credential-helper を使用して可能になりました https://aws.Amazon.com/blogs/compute/authenticating- Amazon-ecr-repositories-for-docker-cli-with-credential-helper / 。
それの短いです:
{"credsStore": "ecr-login"}
私もこのまったく同じ問題を調査していました。どちらも探していた答えは思いつきませんでしたが、シェルスクリプトを使用して回避策を作成できました。 AWSがECRクレデンシャルに対するより優れたソリューションを提供するまで、これらの方針に沿って何かを行う予定です。
JenkinsジョブのDocker Build and Publishステップを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}
Docker Build and Publishプラグインで https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR を使用しても問題なく機能します。