티스토리 뷰

CI, CD

빠른 생산성을 가져가지 위해 통합(Intergration)과 배포(Delivery) 단계를 자동화하고 지속적인 배포 환경을 구성하는 것에 대한 중요성이 커지게 되었습니다.

 

저 같은 경우 기존에는 배포와 인프라 환경에 대한 운영을 FTP와 SSH를 이용하여 수동으로 하고 있었지만 이번에 Jenkins와 Elastic Beanstalk을 이용해서 통합과 배포를 자동화하게 되었고 이전에 비해 생산성 관점에서 많은 이득을 보았다고 생각합니다.

 

이 글에서는 이와 관련하여 경험을 공유하고자 합니다.

우선 목표하는 구성은 다음과 같습니다.

 

클릭하시면 자세히 볼수 있어요!

 

1. Github에 소스를 push를 합니다.

2. Github에서 Jenkins로 WebHook을 날리게 됩니다.

3. Jenkins에서는 소스를 war로 빌드 후 S3에 업로드하고 난 후 Elastic Beanstalk으로 Deploy 명령을 내리게 됩니다.

4. Eleastic Beanstalk은 S3에 업로드된 war파일을 가지고 각 서버로 배포를 진행하게 됩니다.

 

 

 

내용이 많기 때문에 총 3개의 파트로 나눠서 하나하나 자세히 정리해보도록 하겠습니다.

 

Elastic Beanstalk과 Jenkins로 CI, CD 구축하기 (Part1. Elastic Beanstalk 구축)

Elastic Beanstalk과 Jenkins로 CI, CD 구축하기 (Part2. Jenkins 설치)

Elastic Beanstalk과 Jenkins로 CI, CD 구축하기 (Part3. Jenkins Pipeline 구성)

 

 

1. Spring 프로젝트 생성

Java 1.8, Spring Boot 2.x, Thymeleaf, Gradle, Intellij IDEA 환경으로 프로젝트를 생성합니다.

여기서 핵심은 서버에 배포할 war 파일을 생성하는 것이기 때문에 꼭 위의 기술 스택을 사용할 필요는 없습니다.

 

1.1 New Project

File > New > Project에서 Spring Initializr를 선택하고 SDK는 Java 1.8을 선택합니다.

 

 

 

Gradle Project를 선택하고 Packaging은 war로 선택합니다.

 

 

 

Dependency는 간단하게 Spring Web과 Thymeleaf만 추가하도록 하겠습니다.

 

 

 

HomeController와 home.html 파일을 만들고 bootRun Task를 구동하여 프로젝트를 시작해보죠.

간단한 소스지만 향후 Jenkins 연동을 위해 GitHub에 등록해 놓도록 하겠습니다.

 

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home";
    }

}

HomeController.java

 

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>SpringBoot Thymeleaf 예제</title>
</head>
<body>
    Hello World!!
</body>
</html>

home.html

 

 

실행화면

 

 

 

1.2 war 파일 생성

이제 Elastic Beanstalk에 등록하기 위한 war파일 생성해 보겠습니다.

 

나중에 Jenkins에서 build 후 생성 된 war파일을 편리하게 검색하기 위해 생성되는 파일명을 application.war로 변경해보도록 하겠습니다.

 

build.gradle에 아래 코드를 추가해 줍니다.

bootWar {
    archiveFileName = 'application.war'
}

 

 

Gradle 도구에서 build > bootWar를 구동하게 되면 build > libs 하위에 war파일이 생성됩니다.

 

 

 

 

2. Elastic Beanstalk 생성

이제 본격적으로 Beanstalk을 생성해보도록 하겠습니다.

AWS 서비스에서 컴퓨팅 > Elastic Beanstalk을 선택하고 새 애플리케이션 생성을 선택합니다.

 

 

 

애플리케이션 이름을 정한 후 생성을 눌러보죠.

 

 

 

새로운 애플리케이션이 생성되었습니다. 아직은 환경설정을 하지 않았기 때문에 아무것도 보이지 않습니다.

오른쪽에 작업을 눌러서 나오는 목록 중에 환경 생성을 눌러보겠습니다.

 

 

 

2.1 환경 티어 선택

환경 티어를 선택하는 화면이 나옵니다.

SQS 메시지를 처리하기 위한 Worker를 생성하려면 작업자 환경을 선택하면 되지만 이번에는 웹 애플리케이션을 구축하는 것이 목적이기 때문에 웹 서버 환경을 선택합니다.

 

 

 

2.2 웹 서버 환경 생성

이제 웹 서버 환경에 대한 기본 구성을 선택해야 합니다.

 

환경 이름과 도메인에는 springbootthymeleaf-sample, 플랫폼은 Tomcat, 애플리케이션 코드에는 샘플 애플리케이션을 선택하도록 하겠습니다. 참고로 도메인은 굳이 입력하지 않아도 자동으로 생성됩니다.

 

다음으로 환경 생성 전에 추가 옵션 구성을 통해 몇 가지를 더 설정하도록 하겠습니다.

제가 지식이 부족하여 찾지 못한 걸 수도 있으나 여러 번 테스트해본 결과 이대로 환경 생성을 해버리면 이후에 어떤 설정들은 다시 변경할 수 없는 것으로 확인되었습니다. (ex.. 로드 밸런서 유형, 배포 방식)

 

 

 

2.3 추가 옵션 구성

이 단계에서는 인스턴스 유형 설정이나 보안 그룹 설정, 로드 밸런싱 유형 설정, 배포 방식 설정 등 다양한 설정이 가능합니다.

이 글에서는 로드 밸런서 유형을 application으로 가져가고 배포 방식은 롤링 방식으로 가져가기 위해 몇 가지를 변경해보도록 하겠습니다. 먼저 구성 사전 설정에서 저비용으로 설정되어 있는 옵션을 사용자 지정 구성으로 바꿉니다. 

 

 

 

 

용량 항목을 보면 환경 유형이 단일 인스턴스에서 로드 밸런싱, Auto Scaling 유형으로 변경된 것으로 확인할 수 있습니다. 여기에서 최소, 최대 인스턴스 지정이 가능한데 1대만 설정하게 되면 배포 시 다운타임이 발생하기 때문에 최소 인스턴스는 2대로 가져가도록 하겠습니다.

 

 

 

다음으로 배포 방식을 변경해보도록 하겠습니다.

Beanstalk에서 제공하는 배포 방식에는 크게 4가지가 있습니다.

 

1. All at once : 모든 인스턴스에 동시에 새 버전을 배포

2. Rolling : 배치 단위로 새 버전 배포

3. Rolling with additional batch : 배치 단위로 새 버전 배포, +1 추가 배치

4. Immutable : 새로운 인스턴스 그룹에 배포

 

참고로 Immutable은 Blue/Green 배포 방식과는 조금 차이가 있습니다.

각 배포 방식에 대한 설명과 Blue/Green 배포 방식과의 차이는 AWS DevDay2018에서 발표한 영상에서 자세히 설명하고 있습니다.

 

참고 : AWS Elastic Beanstalk 활용하여 수 분만에 코드 배포하기 https://youtu.be/AfRnvsRxZ_0?t=1724

 

각 배포 방식마다 장단점이 존재하며 각자의 상황에 맞게 배포 전략을 세우는 걸 추천드립니다.

이 글에서는 Rolling 방식으로 배포 옵션을 지정하고 한 번에 1개의 인스턴스에 배포하는 걸로 설정하도록 하겠습니다.

 

 

 

 

 

 

설정이 마무리되었으면 환경을 생성합니다. 생성에는 약 5 분 정도 소요되는 것 같습니다.

 

생성중..

 

생성 완료!!

 

 

정상적으로 환경이 구성되었는지 확인하기 위해 몇 가지를 확인해보죠.

먼저 Beanstalk에서 생성해준 URL로 접속을 해보겠습니다.

 

 

 

샘플 애플리케이션에 접속되는 걸 보실 수 있습니다.

 

이전에 환경 설정 시 최소 인스턴스 2대와 application 유형의 로드 밸런서를 설정하였기 때문에 정상적으로 생성되었는지 확인해보도록 하겠습니다.

 

2개의 인스턴스가 생성되어 있습니다.
application 유형의 로드밸런서 1개가 생성되어 있습니다.

 

 

 

3. 배포

먼저 수동으로 배포를 해보도록 하겠습니다.

실제로 프로덕션 환경을 구성하기 위해서는 도메인 연결, 보안 및 모니터링, 로그 처리 등 훨씬 더 많은 작업이 필요하겠으나 최소한의 설정으로 Beanstalk을 구성해보는 걸 목표로 잡았기 때문에 바로 배포를 진행해서 결과를 확인해보도록 하겠습니다.

 

대시보드에서 업로드 및 배포를 선택합니다.

 

 

 

 

war파일을 선택하고 버전 레이블을 입력한 후 배포를 선택합니다.

이제 한 번에 1대의 인스턴스마다 배포를 시작하게 됩니다.

 

 

 

 

이벤트 항목에서 배포에 대한 자세한 진행사항을 확인하실 수 있습니다.

 

 

1번 서버가 먼저 배포되고 난 후 로드 밸런서의 상태를 확인합니다.

만약 정상적이라면 2번 서버의 배포가 시작되는 걸 확인하실 수 있습니다.

 

 

배포가 모두 완료되었으면 다시 URL에 접근해서 정상적으로 접속되는지 확인해보도록 하겠습니다.

 

잘 접속되고 원하는 결과물이 나오는 것으로 확인됩니다.

 

 

 

4. 롤백

프로덕션 환경에 배포 시에는 항상 롤백에 대한 방안을 마련 후 배포하는 것이 좋습니다.

Blue/Green 배포 시에는 이전 환경과 URL Swapping을 통해 롤백이 가능하지만 나머지 배포 방식에서는 이전 버전의 애플리케이션을 다시 재배포하는 방식으로 롤백이 가능합니다. 이를 위해서 Beanstalk은 애플리케이션별로 버전을 관리하고 이전 버전 다운로드를 다시 배포할 수 있도록 기능을 제공합니다.

 

 

애플리케이션 버전 메뉴에서 그동안 업로드된 애플리케이션들이 표시됩니다.

롤백은 원하는 버전을 선택 후 작업 > 배포를 선택하시면 해당 버전으로 재배포되는 것을 확인하실 수 있습니다.

 

이번에는 Sample Application으로 되돌려보도록 하겠습니다.

 

 

 

 

 

 

URL에 접근하시면 다시 Sample Application으로 롤백된 것을 확인하실 수 있습니다.

 

 

 

다음 글에서는 EC2를 생성하고 Jenkins를 설치를 진행해 보도록 하겠습니다.

최근에 올라온 글
Total
Today
Yesterday
링크