Home AWS를 사용해 무중단 배포 자동화 환경 구축하기 - 4. 어플리케이션 구축 및 로드밸런서 적용
Post
Cancel

AWS를 사용해 무중단 배포 자동화 환경 구축하기 - 4. 어플리케이션 구축 및 로드밸런서 적용

AWS를 사용해 무중단 배포 자동화 환경 구축하기 시리즈

  1. 개요
  2. VPC와 기본 리소스
  3. VPC와 기본 리소스 생성하기
  4. 어플리케이션 구축 및 로드밸런서 적용
  5. AWS 리소스 세팅
  6. CodeDeploy 연동 / 마무리

어플리케이션 구축 및 로드밸런서 적용

이번 포스팅에서는 간단한 Spring Boot 어플리케이션을 만들어 ec2 인스턴스에 배포하고 로드밸런서를 적용해보도록 하겠습니다.

이 시리즈의 서버 구성은 3-tier 가 아닌 presentation, logic 티어가 한 티어에 존재하는 일종의 2-tier 구성 입니다. 3-tier 와의 차이점은 웹(nginx, apache 등)과 어플리케이션(react, spring boot 등)이 프록시 설정을 적용한 한개의 인스턴스에 존재한다는 점입니다. 3-tier 로 구성하려면 presentation(web), logic(was) 티어 간의 통신에 NLB(Network Load Balancer)를 사용하면 되며 이 시리즈를 잘 이해하신다면 쉽게 적용하실 수 있을 것이라 생각됩니다.

Spring Boot 어플리케이션 만들기

현재 호스트ip와 접근ip를 리턴하는 메소드 한개를 가진 간단한 Spring Boot 어플리케이션을 만들었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @GetMapping("/ip")
    public Map<String, String> ip(HttpServletRequest request) throws UnknownHostException {
        return new HashMap<>() {{
            put("hostIp", InetAddress.getLocalHost().getHostAddress());
            put("accessIp", request.getHeader("x-forwarded-for"));
        }};
    }

}

어플리케이션을 만들었다면 jar 파일(혹은 war 파일) 로 빌드 후 프라이빗 서브넷 내부 인스턴스에 옮겨둬야 합니다. 프라이빗 서브넷에 다이렉트로 접근하는 방법(SSH Tunneling 등)에 대해 모르고 계신다면 어쩔 수 없이 Bastion Host에 한번 옮기고 각각의 인스턴스에 다시 파일을 전송해야 합니다. 저는 scp 명령어를 사용하여 파일을 전송하였습니다.

1
scp -i key.pem test.jar -r private.ip:/home/ec2-user

현재 프라이빗 서브넷 내부 인스턴스에는 아무 패키지도 설치되지 않은 상태입니다. 따라서 타임존을 세팅하고 필요 패키지를 설치하도록 하겠습니다. (Amazon Linux 2 기준)

1
2
3
4
5
6
7
8
9
10
11
# 타임존 세팅
rm /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

# nginx 설치
amazon-linux-extras install nginx1 -y
systemctl enable nginx
systemctl start nginx

# open jdk 11 설치
amazon-linux-extras install java-openjdk11 -y

타임존을 세팅하고 nginx, java를 설치하였습니다. 이제 옮긴 jar 파일을 실행하겠습니다.

1
nohup java -jar -Dserver.port=8080 /home/ec2-user/test.jar 1> /dev/null 2>&1 &

jar 파일이 정상적으로 실행되었는지 확인하기 위해 아까 만든 메소드를 curl 명령어를 이용해 호출해보겠습니다.

1
2
3
curl -l localhost:8080/ip

{"accessIp":"127.0.0.1","hostIp":"192.168.2.118"}

현재 인스턴스의 프라이빗 IPv4 주소가 hostIp에 찍혀있다면 성공입니다.

Application Load Balancer 생성 / 적용하기

프라이빗 인스턴스에 어플리케이션을 배포했지만 외부에서의 접근은 불가능한 상태입니다. 이제 로드밸런서를 생성하고 http 프로토콜로 접근 가능하도록 해보겠습니다.

대상그룹 생성하기

로드밸런서를 생성하기 전에 로드밸런서가 타겟으로 삼을 대상 그룹을 만들어야 합니다. aws 콘솔에서 대상그룹을 검색하여 로드밸런서 대시보드로 이동하겠습니다. 이동하였다면 우측 상단의 Create target group 을 클릭합니다.

그 후 아래 설정처럼 설정 한 후 다음으로 넘어갑니다. Health check path 에 /health 라고 입력해둔것을 잘 기억해두세요. tg-1 tg-2

타겟에는 프라이빗 서브넷 내부 인스턴스를 선택하고 추가한 후, Create target group 을 클릭하여 타겟 그룹을 생성합니다.

로드밸런서 생성하기

aws 콘솔에서 로드밸런서를 검색하여 로드밸런서 대시보드로 이동하겠습니다. 이동하였다면 좌측 상단의 Load Balancer 생성 버튼을 클릭합니다. elb-1

첫번째 Application Load Balancer의 생성 버튼을 클릭합니다. 리스너가 80포트에 연결되어있는지 확인하고 가용영역을 지정(2a, 2c)한 후 다음 단계로 넘어갑니다. elb-2

두번째 보안 설정 구성 단계는 현재 https 프로토콜을 적용하지 않았기 때문에 넘어갑니다. (실제 배포될 프로덕션 어플리케이션에는 필수입니다.)

세번째 보안 그룹 구성에는 80포트만 오픈한 보안그룹을 하나 만들고 적용합니다.

네번째 라우팅 구성에서는 방금 만든 대상그룹을 선택하고 넘어갑니다. elb-3

구성을 완료하였다면 로드밸런서를 생성합니다.

실제 접근하기

real-1 DNS 이름을 복사하고 브라우저 주소창에 붙여넣은후 접근해보도록 하겠습니다.

외부 도메인 등록 업체를 이용하는 경우 이 DNS를 해당 도메인에 연결하면 됩니다. 관련해서는 업체마다 설정방법이 다르니 이용하고 있는 업체에 문의하시기 바랍니다.

접근이 되지 않습니다. 로드밸런서를 생성하고 적용했지만 아직 몇가지 확인해야 할것이 남아있습니다.

  1. 대상그룹에 연결된 타겟들이 모두 healthy 상태인가?
  2. 로드밸런서가 프라이빗 서브넷에 접근할 수 있도록 프라이빗 서브넷 내부 인스턴스의 보안그룹을 수정하였는가?
  3. 웹서버와 was가 프록시 설정을 통해 연결되었는가?

1번 항목부터 살펴보겠습니다. 대상 그룹은 만들때 설정한 Health check path 를 통해 해당 인스턴스가 유효한 상태인지 판단합니다. 우리는 위에서 /health 라고 설정하였기 때문에 인스턴스의 nginx 설정을 바꿔주도록 하겠습니다.

1
2
3
4
5
6
7
8
9
/etc/nginx/conf.d/test.conf

server {
        listen 80;

        location /health {
            return 200;
        }
}

config 파일을 하나 만들고 /health 경로에 대해 200 상태값을 반환하도록 설정하였습니다. 저장후 nginx를 재시작해야 한다는 것을 잊지 마세요.

다시 대상그룹 대시보드로 돌아와 방금 만든 대상그룹을 선택하고 등록한 타겟의 Health status가 healthy 인지 확인합니다. (가용존별 프라이빗 서브넷에 인스턴스를 생성하였다면 등록한 타겟은 N개여야 합니다.) real-2

다음은 보안그룹입니다. 프라이빗 서브넷 내부 인스턴스에 적용되어있는 보안그룹을 수정하여 로드밸런서가 80포트를 통해 인스턴스에 접근할 수 있도록 합니다. real-3

마지막으로 프록시 설정입니다. 아까 생성한 test.conf 파일을 수정하여 80포트로 들어오는 요청을 8080포트로 보내도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
server {
        listen 80;

        location /health {
            return 200;
        }

        location / {
            proxy_pass http://127.0.0.1:8080;
        }
}

모든 설정이 완료되었다면 nginx 재시작 후 DNS로 접속해보도록 하겠습니다. 우리는 https 설정을 하지 않았기 때문에 http 프로토콜로 접속해야 함을 잊지 마세요.

real-4

DNS 주소/ip 로 접근했을때 위와같이 accessIp에는 내 ip가, hostIp에는 프라이빗 인스턴스의 IPv4 주소가 찍혀 나온다면 성공입니다. 만약 가용존별 프라이빗 서브넷을 구성하였다면 새로고침을 눌렀을때 hostIP가 계속 바뀌는지 확인해보세요.

마치며

이번 포스팅까지 기본적인 서버 구축은 끝이 났습니다. 여기까지가 aws를 활용해 설계할 수 있는 가장 기본적인 형태의 아키텍처라고 생각되는데요, 다음 포스팅부터는 Jenkins와 Codedeploy를 활용하여 배포까지 자동화 해보도록 하겠습니다.

This post is licensed under CC BY 4.0 by the author.

AWS를 사용해 무중단 배포 자동화 환경 구축하기 - 3. VPC와 기본 리소스 생성하기

프록시 패턴 (Proxy Pattern)