Amazon Elastic Container RegistryをJenkinsと統合する


10

Amazonの新しいElastic Container Registry(ECR)をJenkinsビルドサービスと統合しようとしています。Cloudbees Docker Build&Publishプラグインを使用してコンテナーイメージをビルドし、それらをレジストリに公開しています。

プライベートレジストリの代わりにECRを使用するために、実行aws --region us-east-1 ecr get-loginするdocker loginコマンドを実行するAWS CLIコマンドを実行しましたが、パスワードをコピーし、そのパスワードから「ユーザー名とパスワード」タイプのJenkins認証情報を作成しました(ユーザー名は常に「AWS」)。

そしてそれはうまくいきます!問題は、AWS CLIによって生成されるECRパスワードが12時間のみ有効であることです。現在、1日2回手動でパスワードを再生成し、Jenkinsの認証情報画面を手動で更新する必要があります。そうしないと、ビルドが失敗します。

永続的なECRログイントークンを生成する方法、またはトークンの生成を何らかの方法で自動化する方法はありますか?

回答:


6

これは、https: //aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/で説明されているように、amazon-ecr-credential-helperを使用して可能になりました。

それの短いです:

  • Jenkinsインスタンスに、ECRリポジトリでプル/プッシュするための適切なAWS認証情報があることを確認してください。これらは、環境変数、共有認証情報ファイル、またはインスタンスプロファイルの形式にすることができます。
  • docker-credential-ecr-loginバイナリを$ PATHのいずれかのディレクトリに配置します。
  • Docker構成ファイルをJenkinsユーザーのホームディレクトリ(たとえば、/ var / lib / jenkins / .docker / config.json)の下に書き込みます。内容で{"credsStore": "ecr-login"}
  • Docker Build and Publishプラグインをインストールし、jenkinsユーザーがDockerデーモンにアクセスできることを確認します。
  • 最後に、Dockerイメージを公開するビルドステップでプロジェクトを作成します

4

@Connor McCarthyが言ったように、Amazonがより永続的なキーのためのより良いソリューションを考え出すのを待つ間、当面はJenkinsサーバーでキーを生成する必要があります。

私の解決策は、Groovy APIを使用して、12時間ごとにECRのJenkins資格情報を自動的に更新する定期的なジョブを持つことです。これはこの非常に詳細な回答に基づいていますが、いくつか異なることを行い、スクリプトを変更する必要がありました。

手順:

  1. Jenkinsマスターが必要なAWS APIにアクセスできることを確認してください。私のセットアップでは、JenkinsマスターはIAMロールを持つEC2で実行されているecr:GetAuthorizationTokenため、サーバーロールに権限を追加する必要がありました。[ 更新 ]プッシュを正常に完了するには、次の権限も付与する必要がありますecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage。Amazonには、と呼ばれるこれらの機能を提供する組み込みポリシーがありますAmazonEC2ContainerRegistryPowerUser
  2. AWS CLIがマスターにインストールされていることを確認してください。私のセットアップでは、マスターがdebian dockerコンテナーで実行されているので、このシェルビルドステップをキー生成ジョブに追加しました。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
  3. Jenkinsシステムの一部としてGroovyスクリプトを実行できるGroovyプラグインをインストールします。
  4. 認証情報画面でAWS ECRキーを探し、[詳細]をクリックして、その「ID」を記録します。この例では、「12345」であると想定します。
  5. 12時間の定期的な起動で新しいジョブを作成し、次のスクリプトを使用して「システムGroovyスクリプト」ビルドステップを追加します。

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」の複数の資格情報がある場合は、スクリプトに基づいて資格情報を見つけるようにスクリプトを更新する必要があります。説明フィールドか何か。
  • クレデンシャルのAPIは、クレデンシャルオブジェクトを単に更新するのではなく、新しいオブジェクトで置き換え、実際のECRキーの実際のIDをスクリプトで使用する必要があります。Dockerビルドステップとキーの間のバインディングはIDによるものです。nullID の値を使用すると(前にリンクした回答のように)、新しいIDが作成され、Dockerビルドステップでの資格情報の設定が失われます。

これで完了です。スクリプトは12時間ごとに実行でき、ECR資格情報を更新できます。Dockerプラグインを引き続き使用できます。


3

私もこのまったく同じ問題を調査していました。どちらも探していた答えは思いつきませんでしたが、シェルスクリプトで回避策を作成することができました。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が好きだということです。それが私の人生を簡素化するので、むしろ使い続けています。システムにいくつかのコンテナービルドがあり、さらに追加したいと考えています。そのスクリプトを各ビルドに統合することは、私が共存するよりも面倒です。回答として追加している代替ソリューションがあります。
Guss

2

Docker Build and Publishプラグインでhttps://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECRを使用しても問題なく機能します。


インストールしましたが、どうすればいいのかわかりません。設定もUIもありません。
ガス

プラグインをインストールします。Docker Build and Publishステップでは、「Registry credentials」というドロップダウンがあります。その横にある[追加]をクリックし、ダイアログでタイプとして[AWS認証情報]を選択します。アクセスキー/シークレットキーを入力してください。
Danilo

わかりました。残念ながら、インスタンスプロファイルをサポートしていません。
ガス

はい。しかし、今のところ、私はこのソリューションを好みます。
Danilo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.