Integre o Amazon Elastic Container Registry ao Jenkins

9

Estou tentando integrar o novo Elastic Container Registry (ECR) da Amazon ao meu serviço de criação do Jenkins. Estou usando o Cloudbees Docker Build & Publique o plug-in para criar imagens de contêiner e publicá-las em um registro.

Para usar o ECR em vez do meu registro particular, executei o comando aws --region us-east-1 ecr get-login da AWS CLI que emitiu um comando docker login para executar - mas copiei a senha e criei as credenciais do Jenkins do tipo "Username with senha "da senha (o nome de usuário é sempre" AWS ").

E isso funciona bem! O problema é que a senha do ECR gerada pelo AWS CLI é válida apenas por 12 horas. Então, agora, tenho que regenerar manualmente a senha duas vezes por dia e atualizar a tela de credenciais do Jenkins manualmente, caso contrário, minhas compilações começam a falhar.

Existe uma maneira de gerar tokens de login ECR permanentes ou de alguma forma automatizar a geração de tokens?

    
por Guss 23.12.2015 / 08:12

4 respostas

4

Como disse @Connor McCarthy, enquanto esperávamos que a Amazon apresentasse uma solução melhor para chaves permanentes, nesse meio tempo nós precisaríamos gerar as chaves do servidor Jenkins de alguma forma.

Minha solução é ter um job periódico que atualize as credenciais do Jenkins para o ECR a cada 12 horas automaticamente, usando a API do Groovy. Isto é baseado em esta resposta muito detalhada , embora eu tenha feito algumas coisas de forma diferente e eu teve que modificar o script.

Etapas:

  1. Verifique se seu mestre do Jenkins pode acessar a API da AWS necessária. Na minha configuração, o mestre do Jenkins está sendo executado no EC2 com uma função do IAM, portanto, precisei adicionar a permissão ecr:GetAuthorizationToken à função de servidor. [ update ] Para que os pushes sejam concluídos com êxito, você também precisa conceder estas permissões: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage . A Amazon tem uma política interna que oferece esses recursos, chamados AmazonEC2ContainerRegistryPowerUser .
  2. Verifique se o AWS CLI está instalado no mestre. Na minha configuração, com o mestre executando em um contêiner do Docker do Debian, acabei de adicionar esta etapa de criação do shell ao trabalho de geração de chave: 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. Instale o plug-in do Groovy que permite executar o script Groovy como parte do sistema Jenkins .
  4. Na tela de credenciais, procure sua chave ECR do AWS, clique em "Avançado" e registre seu "ID". Para este exemplo, vou assumir que é "12345".
  5. Crie uma nova tarefa, com um lançamento periódico de 12 horas, e adicione uma etapa de criação "script Groovy do sistema" com o seguinte 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)
}

Por favor, note:

  • o uso da string codificada "AWS" como o nome de usuário das credenciais ECR - é assim que a ECR funciona, mas se você tiver várias credenciais com o nome de usuário "AWS", será necessário atualizar o script para localize as credenciais com base no campo de descrição ou algo assim.
  • Você deve usar o ID real de sua chave ECR real no script, porque a API para credenciais substitui o objeto de credenciais por um novo objeto em vez de apenas atualizá-lo, e a ligação entre a etapa de compilação do Docker e a chave é o ID. Se você usar o valor null para a ID (como na resposta que eu vinculei antes), uma nova ID será criada e a configuração das credenciais na etapa de compilação da janela de encaixe será perdida.

E é isso. O script deve ser executado a cada 12 horas e atualizar as credenciais do ECR, e podemos continuar a usar os plug-ins do Docker.

    
por 23.12.2015 / 19:37
6

Agora é possível usar amazon-ecr-credential-helper conforme descrito em link .

O mais curto é:

  • Assegure-se de que sua instância do Jenkins tenha as credenciais adequadas da AWS para extrair / enviar seu repositório ECR. Eles podem estar na forma de variáveis de ambiente, um arquivo de credencial compartilhado ou um perfil de instância.
  • Coloque o binário docker-credential-ecr-login em um dos diretórios em $ PATH.
  • Grave o arquivo de configuração do Docker no diretório inicial do usuário do Jenkins, por exemplo, /var/lib/jenkins/.docker/config.json. com o conteúdo {"credsStore": "ecr-login"}
  • Instale o plug-in do Docker Build e Publish e certifique-se de que o usuário do jenkins possa entrar em contato com o daemon do Docker.
  • Por fim, crie um projeto com uma etapa de criação que publique a imagem do docker
por 27.10.2016 / 23:22
3

Eu estava analisando exatamente o mesmo problema também. Eu não encontrei a resposta que estávamos procurando, mas consegui criar uma solução com scripts de shell. Até que a AWS saia com uma solução melhor para as credenciais do ECR, planejo fazer algo nesse sentido.

Substitui a etapa de Construção e Publicação do Docker da tarefa do Jenkins por e execute a etapa do Shell. Eu usei o seguinte script (provavelmente poderia ser escrito melhor) para criar e publicar meu contêiner para ECR. Substitua as variáveis em < > parênteses conforme necessário:

#!/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}
    
por 23.12.2015 / 18:11
1

Usar link com o plug-in Docker Build and Publish funciona bem.

    
por 26.01.2016 / 10:40