Integrare Amazon Elastic Container Registry con Jenkins


10

Sto cercando di integrare il nuovo Elastic Container Registry (ECR) di Amazon con il mio servizio di build Jenkins. Sto usando il plug-in Cloudbees Docker Build & Publish per creare immagini container e pubblicarle in un registro.

Per utilizzare ECR invece del mio registro privato, ho eseguito il comando AWS CLI aws --region us-east-1 ecr get-loginche emette un docker logincomando da eseguire - ma ho appena copiato la password e creato una credenziale Jenkins di tipo "Nome utente con password" da quella password (il nome utente è sempre "AWS").

E funziona benissimo! Il problema è che la password ECR generata dalla CLI AWS è valida solo per 12 ore. Quindi in questo momento, devo rigenerare manualmente la password due volte al giorno e aggiornare manualmente la schermata delle credenziali di Jenkins, altrimenti le mie build iniziano a fallire.

Esiste un modo per generare token di accesso ECR permanenti o in qualche modo automatizzare la generazione di token?

Risposte:


6

Questo è ora possibile usando amazon-ecr-credential-helper come descritto in https://aws.amazon.com/blogs/compute/authenticating-amazon-ecr-repositories-for-docker-cli-with-credential-helper/ .

Il corto è:

  • Assicurati che l'istanza di Jenkins disponga delle credenziali AWS appropriate per eseguire il pull / push con il repository ECR. Questi possono essere sotto forma di variabili di ambiente, un file di credenziali condiviso o un profilo di istanza.
  • Posiziona il file binario docker-credential-ecr-login in una delle directory in $ PATH.
  • Scrivi il file di configurazione Docker nella directory home dell'utente Jenkins, ad esempio /var/lib/jenkins/.docker/config.json. con il contenuto{"credsStore": "ecr-login"}
  • Installa il plugin Docker Build and Publish e assicurati che l'utente jenkins possa contattare il demone Docker.
  • Infine, crea un progetto con un passaggio di creazione che pubblica l'immagine della finestra mobile

4

Come ha detto @Connor McCarthy, aspettando che Amazon trovasse una soluzione migliore per chiavi più permanenti, nel frattempo avremmo bisogno di generare le chiavi sul server Jenkins in qualche modo.

La mia soluzione è quella di avere un lavoro periodico che aggiorni automaticamente le credenziali Jenkins per ECR ogni 12 ore, usando l'API Groovy. Questo si basa su questa risposta molto dettagliata , anche se ho fatto alcune cose in modo diverso e ho dovuto modificare lo script.

passi:

  1. Assicurati che il tuo master Jenkins possa accedere all'API AWS richiesta. Nella mia configurazione il master Jenkins è in esecuzione su EC2 con un ruolo IAM, quindi ho dovuto solo aggiungere l'autorizzazione ecr:GetAuthorizationTokenal ruolo del server. [ Aggiornamento ] per ottenere qualsiasi spinte completare con successo, si sarebbe anche necessario concedere queste autorizzazioni: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage. Amazon ha una politica integrata che offre queste funzionalità, chiamata AmazonEC2ContainerRegistryPowerUser.
  2. Assicurati che la CLI AWS sia installata sul master. Nella mia installazione, con il master in esecuzione in un contenitore docker debian, ho appena aggiunto questo passaggio di creazione della shell al lavoro di generazione delle chiavi: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. Installa il plugin Groovy che ti permette di eseguire lo script Groovy come parte del sistema Jenkins.
  4. Nella schermata delle credenziali, cerca la chiave ECS di AWS, fai clic su "Avanzate" e registra il suo "ID". Per questo esempio suppongo sia "12345".
  5. Crea un nuovo lavoro, con un lancio periodico di 12 ore, e aggiungi un passaggio di build "script Groovy di sistema" con il seguente 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)
}

Notare che:

  • l'uso della stringa hard coded "AWS"come nome utente per le credenziali ECR: ecco come funziona ECR, ma se si dispone di più credenziali con il nome utente "AWS", è necessario aggiornare lo script per individuare le credenziali in base alla campo della descrizione o qualcosa del genere.
  • È necessario utilizzare l'ID reale della chiave ECR reale nello script, poiché l'API per le credenziali sostituisce l'oggetto credenziali con un nuovo oggetto anziché semplicemente aggiornarlo e l'associazione tra il passaggio di creazione Docker e la chiave è tramite l'ID. Se si utilizza il valore nullper l'ID (come nella risposta che ho collegato in precedenza), verrà creato un nuovo ID e l'impostazione delle credenziali nella fase di creazione della finestra mobile andrà persa.

E questo è tutto: lo script dovrebbe essere in grado di funzionare ogni 12 ore e aggiornare le credenziali ECR e possiamo continuare a utilizzare i plugin Docker.


3

Stavo esaminando anche questo stesso identico problema. Non ho trovato la risposta che nessuno di noi cercava, ma sono stato in grado di creare una soluzione alternativa con gli script di shell. Fino a quando AWS non presenterà una soluzione migliore alle credenziali ECR, ho intenzione di fare qualcosa di simile.

Ho sostituito il passaggio Creazione e pubblicazione Docker del processo Jenkins con il passaggio Esegui shell. Ho usato il seguente script (probabilmente potrebbe essere scritto meglio) per creare e pubblicare il mio contenitore in ECR. Sostituire le variabili tra parentesi <> secondo necessità:

#!/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}

Sembra molto ragionevole. il fatto è che mi piace Docker Build and Publish, e piuttosto continuo a usarlo, perché mi semplifica la vita. Ho diverse build di container nel sistema, e voglio aggiungerne altre, e l'integrazione di quello script per ogni build è più una seccatura di quella con cui sono disposto a convivere. Ho una soluzione alternativa che sto aggiungendo come risposta.
Guss,

2

L'uso di https://wiki.jenkins-ci.org/display/JENKINS/Amazon+ECR con il plug-in Docker Build and Publish funziona perfettamente.


L'ho installato, ma non sono riuscito a capire cosa farsene: non ha configurazione né UI.
Guss,

Installa il plugin. Nel passaggio Crea e pubblica Docker è disponibile un menu a discesa chiamato "Credenziali di registro". Fai clic su "Aggiungi" accanto ad esso, seleziona come tipo "Credenziali AWS" nella finestra di dialogo. Immettere la chiave di accesso / chiave segreta.
Danilo,

Ora vedo. Peccato che non supporti i profili di istanza.
Guss,

Sì. Ma per ora preferisco questa soluzione.
Danilo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.