ผสานรวม Amazon Elastic Container Registry กับ Jenkins


10

ฉันกำลังพยายามรวม Elastic Container Registry (ECR) ใหม่ของ Amazon กับ Jenkins build service ของฉัน ฉันใช้ปลั๊กอินสร้าง & เผยแพร่ของ Cloudbees Docker เพื่อสร้างอิมเมจคอนเทนเนอร์และเผยแพร่ลงในรีจิสตรี

หากต้องการใช้ ECR แทนการลงทะเบียนส่วนตัวฉันได้รันคำสั่ง AWS CLI aws --region us-east-1 ecr get-loginซึ่งdocker loginใช้เรียกคำสั่ง - แต่ฉันเพิ่งคัดลอกรหัสผ่านและสร้างหนังสือรับรอง Jenkins ประเภท "ชื่อผู้ใช้ด้วยรหัสผ่าน" จากรหัสผ่านนั้น (ชื่อผู้ใช้คือ เสมอ "AWS")

และนั่นก็ใช้ได้ดี! ปัญหาคือรหัสผ่าน ECR ที่สร้างโดย AWS CLI นั้นใช้ได้เพียง 12 ชั่วโมงเท่านั้น ดังนั้นตอนนี้ฉันต้องสร้างรหัสผ่านใหม่สองครั้งต่อวันและอัปเดตหน้าจอข้อมูลรับรอง Jenkins ด้วยตนเองมิฉะนั้นงานสร้างของฉันก็เริ่มล้มเหลว

มีวิธีในการสร้างโทเค็นการเข้าสู่ระบบ ECR แบบถาวรหรือไม่หรือเป็นการสร้างโทเค็นอัตโนมัติ?

คำตอบ:


6

นี่คือตอนนี้ไปได้โดยใช้Amazon-ECR-ข้อมูลรับรองผู้ช่วยที่อธิบายไว้ในhttps://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/

สั้น ๆ ของมันคือ:

  • ตรวจสอบให้แน่ใจว่าอินสแตนซ์ Jenkins ของคุณมีข้อมูลรับรอง AWS ที่เหมาะสมในการดึง / ดันด้วยที่เก็บ ECR ของคุณ สิ่งเหล่านี้สามารถอยู่ในรูปแบบของตัวแปรสภาพแวดล้อมไฟล์ข้อมูลรับรองที่แชร์หรือโปรไฟล์อินสแตนซ์
  • วางไบนารีนักเทียบท่าข้อมูลประจำตัว - ecr-login ที่หนึ่งในไดเรกทอรีใน $ PATH
  • เขียนไฟล์คอนฟิกูเรชัน Docker ภายใต้โฮมไดเร็กทอรีของผู้ใช้ Jenkins ตัวอย่างเช่น /var/lib/jenkins/.docker/config.json กับเนื้อหา{"credsStore": "ecr-login"}
  • ติดตั้งปลั๊กอิน Docker Build และ Publish และตรวจสอบให้แน่ใจว่าผู้ใช้ jenkins สามารถติดต่อ Docker daemon ได้
  • สุดท้ายสร้างโครงการด้วยขั้นตอนการสร้างที่เผยแพร่อิมเมจนักเทียบท่า

4

ดังที่ @Connor McCarthy กล่าวขณะที่รอให้ Amazon หาวิธีแก้ปัญหาที่ดีกว่าสำหรับรหัสถาวรที่มากขึ้นในเวลาที่เราต้องการสร้างคีย์บนเซิร์ฟเวอร์ Jenkins

โซลูชันของฉันคือการมีงานเป็นระยะซึ่งจะอัปเดตข้อมูลรับรอง Jenkins สำหรับ ECR ทุก 12 ชั่วโมงโดยอัตโนมัติโดยใช้ Groovy API นี่เป็นคำตอบที่ละเอียดมากแม้ว่าฉันจะทำบางสิ่งที่แตกต่างออกไปและฉันก็ต้องแก้ไขสคริปต์

ขั้นตอน:

  1. ตรวจสอบให้แน่ใจว่า Jenkins master ของคุณสามารถเข้าถึง AWS API ที่ต้องการ ในการตั้งค่าของฉันอาจารย์เจนกินส์กำลังทำงานบน EC2 ที่มีบทบาท IAM ดังนั้นฉันต้องเพิ่มสิทธิ์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. ติดตั้งปลั๊กอิน Groovyที่ให้คุณเรียกใช้สคริปต์ Groovy ซึ่งเป็นส่วนหนึ่งของระบบ Jenkins
  4. ในหน้าจอข้อมูลรับรองให้มองหาคีย์ AWS ECR ของคุณคลิก "ขั้นสูง" และบันทึก "ID" สำหรับตัวอย่างนี้ฉันจะสมมติว่า "12345"
  5. สร้างงานใหม่ด้วยการเปิดตัวเป็นระยะเวลา 12 ชั่วโมงและเพิ่มขั้นตอนการสร้าง "ระบบ Groovy script" ด้วยสคริปต์ต่อไปนี้:

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" คุณจะต้องอัปเดตสคริปต์เพื่อค้นหาข้อมูลรับรองตาม ฟิลด์คำอธิบายหรือบางอย่าง
  • คุณต้องใช้ ID จริงของคีย์ ECR จริงของคุณในสคริปต์เนื่องจาก API สำหรับข้อมูลรับรองจะแทนที่วัตถุข้อมูลรับรองด้วยวัตถุใหม่แทนที่จะเพิ่งอัปเดตและการผูกระหว่างขั้นตอนการสร้างนักเทียบท่าและรหัสนั้นเป็นรหัส หากคุณใช้ค่าnullสำหรับ ID (เช่นเดียวกับคำตอบที่ฉันเชื่อมโยงมาก่อน) ID ใหม่จะถูกสร้างขึ้นและการตั้งค่าข้อมูลรับรองในขั้นตอนการสร้างนักเทียบท่าจะหายไป

และนั่นคือ - สคริปต์ควรจะสามารถเรียกใช้ทุก ๆ 12 ชั่วโมงและรีเฟรชข้อมูลประจำตัว ECR และเราสามารถใช้ปลั๊กอิน Docker ต่อไปได้


3

ฉันกำลังมองหาปัญหาเดียวกันนี้เช่นกัน ฉันไม่ได้คิดคำตอบที่เราสองคนกำลังมองหา แต่ฉันสามารถสร้างวิธีแก้ปัญหาด้วยการเขียนสคริปต์เชลล์ จนกระทั่ง AWS ออกมาพร้อมทางออกที่ดีกว่าสำหรับข้อมูลรับรอง ECR ฉันวางแผนที่จะทำบางสิ่งตามสายเหล่านี้

ฉันแทนที่ขั้นตอนการสร้างและเผยแพร่ Docker ของงาน Jenkins ด้วยและ Execute Shell step ฉันใช้สคริปต์ต่อไปนี้ (อาจจะเขียนได้ดีกว่า) เพื่อสร้างและเผยแพร่คอนเทนเนอร์ของฉันไปยัง 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 และฉันค่อนข้างจะใช้มันต่อไปเพราะมันทำให้ชีวิตของฉันง่ายขึ้น ฉันมีหลายคอนเทนเนอร์บิวด์ในระบบและต้องการเพิ่มมากขึ้นและการรวมสคริปต์นั้นเข้ากับแต่ละบิลด์นั้นสร้างความยุ่งยากมากกว่าที่ฉันเต็มใจจะอยู่ด้วย ฉันมีทางเลือกอื่นที่ฉันเพิ่มไว้เป็นคำตอบ
Guss

2

การใช้https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECRด้วยปลั๊กอิน Docker Build และ Publish ใช้งานได้ดี


ฉันได้ติดตั้งแล้ว - แต่ไม่สามารถคิดได้ว่าจะทำอย่างไรกับมัน: มันไม่มีการกำหนดค่าและไม่มี UI
Guss

ติดตั้งปลั๊กอิน ในขั้นตอนสร้างและเผยแพร่ Docker คุณจะมีรายการแบบหล่นลงชื่อ "ข้อมูลรับรองรีจิสทรี" คลิกที่ "เพิ่ม" ถัดจากนั้นเลือกเป็นประเภท "ข้อมูลประจำตัว AWS" ในกล่องโต้ตอบ ป้อนรหัสการเข้าถึง / รหัสลับ
Danilo

ตอนนี้ฉันเห็นแล้ว น่าเสียดายที่มันไม่รองรับโปรไฟล์อินสแตนซ์
Guss

ใช่. แต่ตอนนี้ฉันชอบโซลูชันนี้
Danilo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.