Jenkins에서 ECR로 Docker 이미지를 푸시하는 쉬운 방법

9887 단어 dockerecrjenkins
제 개인적인 글이라 소개 등은 없습니다. 간단히 말해서 GitHub에서 코드를 가져와 Docker 이미지를 빌드합니다. ECS 서비스를 배포하기 위해 이미지를 ECR에 푸시하려고 합니다. 쉘 명령으로 빠르고 간단하게 만들고 싶습니다. 어떻게 작동시키시겠습니까?

Jenkins가 Docker와 작동하도록 만들기



여기에서는 Amazon Linux 2 이미지에서 시작되는 EC2에 Jenkins가 설치되어 있다고 가정합니다. jenkins 사용자를 docker 그룹에 추가해야 합니다.

sudo usermod -aG docker jenkins


완료되면 이미지를 빌드하고 태그를 지정할 수 있습니다.

docker build -t <img name>:v_$BUILD_NUMBER --pull=true /var/lib/jenkins/workspace/<jenkins job name> \
&& docker tag <img name>:v_$BUILD_NUMBER <AWS user ID>.dkr.ecr.<region>.amazonaws.com/<ECR repo name>:v_$BUILD_NUMBER


이제 두통이옵니다. docker push 명령을 사용하여 이미지를 ECR에 푸시하려고 하면 jenkins ECR에 연결할 인증 토큰이 없기 때문에 실패합니다.

토큰 가져오기 및 로그인



토큰을 얻으려면 aws ecr get-login-password (AWS CLI v2, v1 명령이 get-login인 경우)를 실행해야 합니다. 그러나 이는 AWS CLI에 jenkins 에 대한 자격 증명 프로필이 있는 경우에만 작동합니다. 그것이 없으면 오류가 발생합니다: Unable to locate credentials. You can configure credentials by running "aws configure".
문제는 Jenkins의 빌드 내에서 항상 aws configure 실행하고 싶지 않다는 것입니다. 불필요하며 IAM 사용자의 암호를 노출합니다.

내가 한 것은 Jenkins가 설치된 EC2에 SSH로 연결하고 aws configurejenkins 사용자로 실행하는 것입니다.

sudo -H -u jenkins aws configure


ECS 배포를 위해 생성한 IAM 사용자의 모든 키와 암호를 AWS에 제공하면 자격 증명 프로필을 생성할 수 있습니다. 이 프로필의 이름은 default이고 jenkins 사용자를 위해 저장됩니다.

프로필이 주어지면 Jenkins 작업으로 돌아가서 인증 토큰을 가져오고 docker에 로그인해도 됩니다.

aws ecr get-login-password --region <region> --profile=default | docker login --username AWS --password-stdin <AWS user ID>.dkr.ecr.<region>.amazonaws.com


이미지를 ECR로 푸시합니다.

docker push <AWS user ID>.dkr.ecr.<region>.amazonaws.com/<ECR repo name>:v_$BUILD_NUMBER


그것들을 모두 합치면 하나의 Jenkins 빌드 셸 명령이 있습니다.

docker build -t <img name>:v_$BUILD_NUMBER --pull=true /var/lib/jenkins/workspace/<jenkins job name> \
&& docker tag <img name>:v_$BUILD_NUMBER <AWS user ID>.dkr.ecr.<region>.amazonaws.com/<ECR repo name>:v_$BUILD_NUMBER \
&& aws ecr get-login-password --region <region> --profile=default | docker login --username AWS --password-stdin <AWS user ID>.dkr.ecr.<region>.amazonaws.com \
&& docker push <AWS user ID>.dkr.ecr.<region>.amazonaws.com/<ECR repo name>:v_$BUILD_NUMBER


이 셸 명령을 사용하여 Jenkins는 최신 Docker 이미지를 ECR에 푸시할 수 있어야 합니다. 두 번째 셸 명령은 코드를 배포합니다.

#!/bin/bash

REGION=<region>
SERVICE_NAME=<service name>
CLUSTER=<cluster name>
IMAGE_VERSION="v_"${BUILD_NUMBER}
TASK_FAMILY=<task name>

# Create a new task definition for this build

sed -e "s;%BUILD_NUMBER%;${BUILD_NUMBER};g" ./task-def.json > ${TASK_FAMILY}-v_${BUILD_NUMBER}.json

aws ecs register-task-definition --family ${TASK_FAMILY} --cli-input-json file://${TASK_FAMILY}-v_${BUILD_NUMBER}.json

# Update the service with the new task definition and desired count
REVISION=`aws ecs describe-task-definition --task-definition ${TASK_FAMILY} | egrep "revision" | tr "/" " " | awk '{print $2}' | sed 's/"$//'`
SERVICES=`aws ecs describe-services --services ${SERVICE_NAME} --cluster ${CLUSTER} --region ${REGION} | jq .failures[]`


#Create or update service
if [ "$SERVICES" == "" ]; then
  echo "entered existing service"
  DESIRED_COUNT=`aws ecs describe-services --services ${SERVICE_NAME} --cluster ${CLUSTER} --region ${REGION} | jq .services[].desiredCount`
  if [ ${DESIRED_COUNT} = "0" ]; then
    DESIRED_COUNT="1"
  fi
  aws ecs update-service --cluster ${CLUSTER} --region ${REGION} --service ${SERVICE_NAME} --task-definition ${TASK_FAMILY}:${REVISION} --desired-count ${DESIRED_COUNT} --deployment-configuration maximumPercent=100,minimumHealthyPercent=0
else
  echo "entered new service"
  aws ecs create-service --service-name ${SERVICE_NAME} --desired-count 1 --task-definition ${TASK_FAMILY} --cluster ${CLUSTER} --region ${REGION}
fi


사전 요구 사항


  • Amazon Linux 2 이미지를 사용하여 EC2 인스턴스가 시작됨
  • Jeknins가 인스턴스에 설치됨
  • EC2ContainerRegister 정책이 연결된 IAM 사용자가 생성됨
  • 인스턴스의 AWS CLI가 버전 2로 업그레이드됨
  • 소스 코드는 다음과 유사한 파일 구조를 가지고 있습니다.

  • 소스 구조




    \root
       + src  << source code folder
         - source files
       - Dockerfile
       - task-def.json
    

    좋은 웹페이지 즐겨찾기