我试图将亚马逊的新弹性容器registry(ECR)与我的Jenkins构build服务相集成。 我正在使用Cloudbees Docker Build&Publish插件来构build容器映像并将其发布到registry中。
要使用ECR而不是我的私人registry,我已经运行了AWS CLI命令aws --region us-east-1 ecr get-login这会发出一个docker login命令来运行 – 但是我只是复制出密码并创build了一个Jenkins从该密码(用户名始终为“AWS”)键入“用户名和密码”凭据。
那工作正常! 问题是由AWS CLI生成的ECR密码只有12小时有效。 所以现在,我必须每天手动重新生成密码两次,并手动更新Jenkins凭据屏幕,否则我的构build开始失败。
有没有办法生成永久的ECRlogin令牌,或以某种方式自动化令牌生成?
现在可以使用amazon-ecr-credential-helper ,如https://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/中所述 。
它的缺点是:
{"credsStore": "ecr-login"} 正如康纳·麦卡锡(@Connor McCarthy)所说,在等待亚马逊为更多永久密钥提出更好的解决scheme的同时,我们还需要自己在Jenkins服务器上自行生成密钥。
我的解决scheme是定期使用Groovy API,每12小时自动更新ECR的Jenkins凭证。 这是基于这个非常详细的答案 ,但我做了一些不同的事情,我不得不修改脚本。
脚步:
ecr:GetAuthorizationToken添加到服务器angular色。 [ 更新 ]要成功推送完成,您还需要授予这些权限ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage 。 亚马逊有一个内置的策略,提供这些function,称为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 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”的凭证,那么你需要更新脚本以find凭证基于描述字段或其他内容。 null (如在之前链接的答案中),则会创build一个新的ID,并且Docker构build步骤中凭据的设置将丢失。 就是这样 – 脚本应该能够每12小时运行一次并刷新ECR凭据,并且我们可以继续使用Docker插件。
我也在研究这个完全相同的问题。 我没有拿出我们正在寻找的答案,但是我能够用shell脚本创build一个解决方法。 在AWS出现更好的ECR凭证解决scheme之前,我计划按照这些方法做一些事情。
我将Jenkins作业的Docker Build和Publish步骤replace为Execute Shell步骤。 我使用下面的脚本(可能写得更好)来构build和发布我的容器到ECR。 根据需要replace<>括号中的variables:
#!/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和Publish插件的https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR工作得很好。