본문 바로가기
카테고리 없음

AWS ECR과 ECS를 이용한 CI/CD 구현(3)

by sum_mit45 2024. 11. 21.
728x90
반응형
11월 15일(금) ~ 11월 18일(월) 수업 중

 

AWS Elastic Container Registry(ECR) Elastic Container Service(ECS)를 활용하면 애플리케이션 배포 프로세스를 자동화하여 안정성과 효율성을 극대화할 수 있다. ECR과 ECS를 활용한 CI/CD 파이프라인을 단계별로 구축하는 방법을 정리하였다.

 

전체 목차는 아래와 같다.

0. ECR과 ECS 소개
1. Spring Boot 프로젝트 생성
2. Docker 이용한 CI/CD 적용
3. Git Ops 설정
4. Docker Hub와 연동하여 이미지 빌드 및 배포 자동화
5. AWS ECR(Elastic Container Registry)
6. GitHub Actions에서 ECR에 접근 설정
7. AWS ECS(Elastic Container Service)
8. Github Actions에서 ECS 적용하기 => CD

 

이전 단계는 아래 두 곳에서 확인 가능하다.

2024.11.19 - [분류 전체보기] - AWS ECR과 ECS를 이용한 CI/CD 구현(1)

 

AWS ECR과 ECS를 이용한 CI/CD 구현(1)

11월 15일(금) ~ 11월 18일(월) 수업 중 AWS Elastic Container Registry(ECR)와 Elastic Container Service(ECS)를 활용하면 애플리케이션 배포 프로세스를 자동화하여 안정성과 효율성을 극대화할 수 있다. ECR과 ECS를

sum-mit45.tistory.com

 

7. AWS ECS(Elastic Container Service)

AWS ECS(Amazon Elastic Container Service)는 컨테이너화된 애플리케이션을 쉽게 실행, 관리, 확장할 수 있도록 돕는 AWS의 관리형 서비스

 

각 코드에 대한 자세한 설명은 아래 글에서 확인해 볼 수 있다. 

2024.11.18 - [분류 전체보기] - [AWS] Amazon Elastic Container Service(ECS) 서비스: 클러스터 생성과 서비스 배포

 

[AWS] Amazon Elastic Container Service(ECS) 서비스: 클러스터 생성과 서비스 배포

11월 18일(월) AWS 실습 내용 중 Amazon Elastic Container Service (ECS)는 AWS에서 제공하는 확장 가능한 컨테이너 관리 서비스로, 도커 컨테이너를 클라우드에서 손쉽게 실행하고 관리할 수 있도록 도와준

sum-mit45.tistory.com

Cluster 생성

(7-1) ECR 접속해서 Cluster 생성

ECS > [클러스터 생성]

(7-2) Cluster 구성

클러스터 구성

  • 클러스터 이름: cicdcluster => 이후에 github actions yaml 파일에서 활용한다. 
  • 인프라: AWS Fargate(서버리스)를 활용했다. 

(7-3) 생성된 Cluster 확인

생성된 클러스터 확인

 

아직은 태스크와 서비스를 만들지 않았기 때문에 서비스 값은 0이고, 실행 중인 태스크도 없다고 나온다. 

Task 생성

(7-4) ECR 접속해서 [태스크 정의] > [새 태스크 정의 생성]

ECS > 태스크 정의 > 새 태스크 정의 생성

(7-5) 태스크 정의 구성

태스크 정의 구성

  • 태스크 정의 패밀리: awscicd
  • 인프라 요구사항: 시작 유형을 AWS Fargate(서버리스)로 선택한다. 

컨테이너 구성

  • 태스크 내에 컨테이너를 생성한다.
  • 이름: awscicd
  • 이미지 URI: nginx => 기존의 docker hub에 있는 nginx 이미지를 가져온다. 
  • 그 외는 기본 설정과 동일하게 한다.

(7-6) 생성된 태스크 확인

생성된 태스크 확인

Service 생성

(7-7) ECR 접속해서 특정 클러스터 선택 후 [서비스 생성]

ECR > 클러스터 선택 > 서비스 생성

(7-8) 서비스 - 환경

서비스 환경 설정

  • 컴퓨팅 구성: [시작 유형]

(7-9) 서비스 - 배포 구성

서비스 배포 구성

  • 애플리케이션 유형: 서비스
  • 태스크 패밀리: awscicd 선택 (위에서 만든 태스크 패밀리 선택)
  • 서비스 이름: awscicd
  • 원하는 태스크: 3 (3개의 태스크가 한 서비스로 띄워진다.)

(7-10) 서비스 - 네트워킹

서비스 네트워킹

  • 기존의 설정을 활용한다. 주의할 점은 해당 보안그룹의 포트를 열었는지 확인해봐야 한다. 

(7-11) 서비스 - 로드 밸런싱

서비스 로드밸런싱

  • 로드 밸런서 유형: Application Load Balancer
  • 로드 밸런서 이름: awscicdlb 
  • 이렇게 설정한 이후에 나머지는 수정하지 않고, 서비스를 [생성]한다. 

(7-12) 생성된 서비스 확인

생성된 서비스 확인

(7-13) 로드밸런서 DNS로 실행 확인하기

클러스터 > 로드 밸런서 보기

  • 내가 생성한 [클러스터]를 누르고 [로드 밸런서 보기]를 클릭한다. 
  • 아래의 [DNS 이름]을 이용해서 내가 만든 Nginx 서버로 들어갈 수 있다. (포트는 80을 사용했다.)

DNS 이름

  • Welcome to nginx! 화면이 나오면 성공한 것이다. 

접속 화면 확인

8. Github Actions에서 ECS 적용하기

위에서 설정한 ECS를 적용하기 위해서 yaml 파일을 수정해주어야 한다. 

task json 파일 다운로드

(8-1) ECR > [태스크] > [JSON]

  • ECR 서비스에 접속해서, [태스크 정의] > 해당 태스크 선택 > [JSON] > [JSON 다운로드] 클릭해서 해당 파일을 다운받는다.
  • 맨 위에 task-definition.json 으로 이름을 변경해서 올린다. (파일명은 yaml파일에 따라 수정해도 된다.)

태스크 json 파일 다운로드
해당 위치에 파일을 올린다.

yaml 파일 수정

(8-2) yaml 파일 수정

전체 yaml 파일을 아래와 같다. 이제는 AWS의 repository를 사용하므로 docker hub 관련된 코드는 지워도 된다.

name: Java and AWS ECS CICD
on:
  push:
    branches: [ "main" ]

permissions:
  id-token: write
  contents: read

env:
  AWS_REGION: ap-northeast-2
  ECR_REPOSITORY: cicd
  ECS_CLUSTER: cicdcluster
  ECS_SERVICE: awscicd
  CONTAINER_NAME: awscicd
  ECS_TASK_DEFINITION: ./task-definition.json

jobs:
  build-docker-image:
    runs-on: ubuntu-latest
    steps:
      #소스 코드 가져오기
      - uses: actions/checkout@v3

      #JDK 설치
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      #Spring Boot Application Build
      - name: Build with Gradle
        uses: gradle/gradle-build-action@v3
        with:
          arguments: clean bootJar

      #AWS 로그인
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::575108919464:role/cicdrole
          role-session-name: sampleSeesionName
          aws-region: ap-northeast-2

      #ECR 로그인
      - name: Login to ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a

      #이미지를 등록하고 ECR에 Push
      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

      # task를 수정하는 작업
      - name: Fill in the new image ID in the Amazon ECS Task Definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@c804dfbdd57f713b6c079302a4c01db7017a36fc
        with:
          task-definition: ${{ env.ECS_TASK_DEFINITION }}
          container-name: ${{ env.CONTAINER_NAME }}
          image: ${{ steps.build-image.outputs.image }}

      # ECS에 태스크를 배포
      - name: Deploy Amazon ECS Task Definition
        uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          wait-for-service-stability: true

      #Docker Hub 로그인
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      #이미지 업로드
      - name: build and release
        run: |
          docker build -t ${{ secrets.DOCKERHUB_REPOSITORY }} .
          docker tag ${{ secrets.DOCKERHUB_REPOSITORY }}:latest ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY }}:latest
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY }}:latest

 

추가된 코드의 부분은 아래와 같다.

env:
  AWS_REGION: ap-northeast-2
  ECR_REPOSITORY: cicd
  ECS_CLUSTER: cicdcluster
  ECS_SERVICE: awscicd
  CONTAINER_NAME: awscicd
  ECS_TASK_DEFINITION: ./task-definition.json
  • ECS_CLUSTER, ECS_SERVICE, CONTAINER_NAME: 만든 클러스터, 서비스 등에 따라서 바꾸면 된다. 
  • ECS_TASK_DEFINITION: 위에서 다운로드 받은 json 파일의 이름과 경로에 맞게 설정한다. 
# task를 수정하는 작업
- name: Fill in the new image ID in the Amazon ECS Task Definition
  id: task-def
  uses: aws-actions/amazon-ecs-render-task-definition@c804dfbdd57f713b6c079302a4c01db7017a36fc
  with:
    task-definition: ${{ env.ECS_TASK_DEFINITION }}
	container-name: ${{ env.CONTAINER_NAME }}
	image: ${{ steps.build-image.outputs.image }}

 

Amazon ECS 태스크 정의 파일(task-definition)을 업데이트하여 새로 빌드된 Docker 이미지의 ID를 지정하는 작업

  • aws-actions/amazon-ecs-render-task-definition: ECS 태스크 정의에서 컨테이너 이미지를 최신 이미지로 교체
  • task-definition: 수정할 ECS 태스크 정의 파일 경로
  • container-name: 업데이트할 컨테이너의 이름
  • image: 빌드된 Docker 이미지 ID (이전 단계에서 생성된 이미지 ID를 사용)
# ECS에 태스크를 배포
- name: Deploy Amazon ECS Task Definition
  uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
  with:
    task-definition: ${{ steps.task-def.outputs.task-definition }}
    service: ${{ env.ECS_SERVICE }}
    cluster: ${{ env.ECS_CLUSTER }}
    wait-for-service-stability: true

 

Amazon ECS에 새로 수정된 태스크 정의를 배포하는 작업

  • aws-actions/amazon-ecs-deploy-task-definition: ECS 클러스터에서 지정한 서비스에 새로운 태스크 정의를 배포
  • task-definition: 배포할 ECS 태스크 정의 (이전 단계에서 생성된 태스크 정의 출력)
  • service: 배포할 ECS 서비스 이름
  • cluster: 배포할 ECS 클러스터 이름
  • wait-for-service-stability: 서비스의 안정성이 확보될 때까지 기다립니다 (true로 설정되어 있어 안정성이 보장될 때까지 대기)

위의 ECS 주소로 접속해서 Spring Boot의 작업사항이 배포된 것 확인하기

728x90
반응형