본문 바로가기

Public Cloud/AWS

AWS 자습 노트 - 3. 가상머신 EC2 Service Instance 생성 및 활용 (2)

반응형

 

이전 포스팅에 이어 AWS EC2 활용을 이어서 정리하려고 한다. 궁극적으로 간단한 LAMP(Linux-Apche HTTP 서버-MySQL-PHP) 구조와 비슷하게 Linux에 NGINX 서버를 올리고 PostgreSQL을 활용하는 Spring Boot로 만들어진 Web Application Server를 연결해서 간단한 WEB Server를 AWS에 올리려고 하는 것이 목표로 이 포스팅을 이어나가려고 한다.

 

WEB Server를 포함한 Linux 가상머신 만들기

EC2 Instance를 만들기를 선택하고 Step 1에서 RedHat Linux 머신을 선택하고, Step 2에서 t2.micro를 선택하는 것 까지는 동일하나 Step 3에서 페이지 제일 하단에 있는 Advanced Detail에 User Data로 Shell Script를 추가했다. 내용은 다음과 같다. (물론 위와 같이 User data를 사용하지 않고, EC2 Instance가 생성된 후 ssh 접속한 후에 nginx를 설치해도 상관없다. )

#!/bin/bash
yum update -y
yum install nginx -y
systemctl enable nginx
systemctl start nginx

 

그리고 이 EC2 Instance는 WEB Server용으로 사용하려고 하기 때문에 'Configure Security Group'을 여기에 맞게 수정하였다. 아래 그림과 같이 Inbound에서 80 port와 443 port는 어디에서든 접속할 수 있게 설정했다. (Source Field의 Select Box를 눌렀을 때 'Any Where'를 선택하면 된다.)

새로 만든 EC2 Instance가 정상적으로 시작한 것을 확인한 후에 Public IP 혹은 Public Domain Name를 이용해 Browser로 접속을 시도해 보자.

아래와 같이 NGINX Server가 정상적으로 구동하고 있다는 것을 알 수 있다. (실제 NGINX가 설치되고 가동될 때 까지는 Instance Status가 Running으로 변경된 이후 약간의 시간이 필요하다.)

WEB Server와 Application Server 연결

일반적으로 WEB Server는 Static한 Contents를 담당하고, Background Logic 부분은 Application Server에 요청해서 처리한다. 이와 같이 구성하기 위해 NGINX가 자신이 수신한 Request를 Application Server로 Route하게 해주도록 설정을 변경해야 하고, 먼저 기존에 정지되어 있던 Application Server를 다시 Start 시켰다. 아래 그림과 같이 정지되어 있는 Instance는 기존에 할당 받았던 public IP와 Domain Name을 잃게 되지만(Start했을 때 새로 할당 받게 되며, Reboot하는 경우는 기존 IP와 Domain Name을 유지한 상태로 Reboot 한다) 기존 Private IP는 유지된다. (Remark : WEB Server와 Application Server 모두 172.31.x.x/16 의 Private Network 상에 있다)

 

Application Server용 EC2 Instance가 running된 것을 확인한 후 접속해 보면 정상적으로 동작하는 것을 알 수 있다. (running 이후에 Application Server의 Public IP는 54.180.90.243 였다.)

이제 WEB Server로 접속했을 때 WEB Server가 Application Server에 Request를 전달하고 그 Response를 다시 접속한 사용자에게 전달하게 설정을 변경해야 한다. 이를 위해 아래와 같이 WEB Server에 ssh로 접속해서 NGINX 설정 파일(/etc/nginx/nginx.conf)에서 설정 내용을 수정한 후 Restart 해야 한다.

...
# nginx 설정 파일을 편집기로 연다.
[ec2-user@ip-172-31-17-120 ~]$ sudo vi /etc/nginx/nginx.conf
...
# 파일 내부에서 server 부분을 찾아 아래와 같이 location을 추가한다.
  (들어오는 모든 요청을 Application Server ; 172.31.22.117:8080으로 전달)
...
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_pass http://172.31.22.117:8080
        }
...
# NGINX Restart
[ec2-user@ip-172-31-17-120 ~]$ sudo systemctl restart nginx.service
...

Debugging 과정 공유

위 과정이 끝나면 잘될 줄 알았는데 WEB Server에 접속했을 때 계속해서 404 Error가 Return됐다. 원인을 분석하기 위해 NGINX가 돌고 있는 EC2 Instance에 접속해 NGINX의 Log를 확인하니 '13: Permission denied' 가 다수 발생했음이 확인되었고. WEB Server와 Application Server간에 통신의 문제가 있는 지를 점검하려고 WEB Server Instance의 Shell에서 curl command를 이용해 Application Server에 요청을 보내니 정상적으로 처리되고 있었다.

...
# NGINX의 Error Log 확인 
[ec2-user@ip-172-31-17-120 ~]$ sudo cat /var/log/nginx/error.log
...
2019/05/16 04:43:28 [crit] 10878#0: *1 connect() to 172.31.22.117:8080 failed (13: Permission denied) while connecting to upstream, client: 121.136.189.225, server: _, request: "GET /nginx-logo.png HTTP/1.1", upstream: "http://172.31.22.117:8080/nginx-logo.png", host: "ec2-54-180-99-160.ap-northeast-2.compute.amazonaws.com", referrer: "http://ec2-54-180-99-160.ap-northeast-2.compute.amazonaws.com/"
...
# curl 명령으로 WEB Server에서 Application Server로 Connection 상태 확인
[ec2-user@ip-172-31-17-120 ~]$ curl -X GET http://54.180.90.243:8080
Hello. Red-Dwarf. Welcome to Brown-Dwarf World.
...

구글링을 해본 결과 Redhat Linux Instance에 기본적으로 SELinux가 동작하게 되는데, 이 SELinux가 HTTP Proxy를 차단하면서 생긴 문제였다. 이를 아래와 같이 disable 시키고 다시 WEB Server로 접속 시도한 결과 정상적으로 Application Server를 통해 Response를 전달하였다.

$setsebool -P httpd_can_network_connect true

Application 서버 숨기기

일반 WEB Site를 구축할 때 Application Server는 외부에 노출하지 않고 순기는 것이 일반적이다. 즉, Application Server는 Public 주소로 접속하는 일이 없어야 한다. AWS에서는 Security Group을 통해 이와 같은 요구를 부합한다.  AWS Portal > Services > EC2 > Security Groups로 들어가서 현재 Application Server의 Inbound, Outbound Traffic을 설정하는 Security Group의 내용을 수정하려 했다. 아래와 같이 8080 Port에 대해 IPv4나 IPv6의 모든 접속을 허용하는 것을 확인할 수 있다.

그 내용을 같은 Private Network에서만 접속할 수 있게 수정한다. WEB Server와 Application Server 모두 172.31.x.x/16 대역의 Private Network에 있기 때문에 아래와 같이 수정하면 된다.

 

Security Group 설정은 변경 후 저장만 하면 바로 적용이 되기 때문에 위와 같이 수정한 후 Save를 누르면 다른 과정 없이 바로 아래와 같이 Public Network에서 Application 서버로의 접속이 막히는 것을 확인할 수 있다.

.