AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 744902
Accepted
Guss
Guss
Asked: 2015-12-23 23:12:00 +0800 CST2015-12-23 23:12:00 +0800 CST 2015-12-23 23:12:00 +0800 CST

将 Amazon Elastic Container Registry 与 Jenkins 集成

  • 772

我正在尝试将 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 小时内有效。所以现在,我必须每天两次手动重新生成密码并手动更新 Jenkins 凭据屏幕,否则我的构建开始失败。

有没有办法生成永久 ECR 登录令牌,或者以某种方式自动生成令牌?

amazon-web-services
  • 4 4 个回答
  • 5969 Views

4 个回答

  • Voted
  1. Klugscheißer
    2016-10-28T13:22:05+08:002016-10-28T13:22:05+08:00

    现在可以使用amazon-ecr-credential-helper,如https://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/中所述。

    它的短处是:

    • 确保您的 Jenkins 实例具有正确的 AWS 凭证以使用您的 ECR 存储库拉/推。这些可以是环境变量、共享凭证文件或实例配置文件的形式。
    • 将 docker-credential-ecr-login 二进制文件放在 $PATH 中的目录之一。
    • 在Jenkins用户的home目录下写入Docker配置文件,例如/var/lib/jenkins/.docker/config.json。与内容{"credsStore": "ecr-login"}
    • 安装 Docker Build and Publish 插件并确保 jenkins 用户可以联系 Docker 守护进程。
    • 最后,创建一个包含发布 docker 镜像的构建步骤的项目
    • 6
  2. Best Answer
    Guss
    2015-12-24T10:37:32+08:002015-12-24T10:37:32+08:00

    正如@Connor McCarthy 所说,在等待亚马逊为更多永久密钥提供更好的解决方案的同时,我们需要以某种方式自己在 Jenkins 服务器上生成密钥。

    我的解决方案是定期使用 Groovy API 每 12 小时自动更新 ECR 的 Jenkins 凭据。这是基于这个非常详细的答案,尽管我做了一些不同的事情,我不得不修改脚本。

    脚步:

    1. 确保您的 Jenkins master 可以访问所需的 AWS API。在我的设置中,Jenkins 主服务器使用 IAM 角色在 EC2 上运行,因此我只需将权限添加ecr:GetAuthorizationToken到服务器角色即可。[更新]要成功完成任何推送,您还需要授予以下权限:ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage. Amazon 有一个提供这些功能的内置策略,称为AmazonEC2ContainerRegistryPowerUser.
    2. 确保 AWS CLI 安装在主服务器上。在我的设置中,master 在 debian docker 容器中运行,我刚刚将此 shell 构建步骤添加到密钥生成作业中: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. 安装Groovy 插件,它允许您将 Groovy 脚本作为 Jenkins 系统的一部分运行。
    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”的凭证,那么您需要更新脚本以根据描述字段什么的。
    • 您必须在脚本中使用真实 ECR 密钥的真实 ID,因为凭证的 API 将凭证对象替换为新对象,而不是仅仅更新它,并且 Docker 构建步骤和密钥之间的绑定是通过 ID 进行的。如果您使用nullID 的值(如我之前链接的答案),则会创建一个新 ID,并且 docker build 步骤中的凭据设置将丢失。

    就是这样 - 脚本应该能够每 12 小时运行一次并刷新 ECR 凭据,我们可以继续使用 Docker 插件。

    • 4
  3. Connor McCarthy
    2015-12-24T09:11:34+08:002015-12-24T09:11:34+08:00

    我也在研究这个完全相同的问题。我没有想出我们两个人都在寻找的答案,但我能够使用 shell 脚本创建一个解决方法。在 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}
    
    • 3
  4. Danilo
    2016-01-27T01:40:09+08:002016-01-27T01:40:09+08:00

    将https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR与 Docker Build and Publish 插件一起使用就可以了。

    • 2

相关问题

  • 如何在 Amazon Linux 服务器上升级到 Java 1.8?

  • 如何在 AWS ubuntu 实例上安装 apache?

  • 了解 Amazon AWS 使用数据

  • 亚马逊提供的负载均衡服务体验如何?

  • ELB 中现有节点的 AWS 自动缩放问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve