Integrasikan Registry Container Amazon Elastic dengan Jenkins

10

Saya mencoba untuk mengintegrasikan Elastic Container Registry (ECR) baru Amazon dengan layanan build Jenkins saya. Saya menggunakan plugin Cloudbees Docker Build & Publish untuk membuat gambar kontainer dan menerbitkannya ke registri.

Untuk menggunakan ECR alih-alih registri pribadi saya, saya telah menjalankan perintah AWS CLI aws --region us-east-1 ecr get-loginyang memuntahkan docker loginperintah untuk dijalankan - tetapi saya hanya menyalin kata sandi dan membuat kredensial Jenkins dengan tipe "Nama pengguna dengan kata sandi" dari kata sandi tersebut (nama pengguna adalah selalu "AWS").

Dan itu bekerja dengan baik! Masalahnya adalah bahwa kata sandi ECR yang dihasilkan oleh AWS CLI hanya berlaku selama 12 jam. Jadi sekarang, saya harus membuat ulang kata sandi secara manual dua kali sehari dan memperbarui layar kredensial Jenkins secara manual, jika tidak, build saya mulai gagal.

Apakah ada cara untuk menghasilkan token masuk ECR permanen, atau entah bagaimana mengotomatiskan pembuatan token?

Guss
sumber

Jawaban:

6

Ini sekarang dimungkinkan menggunakan amazon-ecr-credential-helper seperti yang dijelaskan dalam https://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repository-for-docker-cli-with-credential-helper/ .

Singkatnya adalah:

  • Pastikan instance Jenkins Anda memiliki kredensial AWS yang tepat untuk menarik / mendorong dengan repositori ECR Anda. Ini bisa dalam bentuk variabel lingkungan, file kredensial bersama, atau profil contoh.
  • Tempatkan biner docker-credential-ecr-login di salah satu direktori dalam $ PATH.
  • Tulis file konfigurasi Docker di bawah direktori home dari pengguna Jenkins, misalnya, /var/lib/jenkins/.docker/config.json. dengan konten{"credsStore": "ecr-login"}
  • Instal plugin Docker Build and Publish dan pastikan bahwa pengguna jenkins dapat menghubungi daemon Docker.
  • Terakhir, buat proyek dengan langkah build yang menerbitkan gambar buruh pelabuhan
Klugscheißer
sumber
4

Seperti yang dikatakan @Connor McCarthy, sambil menunggu Amazon muncul dengan solusi yang lebih baik untuk kunci yang lebih permanen, sementara itu kita perlu membuat kunci pada server Jenkins sendiri.

Solusi saya adalah memiliki pekerjaan berkala yang memperbarui kredensial Jenkins untuk ECR setiap 12 jam secara otomatis, menggunakan API Groovy. Ini didasarkan pada jawaban yang sangat terperinci ini , walaupun saya melakukan beberapa hal secara berbeda dan saya harus memodifikasi skripnya.

Langkah:

  1. Pastikan master Jenkins Anda dapat mengakses API AWS yang diperlukan. Dalam pengaturan saya master Jenkins berjalan pada EC2 dengan peran IAM, jadi saya hanya perlu menambahkan izin ecr:GetAuthorizationTokenke peran server. [ Update ] Untuk mendapatkan dorongan menyelesaikan berhasil, Anda juga akan perlu untuk memberikan izin ini: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage. Amazon memiliki kebijakan bawaan yang menawarkan kemampuan ini, yang disebut AmazonEC2ContainerRegistryPowerUser.
  2. Pastikan bahwa AWS CLI diinstal pada master. Dalam pengaturan saya, dengan master berjalan dalam wadah buruh pelabuhan debian, saya baru saja menambahkan langkah pembuatan shell ini ke pekerjaan pembuatan kunci: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. Instal plugin Groovy yang memungkinkan Anda untuk menjalankan skrip Groovy sebagai bagian dari sistem Jenkins.
  4. Di layar kredensial, cari kunci AWS ECR Anda, klik "Advanced" dan catat "ID" -nya. Untuk contoh ini saya akan menganggap itu "12345".
  5. Buat pekerjaan baru, dengan peluncuran berkala 12 jam, dan tambahkan langkah membangun "skrip sistem Groovy" dengan skrip berikut:

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)
}

Tolong dicatat:

  • penggunaan string kode keras "AWS"sebagai nama pengguna untuk kredensial ECR - ini adalah cara kerja ECR, tetapi jika Anda memiliki beberapa kredensial dengan nama pengguna "AWS", maka Anda harus memperbarui skrip untuk menemukan kredensial berdasarkan kredensial ECR. bidang deskripsi atau sesuatu.
  • Anda harus menggunakan ID asli dari kunci ECR Anda yang sebenarnya dalam skrip, karena API untuk kredensial menggantikan objek kredensial dengan objek baru alih-alih hanya memperbaruinya, dan pengikatan antara langkah pembuatan Docker dan kuncinya adalah dengan ID. Jika Anda menggunakan nilai nulluntuk ID (seperti dalam jawaban yang saya tautkan sebelumnya), maka ID baru akan dibuat dan pengaturan kredensial pada langkah pembuatan buruh pelabuhan akan hilang.

Dan itu saja - skrip harus dapat berjalan setiap 12 jam dan menyegarkan kredensial ECR, dan kita dapat terus menggunakan plugin Docker.

Guss
sumber
3

Saya juga melihat ke masalah yang sama persis ini. Saya tidak menemukan jawaban yang kami cari, tapi saya bisa membuat solusi dengan skrip shell. Sampai AWS keluar dengan solusi yang lebih baik untuk kredensial ECR, saya berencana melakukan sesuatu di sepanjang garis ini.

Saya mengganti langkah Docker Build dan Publish dari pekerjaan Jenkins dengan dan Execute Shell step. Saya menggunakan skrip berikut (mungkin bisa ditulis lebih baik) untuk membangun dan menerbitkan wadah saya ke ECR. Ganti variabel dalam kurung <> sesuai kebutuhan:

#!/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}
Connor McCarthy
sumber
Kedengarannya sangat masuk akal. masalahnya - saya suka Docker Build and Publish, dan saya lebih suka terus menggunakannya, karena menyederhanakan hidup saya. Saya memiliki beberapa penampung kontainer dalam sistem, dan ingin menambahkan lebih banyak, dan mengintegrasikan skrip itu ke setiap build lebih merepotkan daripada yang ingin saya jalani. Saya punya solusi alternatif yang saya tambahkan sebagai jawaban.
Guss
2

Menggunakan https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR dengan plugin Docker Build and Publish berfungsi dengan baik.

Danilo
sumber
Saya telah menginstalnya - tetapi tidak tahu apa yang harus dilakukan dengan itu: ia tidak memiliki konfigurasi dan tidak ada UI.
Guss
Instal pengaya. Di langkah Docker Build and Publish Anda memiliki drop-down yang disebut "Registry kredensial". Klik "Tambah" di sebelahnya, pilih sebagai ketik "Kredensial AWS" dalam dialog. Masukkan kunci akses / kunci rahasia.
Danilo
Sekarang saya mengerti. Sayang sekali tidak mendukung profil instan.
Guss
Iya. Tetapi untuk sekarang saya lebih suka solusi ini.
Danilo