-
-
[docker] 기본 개념 및 설치 방법 (feat. m1 mac에 homebrew로 설치하기)
intro : docker의 기본 개념 및 m1 mac에 homebrew로 설치 방법에 대해서 알아보자.
Docker를 배우는 이유
Docker의 가장 큰 장점은 이식성이다. 이식성이란 특정 프로그램을 다른 환경으로 쉽게 옮겨 설치하고 실행할 수 있는 특성을 의미한다. 이를 통해 복잡하고 번거로운 설치 과정을 반복하지 않아도 되고, 필요한 환경을 즉시 실행할 수 있다는 장점이 있다. 또한, Docker는 운영 체제, 버전, 환경 설정, 옵션 등에 상관없이 항상 동일한 환경을 제공하여, 환경 차이로 인한 오류를 방지할 수 있다. 더불어, Docker의 컨테이너는 각 프로그램이 독립된 환경에서 실행되도록 보장하기 때문에, 서로 다른 프로그램 간의 충돌을 방지할 수 있다. 이러한 특성은 개발, 테스트, 배포 과정에서 일관성과 효율성을 높여 주며, Docker가 많은 개발자들에게 필수 도구로 자리 잡게 된 이유 중 하나이다.
Docker란?
컨테이너를 사용하여 각각의 프로그램을 분리된 환경에서 실행 및 관리할 수 있는 툴이다.
컨테이너(Container)란?
하나의 컴퓨터 환경 내에서 독립적인 컴퓨터 환경을 구성해서, 각 환경에 프로그램을 별도로 설치할 수 있게 만든 개념이다. 하나의 컴퓨터 환경 내에서 여러개의 미니 컴퓨터 환경을 구성할 수 있는 형태이다. 여기서 얘기하는 미니 컴퓨터를 보고 Docker에서는 컨테이너(Container)라고 부른다.
컨테이너(Container)의 독립성
컨테이너는 독립적인 컴퓨터 환경 이라고 말할 수 있다. 그렇다면 구체적으로 어떤 부분들이 독립적으로 관리되는지 알아두는 것이 중요하다. 우선, 저장 공간이 독립적이다. 각 컨테이너는 자신만의 저장 공간을 가지며, 일반적으로 A 컨테이너 내부에서 B 컨테이너 내부의 파일에 접근할 수 없다. 또한, 네트워크 역시 독립적입니다. 각 컨테이너는 고유한 네트워크를 가지며, 자신만의 IP 주소를 사용한다. 이러한 특성 덕분에 컨테이너 간의 충돌 없이 독립적인 환경에서 안전하게 애플리케이션을 실행할 수 있다.
(컨테이너의 독립성의 이해를 돕는 이미지)
이미지란?
Docker에서 이미지(Image)는 닌텐도의 칩처럼 특정 프로그램을 실행하기 위한 모든 요소를 포함하는 개념이다. 이미지는 프로그램 실행에 필요한 설치 과정, 설정, 버전 정보 등을 모두 담고 있어, 이를 기반으로 컨테이너(Container)를 실행할 수 있습니다. 예를 들어, Node.js 기반의 Express.js 서버 프로젝트를 이미지로 만들면, 이 이미지를 실행하는 순간 컨테이너 환경에서 서버가 실행된다. 복잡한 설치 과정을 거치지 않고도 손쉽게 프로그램을 실행할 수 있다. 마찬가지로 MySQL 서버 이미지도 실행과 동시에 MySQL 데이터베이스 환경을 제공하므로, 설치 없이 즉시 사용이 가능하다. Docker 이미지는 프로그램 실행에 필요한 모든 것을 포함하여 손쉬운 배포와 실행 환경을 제공한다.
Homebrew로 Docker 설치하기
Step1. 터미널에 brew 명령어로 docker 설치하기
본인의 터미널에서 다음과 같은 명령어를 실행한다.
brew install --cask docker
그렇다면 다음과 같이 설치가 진행된다.
(본인은 기존에 설치되어있다가 다시 재 설치하는거라 화면이 조금 다를 수 있다.)
Step2. 설치된 docker 버전 확인하기
docker가 정상적으로 설치되었는지 확인하기 위해서, 본인의 터미널에서 다음과 같은 명령어를 실행한다.
docker --version
docker compose version
(다음과 같이 화면에 버전이 출력된다면, 정상적으로 설치가 완료된 것이다.)
Step3. Launchpad에서 Docker 실행하기
brew로 설치할때 --cask 옵션은 GUI 프로그램을 설치할때 사용하는 명령어 옵션 인데, Launchpad로 들어가보면 다음과 같이 Docker가 보일것이다. 설치된 Docker를 클릭하여 실행해보자.
(클릭하면 실행된다.)
Step4. docker desktop 실행하기
그럼 화면상단에 docker 모양의 로고가 생기는데 우측 마우스로 클릭하고, Go to The DashBoard 클릭허자.
(Go to The DashBoard 클릭하면 docker desktop이 열린다.)
docker desktop이 다음 이미지 처럼 열리게 된다.
(docker desktop이 열린 모습이다.)
docker를 설치하는 방법에는 다양한 방법이 존재하지만, 차후 쿠버네티스 설정을 쉽게 하기위해 docker desktop을 설치하는 방식으로 설치해 보았다. docker desktop에서 설정값 하나만 켜주면 쿠버네티스를 사용할 수 있다. (쿠버네티스 글에서 다룰 예정)
[번외] Docker를 사용하여 Nginx 설치 및 실행하기
위 방법으로 설치한 docker를 통해 nginx를 설치하고 실행해보자.
Step1. nginx image 다운받기
docker를 통해 컨테이너에 nginx를 실행하려면 가장 먼저 nginx 이미지를 다운받아야 한다. 다음과 같은 명령어를 통해 이미지를 다운받자.
docker pull nginx
(nginx image가 다운이 완료된 모습이다.)
Step2. nginx image 확인하기
docker를 통해 다운받은 image 목록을 조회할수 있는데 다음과 같은 명령어로 조회할 수 있다.
docker image ls
(docker를 통해 다운받은 image 목록이 조회되는 모습이다.)
Step3. docker 명령어를 통해 nginx 실행하기
다운받은 nginx 이미지를 다음과 같은 명령어를 통해 실행할 수 있다. 이 명령어는 이름이 webserver인 새로운 컨테이너를 생성하고, NGINX 이미지를 기반으로 백그라운드에서 실행하며, 컨테이너의 80번 포트를 호스트의 80번 포트와 연결하여 로컬 환경에서 http://localhost 를 통해 NGINX 웹 서버를 사용할 수 있도록 설정하는 뜻을 축약한 명령어 이다.
docker run --name webserver -d -p 80:80 nginx
(위 명령어를 실해한 후 터미널 모습이다.)
Step4. nginx 서버 잘 실행되는지 확인하기
http://localhost로 접근하면 다음과 같은 이미지처럼 화면이 나온다. 위 명령어에서 80번 포트로 접근시에 컨테이너의 80번 포트로 접근히기로 매핑이 되어있기 떄문에 정상적으로 접근이 된 모습이다.
(포트는 80번이기때문에 localhost로 접근만 하면 nginx 페이지가 나온다.)
Step5. 실행되고 있는 컨테이너 목록 확인하기
아래 명령어를 실행하면 기존에 nginx 를 실행하였던 컨테이너를 조회할 수 있다. 현재 실행중인 것을 알 수 있다.
docker ps
(nginx를 실행시킨 컨테이너 이름이 webserver 이다.)
Step6. 실행중인 nginx 컨테이너 정지하기
다음과 같은 명령어로 nginx 컨테이너를 정지할 수 있다. 기존에 실행하였던 nginx 컨테이너 이름을 webserver로 지정하였는데 해당 이름으로도 정지를 할 수 있다.
docker stop webserver
(webserver 컨테이너 정지)
Step7. 정지한 nginx 컨테이너 삭제하기
아래 명령어를 통해 위 단계에서 정지한 nginx 컨테이너를 삭제할 수 있다.
docker rm webserver
(webserver 컨테이너 삭제)
다음으로
이번 시간에는 Docker의 기본 개념을 학습하고, M1 Mac에서 Homebrew를 사용해 Docker Desktop을 설치한 뒤, NGINX를 실행해 보았다. 다음 시간에는 현업에서 자주 사용하는 CLI 명령어들을 학습해 볼 예정이다.
-
[aws] s3와 cloudfront를 활용한 웹 페이지 배포
intro : s3와 cloudfront를 활용한 웹 페이지 배포하는 방법에 대해서 알아보자.
S3는 파일 저장 서비스 아닌가?
이전글에서 S3는 파일을 저장하는 서비스라고 정의하였었다. 사실 S3는 의외의 부가적인 기능을 보유하고 있는데 바로 정적 웹 사이트 호스팅 기능이다. 쉽게 표현하자면 웹 서비스를 다른 사용자들도 쓸 수 있게 인터넷에 배포하는 것을 말한다.
CloudFront란?
컨텐츠(파일, 동영상 등)를 빠르게 전송하게 해주는 서비스이다. AWS의 Cloud Front 서비스가 어떻게 컨텐츠를 빠르게 전송해 주는지 아래 이미지를 통해 작동 과정을 눈으로 확인해보자.
(Cloud Front 작동 과정)
이미지와 같은 정적 파일을 로드할 때, CDN(Content Delivery Network)를 사용하기 전에는 원본 서버(Origin Server)로부터 물리적으로 거리가 먼 사용자는 파일을 로드하는 데 상당한 시간이 걸릴 수 있다. 이는 네트워크 지연(latency) 때문이다. AWS EC2 인스턴스 생성 시 리전을 한국(서울)으로 설정하는 이유도 같은 맥락이다. 서버와 사용자 간의 물리적 거리가 가까울수록 네트워크 지연이 줄어들고, 응답 속도가 빨라져 사용자 경험이 향상된다. 따라서, CDN은 전 세계 여러 지역에 캐시 서버를 두어 사용자와 가까운 서버에서 콘텐츠를 제공함으로써 이런 문제를 효과적으로 해결할 수 있는 중요한 역할을 하는데 그게바로 AWS의 Cloud Front 이다.
S3 + CloudFront 조합을 사용하는 이유
S3만으로도 웹페이지를 배포하는 것은 충분히 가능하다. 그렇다면 왜 S3 + CloudFront 조합을 사용하는 걸까? 그 이유는 CloudFront가 콘텐츠 전송 성능을 크게 향상시키기 때문이다. 전 세계 여러 엣지 로케이션(Edge Location)을 통해 사용자와 가까운 서버에서 콘텐츠를 제공하여 지연(latency)을 줄이고, 응답 속도를 개선할 수 있다. 또한, HTTPS를 적용하려면 CloudFront를 사용하는 것이 더 간편하고 효과적다. S3 자체로도 HTTPS를 구성할 수 있지만, 추가적인 인증서 설정과 도메인 연결이 필요해 복잡도가 높다. CloudFront를 사용하면 이러한 작업이 간소화되며, 보안을 강화할 수 있는 장점이 있다.
S3, CloudFront를 활용한 아키텍처 구성
(사용자의 S3+Clout Front 조합의 웹페이지 접근 과정)
S3 + CloudFront 조합으로 웹 페이지 배포하기
이제 본격적으로 S3와 CloudFront를 통해 웹 페이지를 배포해 보도록 하겠다.
Step1. S3 버킷 생성하기
가장 먼저 해야 할일은 S3 버킷을 생성해야하는데 다음과 같이 AWS 콘솔에서 S3를 검색하여 접속하자.
(버킷 만들기 버튼을 눌러주자.)
버킨 만들기 버튼을 누르면 다음과 같은 화면이 보이게 되고, 버킷이름을 먼저 작성해주자 나같은 경우는 api-server-web-page 라고 지정하였다.
리전은 항상 서울로 설정하는건 잊으면 안된다.
(버킷 이름을 잘 지정해 주자.)
그 이후에 이 버킷의 퍼블릭 액세스 차단 설정 항목에서 모든 퍼블릭 액세스 차단을 언체크 해야한다. 체크박스를 풀어주어야 다른 익명의 사용자들이 S3에 저장된 나의 웹 페이지를 접속할 수 있다. 또한 모든 퍼블릭 액세스 차단을 비활성화하면 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있습니다. 항목에서의 현재 설정으로 인해 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있음을 알고 있습니다.는 체크해 주어야 한다. 아래 이미지를 잘 확인하자.
(체크 언체크 항목 잘 확인하자.)
위 과정을 완료한 후에 다른 부분은 변경하지 않고 화면 우측 하단의 버킷 만들기 버튼을 클릭한다.
(버킷 만들기 버튼 클릭하자.)
위 과정을 정상적으로 진행하였다면 다음과 같이 버킷이 생성 완료된것을 확인 할 수 있다.
(버킷 생성 성공!)
버킷을 생성하였지만, 위 과정을 통해 생성된 버킷은 아직 권한이 열리는건 아니다. 따로 버킷의 권한을 수정하여 정책을 생성해 주어야 한다. 다음과 같이 생성된 버킷의 권한 탭으로 이동하자.
(생성된 버킷을 클릭하고 권한탭으로 이동하면 나오는 화면이다.)
하단으로 조금 내리면 버킷 정책 영역이 보이는데 이부분의 편집 버튼을 클릭하자.
(버킷 정책의 편집 버튼 클릭)
화면 중앙의 새문 추가 버튼을 클릭하자. 본격적으로 S3의 접근 권한을 설정할 것이다.
(새 문 추가)
작업 필터링 영역에 S3 입력 후 체크, GetObject 입력 후 체크하면 다음과 같은 화면이 된다.
(S3 > GetObject 체크)
그 뒤에 리소스 추가를 누르고 다음과 같이 리소스 유형으로 object 리소스 ARN는 기존에 arn:aws:s3:::{BucketName}/{ObjectName} 라고 작성되어 있을텐데 {BucketName}에는 본인의 버킷 이름 즉 나같은 경우는 api-server-web-page를 입력하고, {ObjectName}는 *로 모든 파일에 대해서 접근을 허용해준다. 그 뒤로 리소스 추가 버튼으로 작업을 완료해주자.
(리소스 추가)
정책의 Principal 부분을 보면 기존에는 {} 라고 입력이 되어 있을텐데 "*" 으로 입력해준다. 이후 변경 사항 저장을 눌러서 버킷 정책 편집을 완료해 주자.
("Principal": "*" 입력)
다음과 같이 버킷 정책 편집이 잘 완료된 것을 확인 할 수 있다.
(버킷 정책 편집 완료)
Step2. S3에 파일 업로드 및 웹 호스팅 설정하기
일단 가장 먼저, 생성된 버킷을 아래 이미지 페이지로 이동하여 확인하자.
(범용 버킷에 가면 내가 생성한 버킷이 확인된다.)
내가 생성한 버킷의 이름이 파란색으로 되어있는데 해당 이름을 클릭하면 다음과 같은 페이지로 이동할수 있고 파일을 업로드할 수 있는 업로드 버튼이 보인다.
(업로드 버튼을 누르자.)
그러면 다음과 같은 화면이 나오고 여기서 파일 추가 버튼을 눌러서 간단한 index.html 파일을 업로드 해보자 (업로드 버튼까지 클릭하자.)
(index.html 파일 소스는 다음과 같이 작성되어있다.)
(내가 알만한 문구로만 작성하면 된다.)
그러면 이렇게 버킷에 index.html 파일이 업로드 된 것을 확인할 수 있다.
(버킷에 파일 정상 업로드 확인 완료)
S3에는 파일 업로드 다운로드 기능 뿐만 아니라, 정적 웹사이트 호스팅 기능도 존재한다고 했는데 우리는 지금 생성한 S3의 index.html 파일을 정적 웹사이트 호스팅 기능을 이용해 볼 것이다. 가장먼저 다음과 같이 버킷의 속성 탭으로 이동해보자.
(버킷의 속성 탭으로 이동해보자.)
아래로 화면을 쭉 내리면 정적 웹 사이트 호스팅 영역이 나오는데 편집 버튼을 눌러주자.
(편집 버튼을 클릭하자.)
지금은 간단한 정적 웹페이지를 호스팅 하는 것이기 때문에 정적 웹 사이트 호스팅 영역은 활성화 버튼 클릭, 인덱스 문서는 index.html을 입력하고 아래로 내려서 변경사항 저장 버튼을 눌러준다.
(변경 사항 저장 버튼 클릭 잊지말자.)
변경사항 저장 버튼을 클릭하고 나서, 새롭개 갱신된 화면에서의 제일 하단을 보면 다음과 같이 정적 웹 사이트 호스팅 영역이 존재한다. 버킷 웹 사이트 엔드포인트 의 주소값이 현재 정적 웹사이트 호스팅이 된 주소값인데 클릭해보면 index.html 파일로 접근하게 된다.
(버킷 웹 사이트 엔드포인트의 주소값을 브라우저에 입력해보자.)
정상적으로 접근되는것을 확인할 수 있다.
(S3의 정적 웹사이트 호스팅은 성공이다.)
Step3. CloudFront 생성하기
S3의 정적 웹사이트 호스팅을 완료하였으니 이제는 CloudFront를 생성해볼 차례이다. 가장먼저 AWS 콘솔창에서 CloudFront를 검색해서 접속하자. 다음과 같은 화면이 보일것이다.
(CloudFront 페이지 접속)
CloudFront 배포 생성 버튼을 클릭하자. 그럼 다음과 같은 화면을 볼 수 있다.
(이제부터 각 영역에 맞는값을 입력해 볼 것이다.)
가장 먼저 Origin domain을 설정할 것인데, CloudFront가 원본 파일의 주소가 어디있는지를 물어보는것이다. 우리는 원본파일을 S3에 만들어 두었기에 S3의 주소를 클릭하면 된다.
(S3의 주소를 클릭한다.)
그 뒤에 Origin domain의 아래의 경고 문구가 보이는데 웹 사이트 엔드포인트 사용 버튼클릭을 해준다. AWS 내부 구조상 웹사이트 엔드포인트 사용하는것이 더 좋다고 권장하고 있다. 그러면 http://api-server-web-page.s3-website.ap-northeast-2.amazonaws.com/ 이렇게 이전에 S3를 정적 웹사이트 호스팅 하고나서 버킷 웹 사이트 엔드포인트의 주소값을 확인할 수 있었는데 그 주소로 Origin Domain이 설정이 된다.
(S3의 주소를 클릭한다.)
아래로 내리면 기본 캐시 동작의 영역이 보이는데 이 부분에서 뷰어 프로토콜 정책의 Redirect HTTP to HTTPS를 선택한다. HTTP로 접근하는 요청을 HTTPS로 리디렉션을 하겠다는 설정이다.
(HTTPS 리디렉션 설정)
기본 캐시 동작 영역 이후에 또 아래로 화면을 더 내리면 웹 애플리케이션 방화벽(WAF) 영역이 보이는데 보안 보호 비활성화을 선택해준다. 이걸 선택한다고 해서 보안이 엄청 약해지거나 하는건 아니다. 기본적으로 비활성화를 하더라도 보안이 충분하기 때문에 만약 디테일한 보안을 추가하고싶은 경우 보안 보호 활성화를 눌러주면 된다.
(보안 보호 비활성화 선택)
이후 화면을 더 내리면 설정 영역이 보이는데 CloudFront를 어느 지역에 활성화 시킬것인지 선택하는 부분이다. 우리는 아시아권 중심으로만 서비스를 제공한다 가정하고 북미, 유럽, 아시아, 중동 및 아프리카에서 사용 으로 선택한다.
(아시아권 중심으로 한다는 가정하에 선택하는 것이다.)
같은 설정 영역에 기본값 루트 객체 - 선택 사항이 존재하는데 해당 부분은 / 경로로 접근할때 어던 페이지를 보여줄 것인지 작성하는 부분이다. 당연히 우리는 index.html 파일을 보여줘야 하기떄문에 index.html을 입력한다.
(index.html 입력)
이후 아래의 배포 생성 버튼을 클릭하여 마무리한다.
(배포 생성 버튼 클릭)
배포 생성 버튼을 클릭하고나서 CloudFront > 배포페이지로 이동하면 위 단계를 거쳐서 생성된 CloudFront가 보인다. 이때 세부 정보에 배포 도메인 이름이 보이는데 해당 도메인이 CloudFront로 접근할수 있는 주소이다.
(도메인 주소를 브라우저에 입력해보자.)
어느 정도 시간이 지나고 나면 브라우저에 URL을 입력했을 때, CloudFront를 통해 S3에 호스팅된 정적 웹사이트에 정상적으로 접근할 수 있음을 확인할 수 있다.
(정상 배포 성공!)
Step4. 도메인 연결 및 HTTPS 적용하기
지금까지의 단계를 정리하자면 S3에 index.html을 업로드하고 정적 웹 사이트 호스팅을 한뒤에, CloudFront를 통해서 S3에 접근할수 있도록 설정하였다. 다만 아직 HTTPS가 적용되지 않아서 HTTPS를 적용할 것인데, 가장먼저 ACM 발급 작업이 선행되어야 한다.
(ACM 페이지로 이동하자.)
주의사항
CloudFront에 ACM을 적용하기 위해서는 발급을 리전이 한국이 아니라, 버지니아 북부로 설정해야 한다. 굉장히 중요하니 꼭 확인하자.
ACM 페이지로 이동하였다면 요청 버튼을 클릭하여 다음과 같은 화면에서 별 다른 수정 없이 또 다음 버튼을 클릭해 준다.
(다음 버튼 클릭)
도메인 이름을 입력한다. 기존에 구매했었던 도메인 주소를 입력하였다.
(오랜만이야 visiblego.com)
도메인 이름을 입력한뒤에 다른 부분은 수정하지 않고 화면을 내리면 나오는 요청 버튼을 클릭한다.
(요청 버튼 클릭)
그럼 이미지처럼 화면이 보이는데 중앙에 Route 53에서 레코드 생성 버튼이 보인다 도메인에 CNAME을 추가하는 것인데 해당 버튼을 클릭해 준다.
(Route 53에서 레코드 생성 버튼 클릭)
(레코드 생성 버튼 클릭)
CNAME이 추가된것을 확인 할 수 있다.
(CNAME을 도메인 레코드에 정상적으로 추가된 것을 알 수 있다.)
여기까지 완료되면 이 인증서를 CloudFront로 이동하여 적용해야 한다. 다음 이미지와 같이 이전 단계에서 생성한 CloudFront의 설정 항목으로 이동하여 편집 버튼을 클릭한다. 그럼 하기 페이지를 확인할 수 있다.
(CloudFront 설정 페이지)
화면을 내리면 대체 도메인 이름(CNAME) - 선택 사항이 보이는데 여기서 항목 추가버튼을 클릭하여 ACM 인증서 발급을 받은 도메인 이름을 작성한다. 나같은 경우는 visiblego.com 을 작성하였다. 또한 사용자 정의 SSL 인증서 - 선택 사항에 ACM에서 발급받은 인증서를 선택해 주면 끝이다. 화면 쭉 내려서 변경 사항 저장 버튼을 클릭해서 설정 편집을 완료하자.
(이미지 보고 잘 입력하자.)
그 뒤에 마지막으로 CloudFront에 Route53의 도메인을 연결해야 한다. Route 53의 호스팅 영역 페이지로 이동하자. 이제 레코드 생성을 해야한다.
(레코드 생성 버튼을 누르자.)
그 뒤에 별칭을 활성화 하고, 엔드포인트를 CloudFront 배포에 대한 별칭으로 설정한다. 그러면 리전 항목이 배포 선택으로 변경되는데 CloudFront의 주소값을 설정할 수 있다. 값을 잘 선택한 뒤에 레코드 생성 버튼을 클릭해 주자.
(이미지를 잘 보고 설정하자.)
정상적으로 레코드가 생성되었다고 알림창으로도 알려준다.
(레코드 생성 완료!)
어느정도 시간이 지난 뒤에 CloudFront에 연결한 도메인(visiblego.com)으로 접속해보면 정상적으로 HTTPS로 접근되는것을 확인할 수 있다.
(S3 + CloudFront + HTTPS 완료!)
S3 + CloudFront 종료하기
먼저 CloudFront를 종료해보도록 하겠다. CloudFront 배포 페이지로 이동해서 비활성화 버튼을 클릭하자.
(비활성화 버튼 클릭)
그럼 다음 이미지 처럼 사용 중지가 된다. 비활성화가 되어야 삭제를 할 수 있기 때문에 시간을 기다려 주어야 한다.
(사용중지 상태이다.)
시간이 어차피 걸리는 동안 S3 버킷과 객체를 삭제하자. 가장먼저 버킷을 삭제하기 전에 버킷안의 객체를 전부 먼저 삭제해야한다. index.html 파일을 삭제하자. index.html 파일을 선택하고 삭제 버튼을 클릭하자.
(객체를 전부 삭제해준다.)
버킷을 삭제하자.
(선택하고 삭제버튼을 클릭하자.)
버킷과 객체를 삭제하는동안 CloudFront가 비활성화가 되기를 바라면서 CloudFront 페이지로 이동한다. CloudFront 배포 ID를 선택하고 삭제 버튼을 클릭하여 마무리 하자.
(CloudFront 배포 ID를 선택하고 삭제 버튼을 누르자)
Route53의 호스팅 영역에서의 도메인 레코드 값 CNAME, A타입 레코드 값을 삭제하는건 이미지를 생략한다.
다음으로
다음 글은 기존에 작성했던 AWS 내용을 프로젝트에 적용하는 과정에서 발생한 문제점이나 트러블슈팅에 관한 내용이 될 것 같다. 예를 들어, EC2 인스턴스에 swap을 설정하는 방법이나, RDS 설정 시 불필요한 비용이 발생하지 않도록 항목을 수정하는 방법과 같은 실용적인 주제를 다룰 예정이다. 다음글이 작성된다면, 해당 글의 내용을 수정하고 다음글의 대한 간략한 설명과 링크를 작성하도록 하겠다.
-
[pipeline] 백엔드(spring boot) 프로젝트에 다양한 ci/cd 방식 적용하기
intro : 백엔드(spring boot) 프로젝트에 다양한 ci/cd 방식을 적용해보자.
하기 글은 다음과 같은 과정이 선행되어야 합니다. 다른 글들에 비해 생략된 과정이 많습니다.
[aws] ec2를 통해 백엔드 api 서버 배포하기 (1)
[aws] ec2를 통해 백엔드 api 서버 배포하기 (2)
[pipeline] ci/cd와 github actions의 기본 개념
개인 프로젝트에서 많이 쓰는 CI/CD 구축 방법
이 방법은 주로 개인 및 소규모 프로젝트에서 CI/CD를 심플하고 빠르게 적용시키고 싶을 때 사용한다. 해당 방식은 다음과 같은 장점과 단점을 가진다.
(전체적인 흐름)
장점
git pull을 활용해서 변경된 부분의 프로젝트 코드에 대해서만 업데이트 하기 때문에 CI/CD 속도가 빠르다. 대부분의 CI/CD 방식들은 전체 프로젝트를 통째로 갈아끼우는 방식을 사용한다. CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 복잡하지 않고 간단하다.
단점
빌드 작업을 EC2에서 직접 진행하기 때문에 운영하고 있는 서버의 성능에 영향을 미칠 수 있다. Github 계정 정보가 해당 EC2에 저장되기 때문에 개인 프로젝트 또는 믿을만한 사람들과 같이 진행하는 토이 프로젝트에서만 사용해야 한다.
CI/CD를 적용하기 전의 과정
CI/CD를 도입하기 전의 배포 과정을 살펴보자. 일반적으로 AWS EC2를 사용하는 환경을 가정하면 기본적인 아키텍처와 배포 절차는 다음과 같다.
1. 코드 Push : 개발자가 GitHub의 Main Branch에 코드를 Push 한다.
2. 소스 Pull : AWS EC2에 SSH로 접속한 후, GitHub에서 최신 Main Branch 코드를 Pull 한다.
3. 빌드 및 실행 : EC2 내에서 코드를 빌드하고 애플리케이션을 재 실행 한다.
이 과정의 가장 큰 문제는 최신 코드를 배포할 때마다 개발자가 직접 EC2에 접속하여 수작업으로 Pull, 빌드, 실행을 반복해야 한다는 점이다. 이는 번거롭고, 효율성이 떨어지며, 실수 발생 가능성도 높다. 이러한 문제를 해결하기 위해 우리는 CI/CD를 도입하여 배포 프로세스를 자동화할 것이다.
하기 단계를 진행하기전에 반드시 진행해야 합니다.
sample 프로젝트 로컬에 설치
해당 프로젝트 AWS EC2에 직접 Git Pull 받고 Build하여 실행
정상적으로 Public IP로 접근되는지 확인하기
GitHub Actions에서 EC2에 직접 접근 후 빌드 및 실행
주의사항
AWS EC2 구축시에, 인스턴스 유형으로 t3a.small을 선택하여 구성하자, 프리티어의 t2.micro는 빌드시에 엄청난 리소스에 서버가 먹통이돤다.
Step1. sample 프로젝트 다운로드
기존의 단점이었던 문제를 해결하기 위해서 GitHub Actions에서 AWS의 EC2에 SSH로 접근하여 빌드 후 실행하는 과정을 yml파일로 작성해 보자. 서버파일은 sample 프로젝트를 사용하는것을 권장한다. 해당 프로젝트를 로컬에 다운받고 먼저 실행해 보자. 별다른 문제없이 다음과 같은 화면이 나온다면 문제없이 실행된 것을 알 수 있다.
(정상실행 화면)
Step2. sample 프로젝트 deploy.yml 파일 생성
sample 프로젝트 루트에 .github/workflows 폴더를 생성하고 deploy.yml 파일을 생성한다. 그렇다면 다음과 같은 구조가 되어있을 것이다.
(정상실행 화면)
Step3. deploy.yml 파일에 코드 작성
이어서 deploy.yml 파일에 다음과 같은 코드를 작성한다.
{% raw %}
name: Deploy To EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }} # EC2의 주소
username: ${{ secrets.EC2_USERNAME }} # EC2 접속 username
key: ${{ secrets.EC2_PRIVATE_KEY }} # EC2의 Key 파일의 내부 텍스트
script_stop: true
script: |
cd /home/ubuntu/api-server-pipeline # 여기 경로는 자신의 EC2에 맞는 경로로 재작성하기
git pull origin main
./gradlew clean build
sudo fuser -k -n tcp 8080 || true
nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
{% endraw %}
secrets 값 설정은 아래 공간에서 해야 합니다
(secrets 값 설정)
Step4. Code를 GitHub에 Push 하기
위 단계에서 deploy.yml 파일에 코드를 작성하였는데, 해당 코드를 push한다. 그럼 GitHub Actions 탭에서 다음과 같은 화면을 확인 할 수 있다.
(정상적으로 GitHub Actions으로 빌드 및 배포가 된 모습1)
(정상적으로 GitHub Actions으로 빌드 및 배포가 된 모습2)
이 방법의 단점
가장 처음에는 AWS EC2의 유형으로 t2.micro를 사용하여 똑같은 deploy.yml파일의 설정으로 CI/CD를 진행해 보았는데, 서버가 먹통이 되었다. 아무래도 빌드하는 과정이 생각보다 리소스를 크게 잡아먹는듯 하여 타임아웃 오류가 났는데, 인스턴스 유형을 t3a.small 변경하고 재 진행하여보니 정상적으로 실행된 것을 확인할 수 있었다. 또다른 해결책으로는 swap을 통해서 메모리 사용량을 늘리는 방법이 있다고 한다. 무료 인스턴스 유형으로 해결하기에는 좀 버거워 보인다.
일반 프로젝트에서 많이 쓰는 CI/CD 구축 방법
이 방법은 주로 현업에서 초기 서비스를 구축할 때 이 방법을 많이 활용한다. 처음 서비스를 구현할 때는 대규모 서비스에 적합한 구조로 구현하지 않는다. 확장의 필요성이 있다고 느끼는 시점에 인프라를 고도화하기 시작한다. 왜냐하면 복잡한 인프라 구조를 갖추고 관리하는 건 생각보다 여러 측면에서 신경(비용)쓸 게 많아지기 때문이다. 해당 방식은 다음과 같은 장점과 단점을 가진다.
(전체적인 흐름)
장점
빌드 작업을 Github Actions에서 하기 때문에 운영하고 있는 서버의 성능에 영향을 거의 주지 않는다.
CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 복잡하지 않고 간단하다.
단점
무중단 배포를 구현하거나 여러 EC2 인스턴스에 배포를 해야 하는 상황이라면, 직접 Github Actions에 스크립트를 작성해서 구현해야 한다. 직접 구현을 해보지는 않았는데 꽤 복잡하다고 한다.
하기 단계를 진행하기 전에 위 단계를 꼭 거쳐주세요
lsof -i :8080 // 8080 포트로 실행중인 프로세스 찾기
kill -9 PID // pid 값에 8080 포트로 실행중인 프로세스 종료하기
rm -rf api-server-pipeline // 기존에 EC2에 설치되어있는 sample 프로젝트 삭제하기
GitHub Actions에서 빌드 후 EC2에 빌드 파일 실행
기존에는 GitHub Actions의 역할이 EC2에 접근하여 직접 빌드 및 실행 하는 역할이었다. 이번에는 EC2에서 빌드하는 것이 아닌, GitHub Actions에서 직접 빌드하고, 빌드된 파일을 EC2에 전달만하여 빌드파일을 EC2는 실행만 하는 역할로 CI/CD를 구축해볼 것이다.
Step1. deploy.yml 파일 수정
deploy.yml 파일을 다음과 같이 수정한다. 중요한 부분은 SCP를 통해서 GitHub Action에서 빌드한 파일을 EC2에 전달한다는 점이다.
{% raw %}
name: Deploy To EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository 파일 불러오기
uses: actions/checkout@v4
- name: JDK 17버전 설치
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: 테스트 및 빌드하기
run: ./gradlew clean build
- name: 빌드된 파일 이름 변경하기
run: mv ./build/libs/*SNAPSHOT.jar ./project.jar
- name: SCP로 EC2에 빌드된 파일 전송하기
uses: appleboy/scp-action@v0.1.7 # 빌드 파일 전송 라이브러리
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: project.jar
target: /home/ubuntu/api-server-pipeline/tobe
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3 # SSH 접속 라이브러리
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script_stop: true
script: |
rm -rf /home/ubuntu/api-server-pipeline/current
mkdir /home/ubuntu/api-server-pipeline/current
mv /home/ubuntu/api-server-pipeline/tobe/project.jar /home/ubuntu/api-server-pipeline/current/project.jar
cd /home/ubuntu/api-server-pipeline/current
sudo fuser -k -n tcp 8080 || true
nohup java -jar project.jar > ./output.log 2>&1 &
rm -rf /home/ubuntu/api-server-pipeline/tobe
{% endraw %}
Step2. Controller 파일의 return 값을 수정
정상적으로 반영되었는지 확인을 하기위헤서 return 값을 수정해보자.
package com.example.api_server_pipeline.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AppController {
@GetMapping("/")
public String index() {
return "Hello World, GitHub Actions CI/CD Success! + 변경하였습니다!";
}
}
Step3. 변경된 파일들을 git push 하고 결과 확인
수정된 deploy.yml 파일과 Controller 파일을 git push 하여 정상적으로 EC2에 빌드하여 실행되었는지 확인해보자.
(GitHub Actions에서 deploy.yml 파일이 정상적으로 실행된 모습 1)
(GitHub Actions에서 deploy.yml 파일이 정상적으로 실행된 모습 2)
SCP를 통한 CI/CD 구축
위 방법은 굉장히 개인적으로 진행하는 서비스에 당장 적용해보고싶은 방법이다. EC2 성능에 영향을 미치지도 않고, 빌드도 GitHub 에서 진행하는거라서 부담도 없는거 같다.
-
[pipeline] ci/cd와 github actions의 기본 개념
intro : ci/cd의 개념에 대해서 이해하고, ci/cd의 대표적인 github actions 방식에 대해서 알아보자.
하기 글에 대해 참고할수 있는 sample project 입니다.
sample project click!
CI/CD란?
CI/CD는 Continuous Integration, Continuous Deployment의 약어로, 지속적인 통합과 지속적인 배포의 의미를 담은 단어이다.
CI/CD를 왜 배워야 할까?
우리가 어떤 웹 서비스(서버)를 AWS EC2에 배포하고, 특정 기능을 개발 중이라고 가정해보자. 이 경우 보통 다음과 같은 과정을 거치게 된다. 먼저, 새로 개발한 기능을 GitHub에 push한 뒤 EC2에 접속하여 main 브랜치의 최신 코드를 가져오기 위해 git pull을 실행한다. 이후 build와 실행 과정을 거쳐 변경된 서비스를 배포하게 된다.
이 과정이 코드 수정이 발생할 때마다 반복적으로 수행된다고 생각해보자. 상당히 번거롭고 비효율적이지 않은가? 이런 비효율적인 과정을 해결하고자 CI/CD라는 개념이 탄생했다.
CI/CD는 코드 변경 사항을 테스트하고, 빌드 및 배포 과정을 자동화하여 개발 생산성을 크게 향상시킨다. 이를 통해 개발자는 반복적인 작업에서 벗어나 본질적인 개발 업무에 집중할 수 있다. 특히, 빠른 배포와 안정성을 유지해야 하는 현대 소프트웨어 개발 환경에서는 필수적인 기술이라 할 수 있다.
(CI/CD의 일반적인 과정)
CI/CD 흐름을 이해하기 위한 Github Actions 개념
Github Actions는 로직을 실행시킬 수 있는 별도의 컴퓨터라고 생각하면 된다. CI/CD 과정에서 Github Actions는 빌드, 테스트, 배포에 대한 로직을 실행시키는 역할을 하게 된다.
Github Actions을 통한 CI/CD 전체 흐름
CI/CD의 구성방식은 다양하지만 일반적으로 다음의 흐름을 거친다. 개발자 GitHub애 커밋 > GitHub Actions의 Event Trigger 실행 (commit 감지) > AWS EC2로 배포
(전체 흐름)
Github Actions 기본 문법 및 사용법 정리
Step1. 프로젝트 생성 및 폴더, 파일 생성
가장 먼저 Intelij에 Empty Project를 생성한다. 프로젝트명은 다음과 같이 github-actions-study로 지정하였는데, 본인이 원하는 프로젝트 명으로 설정하여도 무방하다. 프로젝트 루트 경로에 .github 라는 이름의 폴더를 만들고 해당 폴더안에 workflows 라는 폴더를 만들어보자. 그 뒤에 deploy.yml 파일을 생성하자.
폴더 및 파일 생성시 주의 사항
.github > workflows 의 폴더 이름들은 철자가 틀리면 안된다. 사용자가 원하는 이름으로 변경해서는 안되고 꼭 지정된 이름으로 생성해 주어야 한다. 다만 확장자 .yml 파일의 이름은 사용자가 원하는 이름으로 생성하여도 무방하다.
(주의 사항 잘 읽고 폴더와 파일을 생성하자.)
Step2. deploy.yml 코드 작성하기
deploy.yml 파일에 다음과 같이 코드를 작성해보자.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
Step3. github에 프로젝트 push 하기
그 뒤에, github에 repository를 생성하고 push 해준다. 그 뒤에 github 페이지의 Actions tab으로 이동해보면 검정색 화면에서 무언가 실행되고 있는것을 확인할 수 있다. 물론 너무빠르게 실행이 되어서 완료가 된 화면만 볼 수도 있다.
(github-actions-study 프로젝트가 github의 repository에 잘 저장되었다.)
(yml 파일에 입력하였던 echo "Hello World"가 잘 실행된 모습.)
지금까지의 과정속의 deploy.yml 파일의 코드 해석하기
deploy.yml 파일의 최상단 name 부분을 보면 GitHub Actions 실행시켜보기 라고 작성하였었다. 이 부분은 Github Actions에서 workflows의 이름이 된다.
(코드를 확인하세요)
(name: GitHub Actions 실행시켜보기)
on push ~ main의 해당하는 코드 부분의 내용은 해석하자면, 브랜치명이 main에 push가 일어난다면, yml파일에 작성한 로직(jobs)을 실행하겠다 라는 뜻이다.
(코드를 확인하세요)
이어서 jobs ~ run의 해당하는 코드 부분의 내용을 해석해보자.
(코드를 확인하세요)
가장 먼저 jobs에 대해 짚고 넘어가자. 하나의 workflow는 반드시 1개 이상의 job으로 구성되어야 한다. 만약 여러 개의 job으로 구성된 workflow라면, 이들은 기본적으로 병렬적으로 수행된다. 그러나 현재 코드는 단 하나의 job으로만 이루어져 있어, 실행 시 이 단일 job만 수행된다.
My-Deploy-Job 부분의 내용은 job을 식별할 수 있는 이름이라고 볼 수 있는데, 다음과 같이 Actions tab에서 이름이 지정되어 있는것을 볼 수 있다.
(job을 식별하는 ID라고도 볼 수 있음.)
runs-on 부분은 어떤 서버(컴퓨터)에서 Github Actions를 실행시킬 것인지를 작성하게 되는데, 보통 이런 OS는 리눅스의 Ubuntu를 사용하고 최신 버전임을 알리는 latest 키워드가 뒤에 붙게된다.
마지막으로 steps에 대해 살펴보자. 하나의 job은 여러 개의 step으로 구성될 수 있다. 마치 하나의 workflow에 여러 개의 job이 포함될 수 있는 것처럼, 하나의 job 안에도 여러 개의 step이 존재할 수 있다. 각 step은 특정 작업을 수행하며, 순차적으로 실행된다.
Step4. deploy.yml파일에 step 추가하기
기존에 작성한 deploy.yml 파일의 내용을 어느정도 알아보았다. 우리는 이번에 step 부분에 여러개의 명령어를 한번에 입력해 볼것이다. 코드를 다음과 같이 수정해보자.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
여러 명령어 문장 출력하기라는 step이 추가되었다. 기존의 step > run과 다른 점은, 이번에는 명령어가 한 줄이 아닌 여러 개로 구성되어 있다는 것이다. 때로는 여러 개의 명령어를 하나의 step에서 실행하고 싶을 때가 있는데, 이 경우 | 를 사용하여 여러 명령어를 하나의 run 블록 안에 작성할 수 있다. 이를 통해 한 step에서 여러 작업을 순차적으로 처리할 수 있다.
Step5. 수정된 deploy.yml파일 push 하기
정말로 step 안의 여러 명령어가 실행되는지 확인해보자. 이전에 결과를 확인했던 것과 같이 github의 Actions의 tab에 들어가서 확인 할 수 있다. 우리가 예상한것과 같이 여러 명령어(echo Good, echo Morning)가 실행이 잘 되었다.
(Good Morning이 잘 출력되었다.)
Step6. GitHub Actions 환경변수 사용해보기
Github Actions 자체에는 저장되어 있는 변수가 있다. 대표적으로 아래 테이블에 존재하는 지정된 예약어가 존재하는데 우리는 그것 중 몇개를 deploy.yml 파일에 작성하여 ehco 명령어로 출력해 볼것이다.
변수
설명
GITHUB_REPOSITORY
리포지토리 이름 (owner/repo) 형태입니다.
GITHUB_SHA
실행 중인 커밋의 SHA 값입니다.
GITHUB_REF
실행 중인 브랜치 또는 태그의 참조명입니다.
GITHUB_EVENT_NAME
워크플로를 실행시킨 이벤트 이름입니다 (예: push, pull_request).
RUNNER_OS
실행 환경의 운영체제입니다 (Linux, Windows, macOS).
코드를 다음과 같이 수정한다.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
- name: Github Actions 자체에 저장되어 있는 변수 사용해 보기
run: |
echo $GITHUB_SHA
echo $GITHUB_REPOSITORY
해당 코드를 수정한 뒤에 git push를 진행해보자. 아마 다음과 같은 값이 Actions tab에서 출력될 것이다.
($GITHUB_SHA, $GITHUB_REPOSITORY 값이 잘 출력된 것을 볼 수 있다.)
참고로 $GITHUB_SHA 값은 우리가 방금 커밋한 commit hashcode 값과 일치한다.
Step7. GitHub Actions Secret 환경변수 사용해보기
이전 단계에서 살펴본 것처럼, GitHub Actions는 자체적으로 제공하는 환경 변수(예: GITHUB_REPOSITORY, GITHUB_SHA 등)가 존재한다. 하지만 이 환경 변수들은 코드 실행과 관련된 정보만 제공되며, DB 비밀번호나 API 키처럼 민감한 값들을 관리하는 용도로는 적합하지 않다. 이를 해결하기 위해 GitHub에서는 Actions Secrets 기능을 제공합니다. Secrets를 사용하면 민감한 데이터를 안전하게 저장하고 워크플로에서 참조할 수 있다.
아래의 이미지를 참고하여 GitHub > Setting > Secrets and variables > Actions 으로 이동해보자.
(secrets and variables로 잘 이동해보자)
그 뒤에 Repository secrets의 New Repository Secret버튼을 클릭해보자.
(New Repository Secret 버튼 클릭)
다음과 같이 Name과 Secret에 값을 입력하였는데, Name은 아무렇게나 내가 인식할수 있는 값으로 입력하고 Secret에는 민감한 데이터 값을 입력하면된다. 나는 테스트용도의 값들이기에 무작위의 값을 입력하였다. 그 뒤 Add secret 버튼을 클릭하여 저장해주자.
(잘 입력해보자.)
자 이제 다시 deploy.yml 파일로 와서 우리가 Secret 값으로 저장한 API_KEY_PASSWORD 값에 대해서 출력해보자. 아래 코드를 참고해서 수정 후에 git push 하여 어떻게 Actions 에서 출력되는지 확인해보자.
주의사항
secret 값을 사용할때는 secrets를 앞에 붙이고 . 후에 Name 값을 입력해야한다.
{% raw %}
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
- name: Github Actions 자체에 저장되어 있는 변수 사용해 보기
run: |
echo $GITHUB_SHA
echo $GITHUB_REPOSITORY
- name: 아무한테나 노출이 되면 안되는 값
run: |
echo ${{ secrets.API_KEY_PASSWORD }}
{% endraw %}
출력하고자 하였던 API_KEY_PASSWORD 값이 Actions에서 *** 로 출력된다. 민감한 값을 보안을 지키면서 사용 할 수 있음을 알 수 있다.
(*** 으로 민감한 값이 출력된다.)
다음으로
이렇게 하여 기본적인 CI/CD 개념과 GitHub Actions 사용법을 알아보았다. 다음 단계로 Spring Boot 프로젝트에 CI/CD를 적용하는 실습을 진행해보겠다.
-
[aws] s3를 통해 파일 및 이미지 업로드 해보기 (feat. spring boot)
intro : s3를 통해 파일 및 이미지 업로드 하는 방법에 대해서 알아보자.
S3란?
요약하자면 AWS에서 제공하는 파일 저장 서비스이다.
S3를 왜 사용하는걸까 ?
우린 사진이나 동영상과 같은 파일들을 내 휴대폰에 저장하기도 하지만 구글 드라이브나 iCloud에 저장하기도 한다. 내 휴대폰에 저장하기에는 용량이 너무 커서 다른 공간에 따로 저장하고 싶기도하고, 조금만 내 휴대폰에 이미지나 파일들이 쌓이기 시작하면 지저분해 진다. 우리가 이렇게 실생활에서 겪는 고충과 같이 백엔드 서버에 이미지를 저장할 수도 있지만, 이미지가 너무 많이 쌓이다보면 용량을 너무 많이 차지하게 된다. 그래서 S3를 이용하여 별도의 공간을 통해 이미지와 파일을 관리한다.
S3 생성하기
버킷이란?
AWS S3에서의 버킷이라는 단어는 레포지토리 즉 저장소를 뜻한다. 통상적으로 하나의 저장소를 버킷이라고 부른다.
객체란?
ASW S3에서 업로드한 파일을 보고 S3에서는 파일이라고 하지 않고, 객체라고 부른다. 즉 객체는 S3에 업로드 된 파일을 말한다.
Step1. S3 버킷 생성하기
버킷을 만들기 위해서 검색창에 S3라고 검색하고 다음과 같은 페이지로 이동하고 버킷 만들기 버튼을 클릭한다.
(버킷 만들기 버튼 클릭)
버킷 생성 페이지에서 가장 먼저 일반 구성 영역의 버킷 이름을 api-static-files-test로 지정해주었다. 정적인 파일을 올린다는 이름이다. S3 버킷 이름은 AWS 내 전역적으로 고유하기에 유니크한 이름을 설정할 수 있도록 해야한다.
(식별할수만 있으면 되기에 원하는 이름을 작성하여도 된다.)
다음으로 이 버킷의 퍼블릭 액세스 차단 설정 영역으로 이동한다. 모든 퍼블릭 액세스 차단이 기본적으로 체크가 되어 있는데 아래 이미지처럼 언체크로 변경하고, 현재 설정으로 인해 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있음을 알고 있습니다.에 체크한다.
(퍼블릭으로 열어야지 외부에서 접근하여 다운로드 받을 수 있다.)
다음으로 다른 영역은 기본값에서 변경없이 아래로 쭉 내려서 버킷 만들기 버튼을 클릭한다.
(버킷 만들기 버튼 클릭.)
정상적으로 버킷을 만들었다면 다음과 같이 범용 버킷에 내가 생성한 버킷이 조회된다.
(버킷 생성 완료.)
이후 버킷의 아이디를 클릭하여 권한 Chapter로 이동한다.
(버킷의 권한 Chapter로 이동)
화면을 쭉 내리면 버킷 정책 영역으로 이동할 수 있는데 편집 버튼을 클릭한다.
(버킷 정책 영역으로 이동 후 편집 버튼 클릭)
새 문 추가 버튼을 클릭하여 정책을 추가해주자.
(새 문 추가 클릭)
서비스 선택에서 S3를 검색하고 작업 필터링 부분에 GetObject를 검색하고 체크박스를 선택한다.
(GetObject 체크박스 선택)
아래로 좀 내리면 리소스 추가버튼이 있는데 추가 버튼을 클릭한다.
(리소스 추가 버튼 클릭)
리소스 유형에는 object를 선택하고, 리소스 ARN값에 기본값으로 arn:aws:s3:::{BucketName}/{ObjectName} 나열되어 있을텐데 BucketName에 내가 기존에 생성한 버킷의 이름을 입력하고, {ObjectName}에는 * 값을 입력한다. 그 후 리소스 추가버튼을 클릭한다.
(모든 S3에 업로드된 파일에 접근을 허용할수 있도록 한다.)
그 뒤에 json 형태의 데이터 항목중 Key 값이 Principal 항목의 value 값을 "*" 로 설정한다. 누구에게 이 정책을 허용할 것인지 설정하는 부분인데, 모든 사람에게 허용하기 위해 해당 값으로 입력한다.
(Principal 값을 꼭 설정해주어야 한다.)
그 뒤에 변경 사항 저장을 눌러서 버킷 정책 편집을 완료하자.
(변경 사항 저장 버튼 클릭)
Step2. IAM에서 액세스키 발급 받기
기본적으로 AWS의 리소스에 아무나 접근을 할 수 없다. 그렇기 때문에 S3 접근해서 파일을 업로드 할 수 없다. 하지만 백엔드 서버는 S3에 접근하여 파일을 업로드 할 수 있어야 한다. S3에 접근할 수 있는 권한을 받기 위해서 IAM을 통해 권한을 부여 받아야 한다.
가장 먼저 IAM을 검색하여 해당 페이지로 이동한 뒤, 사용자 생성 버튼을 클릭하자.
(사용자 생성 버튼 클릭)
사용자 세부 정보에 사용자 이름으로 api-server를 입력해주자. 다른 이름을 입력해도 된다. 다음 버튼도 눌러주자.
(사용자 이름 입력)
권한 옵션에 직접 정책 연결선택, 권한정책은 AmazonS3FullAccess을 검색하여 체크 후 다음 버튼 클릭
(AmazonS3FullAccess를 반드시 선택한다.)
사용자 생성 버튼 클릭
(IAM 사용자 생성을 완료하자.)
그 뒤에 우리는 액세스 키를 발급받아야 하기 때문에 위 단계에서 생성한 사용자의 보안 자격 증명 Chapter로 이동한다.
(보안 자격 증명으로 이동하자.)
화면을 좀 내리면 액세스 키 영역이 존재하고 액세스 키 만들기 버튼이 보인다. 해당 버튼을 클릭하자.
(액세스 키 만들기 버튼 클릭)
액세스 키 만들기 페이지에서 사용 사례에 AWS 외부에서 실행되는 애플리케이션 로 선택하고 화면 아래의 다음 버튼을 클릭한다. (차후 과정에서 로컬에 스프링부트를 실행하여 접근할것이기에 해당 옵션을 선택하는 것이다.)
(AWS 외부에서 실행되는 애플리케이션 꼭 선택)
설명 태그 설정 부분은 선택사항이기에 빈칸으로 두고 다음단계로 진행해도 된다. 바로 액세스 키 만들기 버튼을 눌러주자.
(액세스 키 만들기 버튼 클릭 )
이 단계에서 제공되는 액세스 키 값은 현재 페이지 에서만 확인이 가능하다. 유출되지 않도록 어딘가에 잘 저장해서 보관해야 차후 스프링 부트에서 해당 키값을 통해 AWS의 S3 버킷에 접근하여 업로드가 가능하다. 키값을 확인 완료하였으면 완료 버튼을 클릭한다.
(키값을 잘 저장해두자.)
S3와 스프링 부트 연결하여 이미지 업로드 하기
이 단계 에서는 스프링 부트 서버가 필요한데 다음과 같은 sample 프로젝트를 clone하여 액세스 키값만 변경하고 S3와 연동해보자. 가장 먼저 해당 본인 PC에 프로젝트를 clone 하자.
하기 단계는 프로젝트를 PC에 설치 완료하였다는 가정하에 진행됩니다.
Step1. yml 파일에 버킷 이름과 키값 입력하기
application.yml.yml 파일의 버킷이름과 키 값을 확인 후에 입력한다.
(자신의 버킷 이름과 액세스 시크릿 키값을 입력합니다.)
Step2. 프로젝트 실행하기
yml 파일 제외하고 다른 부분들은 변경하지 않고 프로젝트를 실행한 뒤, 8080 포트로 서버가 잘 실행되었는지 로그를 통해 확인합니다.
(8080 포트로 정상적으로 실행중인지 확인필요.)
Step3. Postman을 통해 /upload API 호출
/upload API를 post 메소드로 호출. 이때 postman의 body는 form-data로 key 값을 File 타입으로 변경한 뒤에 키 값입력을 file, value 부분에는 업로드 하고자 하는 파일을 선택해 준 뒤에, Send 버튼을 클릭하자.
(Postman을 통해 API 호출해보자)
정상적으로 이미지가 업로드 된 경우, 리턴값으로 aws에 업로드한 이미지 url 주소값이 리턴된다. 해당 값을 클릭해보면 내가 업로드한 이미지를 확인 할 수 있다.
(리턴값으로 aws s3에 업로드된 이미지 주소가 return 된다.)
또한 업로드한 이미지를 S3 대시보드에서 확인할 수 있는데 다음과 같이 조회된다.
(S3 버킷에 정상적으로 업로드 된 것을 확인 완료.)
S3 종료하기
버킷은 삭제하기전에 객체를 반드시 전부 삭제 해야한다. 먼저 객체부터 삭제한다.
(전부 선택 및 삭제버튼 클릭)
S3 버킷에 객체 전부 선택하고 객체 삭제 버튼 클릭
(객체 삭제 버튼 클릭)
삭제할 버킷 선택 후 삭제 버튼 클릭
(삭제 버튼 클릭)
버킷도 삭제 완료하자.
(버킷 삭제)
다음으로
이렇게 해서 S3를 이용한 파일 및 이미지 업로드 기능을 스프링 부트에 적용하는 작업을 마무리했다. 이제 다음 단계로, S3의 또 다른 기능인 정적 웹사이트 호스팅을 학습하고, 이를 CloudFront와 함께 적용하는 방법에 대해 알아볼 예정이다.
다음글 : [aws] s3와 cloudfront를 활용한 웹 페이지 배포
-
[aws] rds(database) 생성하고 접속하기 (feat. mysql)
intro : rds(database)를 생성하고 접속하는 방법에 대해서 알아보자.
RDS란?
요약하자면 관계형 데이터베이스를 뜻하는데, MySQL Maria DB 등 다양한 관계형 데이터베이스를 AWS로부터 빌려서 사용하는 행위이다.
RDS를 왜 사용할까?
로컬환경에서 개발할때는 로컬환경에 설치된 MySQL와 같은 DB를 연결해서 사용한다. 하지만 서버를 배포하고 나면 서버가 내 컴퓨터에 설치된 MySQL과 연결할 수 없다. DB도 외부 인터넷에서 접속할 수 있도록 같이 배포해 주어야 한다. 이러한 이유 뿐만아니라 여러 부가기능 자동백업 모니터링 등을 가지고 있다.
EC2에 MySQL을 직접 설치하면 안될까?
해도된다. 다만 EC2에는 서버를 배포하는게 통상적인데 서버와 DB를 같은 한 컴퓨터 안에 구성하고 운영을할시에 서버가 죽으면서 DB도 같이 죽는 현상이 발생할 수 있기에 현업에서는 분리하여 서버는 EC2에, DB는 RDS에 설치하는게 통상적이다. 다만 개인프로젝트나 학생이 운용하는 경우 비용절감을 위해 EC2에 DB를 설치하고 운용하는것도 괜찮은 방법이다.
RDS 생성하고 접속하기
Step1. RDS 생성하기
가장먼저 rds를 검색하여 대시보드로 접근한다. 그 뒤 대시보드의 데이터베이스 생성 버튼을 클릭하자.
(굉장히 직관적으로 데이터베이스 생성 버튼이 떡하니 있다.)
데이터베이스 생성 버튼을 클릭하면 다음과 같은 페이지가 보이는데 우리는 MySQL을 생성하고 접근해보겠다. 이미지처럼 MySQL을 선택한다.
(MySQL 선택)
다른 부분들은 변경없이 템플릿 영역으로 이동하여 프리티어를 선택해준다. 프리티어라고 해서 성능적으로 크게 나쁜 유형은 아니라고 한다.
(프리티어 선택)
설정 영역의 DB 인스턴스 식별자를 입력한다. 나같은 경우는 api-db 라고 지정하였다. 그 뒤에 자격증명 설정 영역에 값을 입력해야 하는데 DB의 ROOT 계정의 아이디와 비밀번호를 초기 설정하는것이라고 생각하면 된다. 아이디 admin 비밀번호 본인만 아는값 으로 설정하고 넘어간다.
(자격증명 설정에 작성한 값은 어딘가에 기록해두자.)
다음으론 인스턴스 구성 영역에서 DB 인스턴스 유형을 선택한다. t4g.micro가 프리티어에 해당하기에 선택해 주었다.
(프리티어에 해당하는 유형을 잘 찾아서 선택해주자.)
다음으로는 스토리지인데 유형으로 범용 SSD(gp3)를 선택하고 할당된 스토리지는 20GB를 설정한다. 프리티어는 20GB까지 지원해준다.
(프리티어 범위안에 해당하는 값을 잘 찾아서 선택하자. 스토리지는 20GB)
연결영역에서는 다른 부분 변경하지 않고, 퍼블릭 액세스 부분에서만 예로 선택을 확인해준다. 나중에 외부에서 RDS에 접근할 수 있도록 설정하는 거라고 볼 수 있다.
(퍼블릭 액세스에만 예 버튼을 클릭한다.)
위 과정의 단계를 완료한 뒤에 다른 기본값들은 변경하지 않고 쭉 내려서 데이터베이스 생성 버튼을 클릭해주자.
(데이터베이스 생성 버튼 클릭)
다음과 같이 RDS가 생성되고 있음을 확인 할 수 있다.
(생성이 완료되는데 시간이 조금 걸린다. 5분정도 소요되는 것 같다.)
Step2. RDS 보안그룹 설정하기
생성이 완료되는것을 기다리면서, RDS에 설정할 보안그룹을 생성해야한다. EC2 > 네트워크 및 보안 > 보안 그룹 으로 이동한다.
(보안 그룹 생성 버튼을 클릭하자.)
기본 세부 정보의 보안 그룹 이름을 나같은 경우 api-db-security-group 이라고 작성하였다. 아래 설명도 동일하게 작성해준다. 인바운드 규칙으로는 외부에서 어디서든지 접근할수 있도록 Anywhere-IPv4를 설정해준다.
(3306으로 접근할수 있도록만 인바운드 규칙을 잘 설정하자.)
아웃바운드 규칙은 변경하지 않고 쭉 아래로 내려서 보안그뤕 생성 버튼을 클릭하자.
(보안 그룹 생성을 완료하자.)
보안 그룹을 생성완료하고 난뒤, 다시 RDS로 이동하자. 우리가 아까 생성중이었던 RDS는 생성이 완료되었다고 나올 것이다.
(보안 그룹 생성을 완료하니 RDS도 생성이 완료되어있다.)
이제 우리가 생성한 api-db를 편집하여 보안그룹을 변경해줄것이다. 기존에는 default로 설정되어 있는것을 우리가 방금 만든 api-db-security-group 로 변경하는 작업을 진행한다. 가장먼저 api-db를 클릭하고 수정 버튼을 누르고 들어가서 아래로 쭉 내리면 연결 영역이 보이고, default로 보안그룹이 설정되어 있는데 이것을 아래 이미지처럼 api-db-security-group 로 변경해준다.
(보안 그룹을 변경해주자)
다른 부분들은 변경하지 않고 쭉 화면을 내리면 다음 버튼이 있다. 계속 버튼 클릭해 주자.
(계속 버튼 클릭)
다음으로 우리가 변경한 보안그룹을 즉시 변경으로 선택해주고 DB 인스턴스 수정 버튼을 클릭하자.
(즉시변경 DB 인스턴스에 적용)
보안 그룹이 즉시변경되었음을 알림창을 통해 알 수 있다.
(보안 그룹 변경 완료)
Step3. 파라미터 그룹 추가하기
다음과 같이 RDS의 파라미터 그룹 카테고리로 이동한 후 파라미터 그룹 생성 버튼을 클릭한다.
(파라미터 그룹 페이지)
생성 페이지에서 다음 이미지와 같이 값을 같이 작성한다.
(이미지를 잘 보고 따라서 선택하자)
아래처럼 생성된 파라미터 그룹을 수정해야한다. api-db-parameter-group 을 누르고 편집을 눌러주자.
(일단은 생성된 파라미터 그룹이 잘 생성되었는지 부터 확인하자)
편집을 누르면 다음과 같은 화면이 나온다.
(편집페이지로 들어가면 파라미터들을 변경할 수 있는 값들이 나온다.)
우리는 여기서 character 라고 검색하여 인코딩 방식을 utf8mb4(한글 한자 이모티콘을 모두 지원하는 인코딩 방식이다.)로 변경할것이다. 변경해야 하는 항목을 정확하게 보고 다음과 같이 값을 입력하고 변경 사항 저장 버튼을 클릭한다.
(변경해야하는 파라미터 1)
(변경해야하는 파라미터 2)
다음으로는 다시 편집페이지로 들어가서 collation이라고 검색하고 값을 utf8mb4_unicode_ci 값을 입력할 것이다. collation은 정렬에 대한 규칙을 정의하는 값인데 대중적으로 많이 사용하는 utf8mb4_unicode_ci 으로 값을 입력하고 변경 사항 저장 버튼을 클릭한다.
(변경해야하는 파라미터 1)
(변경해야하는 파라미터 2)
마지막으로 time_zone에 대한 값을 변경한다. Asia/Seoul로 입력하고 변경 사항 저장 버튼을 클릭한다.
(마지막 파라미터 변경이다.)
이제는 우리가 생성하고 변경한 파라미터 그룹을 RDS에 다시 수정해줘야한다. 기존에는 default.mysql8.0 으로 DB 파라미터 그룹이 설정되어 있는데 우리가 생성한 파라미터 그룹이름인 api-db-parameter-group으로 변경한다. 이전에 보안그룹을 수정하였던 것처럼 아래로 내려서 계속 버튼을 클릭하고 즉시 적용으로 파라미터 그룹 변경을 완료한다.
(추가 구성 영역에서 파라미터 그룹을 변경하자.)
지금까지 RDS의 생성 후, 보안그룳 수정, 파라미터 그룹 수정을 완료하였다. 그러나 파라미터 그룹에서의 time_zone의 변경은 RDS의 재부팅이 일어나야지만 적용이된다. 그렇기에 다음과 같이 RDS를 재부팅을 해야한다.
(RDS를 재부팅 해주자.)
재부팅을 완료하였다면 드듸어 RDS에 접속할 준비가 완료된 것이다.
Step4. RDS 접속하기
RDS는 접속하기 위해 여러 툴을 사용할 수 있다. datagrip 이라던지 dbeaver 혹은 intelij 로도 접속할 수 있다. 가장 편한방법으로 접속하면 되는데 intelij로 접속해 보겠다.
가장 먼저 RDS의 내가 생성한 RDS인 api-db를 클릭한다. 페이지가 이동되고 api-db의 여러 세부 정보가 나오는데, 이때 우리가 필요한건 엔드포인트의 주소이다. 이 엔드포인트가 DB 접속시의 HOST 부분에 작성될 값이다.
(엔드포인트를 복사하자.)
인텔리제이를 실행하고 MYSQL DB 연결을 할때 다음과 같이 호스트에 엔드포인트 값을 복사해서 넣어주고 admin 계정과 비밀번호를 입력하여 연결한다.
(RDS MYSQL을 접속해보자)
접속이 잘 된것을 확인하였으면 아래처럼 콘솔창을 열어서 쿼리도 실행해보고 정상적으로 작동하는지 확인해보자.
(간단하게 쿼리작성해서 실행도 해보자.)
RDS 종료하기
위 방법을 통해 RDS를 생성하고 접속하는 방법에 대해서 알아보았다. RDS는 비용이 나가는 기능이기에 사용을 완료하였다면 다음과 같은 방법을 통해 안전하게 종료해보자.
가장 먼저 RDS 대시보드 페이지의 데이터베이스 페이지로 이동한다.
(데이터베이스 페이지)
그 뒤에 삭제하고자 하는 데이터베이스를 선택하고 삭제를 클릭한다.
(삭제 버튼 클릭)
삭제 버튼을 클릭하고 나서 삭제할때의 옵션중에 최종 스냅샷 생성, 자동 백업 보존 항목을 언 체크 하고 삭제를 진행한다.
(언체크 해야 하는 항목 확인이 필요함.)
어느정도의 시간이 지나고 나면 삭제가 완벽하게 처리된다.
다음으로
이렇게 하여 RDS 생성 및 접속하기가 마무리 되었다. EC2에 연결하여 DB 접근을 하는것 또한 포스팅에 포함하고자 하였으나, Intelij에서 DB 접속하는 방법만 알아도 충분히 EC2와 연결하는것은 크게 다르지 않기에 생략하였다. 다음으로는 파일 및 이미지 업로드 (S3)를 학습할 예정이다.
다음글 : [aws] s3를 통해 파일 및 이미지 업로드 해보기 (feat. spring boot)
-
[aws] elb(load balance)에 https 연결하기 (feat. ec2)
intro : elb(load balance)에 https 연결하는 방법에 대해서 알아보자.
이전 글 [aws] route53을 통해 도메인 구매하고 연결하기 (feat. ec2) 와 이어집니다.
해당 글은 하기 과정이 선행이 되어 있어야 합니다.
[aws] ec2를 통해 백엔드 api 서버 배포하기 (1)
[aws] ec2를 통해 백엔드 api 서버 배포하기 (2)
[aws] route53을 통해 도메인 구매하고 연결하기 (feat. ec2)
ELB(Elastic Load Balancer)란?
트래픽을 적절하게 분배해주는 장치로, 전문적인 용어로 로드밸런서 라고도 한다. 서버를 2대 이상 가용할시에는 필수적으로 도입한다. 하지만 이번 ELB를 사용하는 이유는 SSL/TLS를 적용하기 위해 ELB를 사용한다.
SSL/TLS 란?
쉽게 설명하자면 http를 https로 바꿔주는 인증서이다. ssl/tls를 이용하여 http가 아닌 https로 통신할수 있게 만들어 준다.
HTTPS를 적용해야 하는 이유
보안적인 이유
데이터를 서버와 주고받을 때 암호화 시켜서 통신을 한다. 암호화 하지 않으면 누가 중간에 데이터를 가로채서 해킹 할 수도 있다.
사용자 이탈
사이트를 들어갔는데, 보안연결이 사용되지 않았습니다. 라는 문구가 나온다면 믿음직스럽지 못한 사이트라고 생각 할 것이다.
ELB 셋팅하기
Step1. 기본 구성
가장 먼저 aws 콘솔에서의 ec2를 검색해서 들어간 후 로드 밸런서를 클릭하면 아래 이미지의 화면이 보인다. 이때 주황색의 로드밸런서 생성을 클릭하자.
(로드밸런서 생성을 클릭하자)
그럼 다음과 같은 화면이 보이는데, 우리는 https연결을 위한 로드밸런서를 생성 하는것이기에 가장 좌측의 https가 보이는 이미지를 클릭한다.
(가장 좌측의 이미지 https가 있는 이미지를 클릭하자)
이제부터 본격적으로 elb의 설정값들을 작성하게 된다. 로드 밸런서의 이름은 나같은 경우는 api-server-elb로 지정해주었다. 편하게 이름을 작성해도 된다. 체계와 로드밸런서 IP 주소 유형은 기본값으로 설정된걸 변경하지 말자.
(로드 밸런서 이름만 지정하고 나머지는 기본값으로 변경X)
네트워크 매핑은 가용영역에 대한 개념을 알아야 하는데, 하나의 리전에서의 세부 영역을 나누어 관리하는 것을 뜻한다. 다만 우리는 HTTPS를 설정하기 위해 로드 밸런서를 생성하고 있는것이기에 전부 다 선택하여 넘어가면 된다.
(https를 설정하기 위해 로드밸런서를 이용하는것임을 잊지 말자)
여기까지의 단계는 홀딩하고 다음 단계를 넘어가자, 아래의 보안그룹 생성은 새창을 열어서 진행하는 것을 추천한다.
Step2. 보안 그룹
위 단계에서의 네트워크 매핑까지의 작성을 홀딩하고, 보안그룹 생성을 위한 새창을 열고 보안그룹 생성 페이지에 접근하자.
우리는 이전에 ec2에서의 보안그룹을 생성해 본적이 있다. 하지만 로드밸런서 elb에서의 보안그룹은 ec2의 보안그룹과는 다르다. 그렇기에 elb의 보안 그룹을 따로 생성하여야 한다.
(ec2의 보안그룹을 클릭하면 다음과 같은 화면이 나온다)
보안 그룹 생성을 클릭하면 다음 이미지의 화면이 나오게 되고, 이때 보안그룹명을 지정해준다. 식별할수 있도록 나같은 경우는 api-server-security-group으로 작성하였다. (이미지에는 없지만 설명 부분에도 보안그룹명과 같은 값을 입력해 줘야 한다.)
(보안 그룹 명을 지정해 주자, 설명부분에도 같은 값을 입력해 주어야 한다.)
인바운드 규칙으로 http, https의 접근을 허용해준다. (Anywhere-IPv4)
(인바운드 규칙에, http와 https의 요청이 들어오는것에 대한 허용을 지정해준다.)
아웃 바운드 규칙은 건들지 않고, 위 내용을 기반으로 한 보안그룹 생성을 진행한다.
(보안 그룹 생성을 눌러준다.)
위 단계에서 보안그룹을 정상적으로 생성하였다면, 기본 구성 에서의 보안그룹을 우리가 새롭게 생성한 api-server-security-group를 선택할 수 있다.
(보안 그룹에 우리가 만든 보안그룹을 적용한다.)
Step3. 리스너 및 라우팅 / 헬스 체크
elb에 들어온 요청을 어떤 ec2 인스턴스에 요청을 전달할 것인지 설정해야하는데, 그 내용을 바로 리스너 및 라우팅 에서 설정해 주어야 한다. 이때 ec2 어떠한 ec2 인스턴스에 요청을 전달해야할지 대상 그룹을 생성하여야 한다. 아래 이미지에서 대상 그룹 생성 버튼을 클릭하자.
(대상 그룹 생성을 클릭하자.)
대상 그룹 생성 페이지에 들어가서 우리는 인스턴스를 선택하고 이름을 지정해준다. 나같은 경우 api-server-target-group로 설정하였다.
(대상 그룹 이름을 지정하자)
프로토콜 포트 부분에는 로드밸런스에서 받은 요청을 어떤 프로토콜의 포트로 요청을 전달할 것인지 설정하는 부분이다. ec2 인스턴스에 http로 80번 포트로 요청을 전달하자.
(HTTP프로토콜 80번 포트로 전달)
상태검사는 elb 즉 로드밸런서가 여러 ec2에게 트래픽을 전달할 때, 몇초간격으로 ec2 인스턴스의 상태를 확인하고 문제가 없는 ec2 인스턴스에게 트래픽을 전달한다. 만약 요청을 보냈을때 응답이 없다면 elb는 해당 ec2가 문제가 있다고 판단하고 요청을 보내지 않는다. 우리는 지금 elb가 ec2에게 상태를 확인할 수 있는 api의 주소값을 입력하는 것이다. 나는 health라는 api를 ec2에 생성할 것이므로, health라고 이름을 지정하였다. 그 뒤 다음을 누른다.
(상태검사의 개념은 짚고 넘어가자.)
다음 버튼을 누르면 다음의 화면이 나오는데, 실행중인 ec2 인스턴스를 클릭하고 아래의 보류중인 것으로 포함 버튼을 클릭하자.
(실행중인 ec2 인스턴스를 클릭하고, 아래에 보류중인 것으로 포함 버튼을 클릭하자.)
그 뒤에 대상 보기 부분에서 선택한 ec2가 이동 된 것을 확인 후 대상 그룹 생성을 완료하자.
(대상 그룹 생성 완료)
위 방법을 통해 대상 그룹을 생성하였다면, 원래의 리스너 및 라우터를 설정하는 부분에서 위에서 생성한 대상그룹명인 api-server-target-group을 선택해주자.
(대상 그룹 선택 완료)
그 뒤에 나머지 부가적인 설정은 건드리지 않고 로드밸런서 생성 버튼을 클릭하여 완료한다.
(대상 그룹 선택 완료)
로드밸런서 생성 완료를 대시보드에서 확인 후 로드밸런서 이름을 클릭하자.
(로드밸런서 생성 완료)
로드밸런서가 우리의 ec2 인스턴스에 요청을 전달하는지 확인하기 위해 다음과 같이 dns 이름을 복사해서 url로 이동해보자.
(DNS 이름 복사해서 URL 주소창에 입력하자)
다음과 같이 접속된다면 로드 밸런서를 정상적으로 생성하였음을 알 수 있다.
(DNS 이름 복사해서 URL 주소창에 입력하자)
Step4. ELB에 도메인 연결하기
이전에는 도메인을 ec2에 연결했었는데, 위 과정을 통해 로드밸런스에 요청을 보내면 로드밸런서가 자동으로 ec2 에게 요청을 전달하는것을 볼 수 있다. 그렇기에 ec2에 도메인을 연결하는것이 아닌, 로드밸런서에게 도메인을 연결을 하는 과정을 진행한다. 가장 먼저 도메인 연결을 하기 위헤 route53의 호스팅 영역으로 이동한다.
(이전글들에서는 todayvisible로 도메인을 연결했으나, 이번에는 visiblego로 연결한다.)
이전 route53 도메인 관련 작업을 진행할때처럼 동일하게 호스팅 영역의 이름을 클릭하고 레코드 생성을 한다. 레코드 생성페이지에 입력할 값이 많은데 레코드 이름같은 경우 난 www를 붙여서 접근하고싶어서 붙여주었다. 레코드 유형은 그대로 A 타입으로 변경하지않고, 별칭을 반드시 선택해준다. 이전 ec2에 연결할때는 그저 ip주소값만 입력하면 끝이었는데 이번에는 로드밸런서에 연결하는것이라 트래픽 라우팅 영역에 Load Balancer을 선택하고, 리전값은 아시아 태평양 서울 그 아래 로드 밸런서 선택은 우리가 만든 로드밸런서를 선택해준다. (기존에 만든 로드밸런서가 없다면 자동으로 하나만 선택된다.) 이후 레코드 생성 버튼을 클릭하여 마무리 한다.
(레코드 생성버튼까지 눌러주자)
정상적으로 레코드가 생성되었다면 다음과같이 도메인으로 접근시에 이러한 화면을 마주할 수 있다.
(도메인으로 요청시 로드밸런서로 요청전달 후 ec2 요청 전달 성공!)
Step5. HTTPS 적용을 위해 인증서 발급받기
HTTPS의 적용을 위한 기초 단계는 모두 끝이났다. 본격적으로 HTTPS의 적용을 진행해보자. 가장먼저 Certificate Manager을 검색한다 그럼 아래 이미지의 화면이 나오는데, 여기서 인증서 요청 버튼을 클릭하자.
(인증서 요청 버튼 클릭)
퍼블릭 인증서 유형을 선택하고 다음 버튼을 클릭하자.
(퍼블릭 인증서 유형 선택)
도메인 이름만 내가 HTTP로 적용하고자하는 도메인 이름을 작성하고 나머지는 변경하지 않고 요청 버튼을 클릭한다.
(인증서 요청이 완료된 모습이다.)
인증서 요청은 완료되었지만 아직 발급이 완료가 된 것은 아니다. 이 도메인의 주인이 내가 맞다는것을 증명하는 과정을 거쳐야 비로소 인증이 완료가 된다. CNAME 이라는 값을 우리의 호스팅영역의 레코드에 추가를 해줘야한다. 물론 이 CNAME의 이름과 값은 아래 이미지처럼 제공해준다. 편리하게 추가할수 있도록 aws에서는 Route53에서 레코드 추가 버튼을 제공해준다. 버튼을 클릭해보자.
(Route53에서 레코드 생성 버튼 클릭.)
(Route53에서 레코드 생성 버튼 클릭.)
(레코드 생성버튼을 클릭하자.)
정상적으로 CNAMe을 레코드에 추가를 완료하면 다음과 같이 상태가 성공으로 변경된다.
(성공으로 상태가 변경되었다.)
Step6. ELB에 HTTPS 설정하기
드디어 이글의 최종적인 목표인 HTTPS를 적용하는 단계에 도달했다. 우리가 HTTPS를 적용해야 하는 부분은 로드밸런서이다. 도메인도 로드밸런서에 적용했고, HTTPS도 로드밸런서에 적용한다. 모든 요청은 로드밸런서를 통해 트래픽을 ec2에 분배해준다. 자 이제 ec2 대시보드 안에 로드밸런서로 이동하여 리스너를 추가하자.
(일단 로드밸런서로 이동)
그 후 리스너 추가 버튼을 클릭하고 다음과 같은 화면에서 프로토콜에 HTTPS를 선택, 라우팅 액션을 대상 그룹으로 전달, 대상그룹은 르드밸런서를 생성하면서 만들어 두었던 ec2 그룹을 선택한다.
(HTTPS 프로토콜은 반드시 선택한다.)
이후 보안 리스너 설정에서는 이전에 발급받은 도메인 인증서(ACM)를 선택해주는 것만 하면 끝이다. 마지막으로 추가버튼을 눌러주자.
(ACM의 약자는 AWS Certificate Manager 이다.)
리스너 추가를 완료한다면 드디어 HTTPS를 통한 접근이 가능하다.
(여기까지의 과정이 정말 길고 길었다.)
Step7. 리디렉션을 통해 HTTP요청을 HTTPS로 변경하기
근데 좀 아쉬운 부분이 있다. 아직까지 로드밸런서에 HTTP프로토콜의 80포트의 리스너 규칙이 존재하기에 HTTP를 통한 접근이 아직 가능하다. 우리는 이 부분을 리디렉션을 통해 HTTP의 요청을 HTTPS의 요청으로 변경해 줄 것이다. 다음의 과정을 따라가보자.
가장먼저 기존에 등록하였었던 리스너 규칙인 HTTP의 규칙을 삭제한다.
(기존의 HTTP의 리스너 규칙을 삭제한다.)
그 뒤에 다시 리스너 추가 버튼을 클릭하고 다음과 같이 라우팅 액션을 URL로 리디렉션을 선택하고 프로토콜과 포트를 HTTPS, 443을 선택 후 다른 부분은 변경하지 않고 추가버튼을 클릭한다. 그럼 HTTP로 접근하여도 자동으로 HTTPS로 리디렉션이 처리가 된다.
(HTTPS로 리디렉션을 하자.)
(HTTP로 접근하여도 동일하게 HTTPS로 리디렉션이 되어 접근된다.)
ELB 종료하기
HTTPS를 적용하기위해 생성한 ELB(로드밸런서)는 비용이 나가는 기능이다. 사용을 완료하였다면 안전하게 종료해보자. 다음과 같이 ec2의 로드밸런서를 클릭하고 현재 작동중인 로드밸런서를 선택하여 삭제를 진행한다.
(로드밸런서 삭제버튼 클릭)
다음으로
이렇게 하여 ELB 셋팅하기가 모두 마무리 되었다. 이번 글은 사실 EC2 배포, 탄력적 IP설정, Route53 도메인 연결, ELB 생성 및 EC2 대상 그룹설정, ACM을 통한 도메인 인증, ELB의 리디렉션 등등 많은 작업을 하나로 압축하여 진행하다보니 글이 길어졌다. 덕분에 진행하면서 많은 우여곡절이 있었고 도메인을 구매하고 호스팅영역을 절대 삭제해서는 안된다는 점도 알았다. 덕분에 todayvisible 주소를 이제 못쓸거같다.
다음으로는 데이터베이스 연결하기 (RDS)를 진행할 예정이다.
다음글 : [aws] rds(database) 생성하고 접속하기 (feat. mysql)
-
[aws] route53을 통해 도메인 구매하고 연결하기 (feat. ec2)
intro : route53을 통해 도메인을 구매하고 연결하는 방법에 대해서 알아보자.
이전 글 [aws] ec2를 통해 백엔드 api 서버 배포하기 (2) 과 이어집니다.
이 글을 읽기전 주의사항
이 글을 보고 도메인을 구매 한 후 호스팅 영역에서의 레코드를 절대 함부로 삭제하지 마세요.
Route53 이란?
간단하게 이야기해서 도메인을 발급하고 관리해주는 서비스이다. 조금 더 전문적인 용어로 표현하면 DNS(Domain Name System)이라고 한다.
도메인 이란?
www.naver.com, www.google.com 등 문자로 표현된 인터넷 주소를 뜻한다.
DNS(Domain Name System)란?
도메인이 없던 시절에는 특정 컴퓨터와 통신하기 위해서 IP주소를 사용했다. 이 IP는 특정 컴퓨터를 가르키는 주소의 역할을 한다. 하지만 IP 주소는 많은 숫자들로 이루어져 있어서 일일이 외우기 너무 불편했다. 이를 해결하기 위해 IP 주소를 문자로 변환해 주는 하나의 시스템(서버)를 만들게 되었다. 이게 바로 DNS이다.
도메인 기반으로 통신하는 이유
일반적으로 서버는 IP기반으로 통신하지 않고 도메인기반으로 통신한다. 이유는 여러가지지만, 많은 이유 중 하나는 HTTPS의 적용 때문이다. IP주소에는 HTTPS적용을 할 수 없다. 도메인 주소가 있어야 HTTPS 적용을 할 수 있다. 이 때문에 특정 서비스를 운영할때 도메인은 필수적으로 사용하게 된다.
ec2 인스턴에 도메인 연결하기
Step1. Route53에 연결할 EC2 생성하기
이 단계부터는 하기 글들의 선행이 필요합니다.
[aws] ec2를 통해 백엔드 api 서버 배포하기 (1)
[aws] ec2를 통해 백엔드 api 서버 배포하기 (2)
Step2. Route53에서 도메인 구매
가장 먼저 route53을 이용하여 도메인을 구입해 볼건데, ec2 항목을 찾아들어가듯이 검색창에 route53을 검색하여 대시보드로 이동하자.
(ec2처럼 route53도 대시보드가 존재한다.)
대시보드에서 도메인 등록버튼이 보이는데 버튼을 클릭하면 다음과 같은 화면이 나온다.
(여기서 내가 원하는 도메인을 찾아보고 구매할 수 있다.)
그럼 내가 원하는 도메인을 검색하고 선택하면 되는데, 다음과 같이 원하는 도메인을 선택한다.
(구입하고자 하는 도메인 선택 (이미지는 예시입니다. 본인이 원하는 도메인을 선택해주세요.))
결제 진행 버튼을 누르면 다음과 같은 화면이 나오는데 요금 옵션은 1년부터 다년까지 여러가지 옵션으로 구매할수 있다. 나는 1년으로 결재하고 자동갱신을 클릭해서 1년이 지나면 자동으로 구매가 될 수 있도록 설정하였다.
(자동갱신까지 선택)
결재인원의 개인정보를 입력해야 하는데, 다른 부분은 간단히 작성하면 되고, 이메일 부분은 특히 신경써서 작성해야한다. 앞으로 결재내역이 발송될 이메일 이기에 잘 작성해두자.
(이메일 부분은 신중하게 작성하자.)
개인정보까지 입력을 잘 했으면 마지막 확인 페이지가 나온다. 작성한 내용이 문제가 없다면 제출버튼을 클릭해 도메인 구입을 완료하자.
(도메인 구입 완료!)
내가 구입한 도메인을 확인하기 위해서는 Route53 > 호스팅 영역 으로 이동하면 되는데, 도메인 구입후에 어느정도 시간이 지나야만 이 페이지에서 내가 구입한 도메인을 확인할 수 있다. 본인은 10분정도 소요가 되었던 것 같다. 또한 도메인 > 등록된 도메인 에서도 내가 구입한 도메인을 확인할 수 있다.
(내가 구입한 도메인 확인하기 (1))
(내가 구입한 도메인 확인하기 (2))
Step3. Rout53에서 구매한 도메인 EC2 퍼블릭 IP에 연결하기
구매한 도메인을 이제 IP에 연결해보자. 다음과 같이 호스팅 페이지로 이동한다. 그 후 내가 구입한 도메인을 클릭하자.
(도메인이름을 클릭하자, 파란색으로 링크가 보인다.)
그럼 다음과 같이 화면이 보이는데, 여기서 레코드 생성을 눌러준다.
(레코드 생성을 누르자.)
레코드 생성페이지에서 본인이 연결하고자 하는 퍼블릭 ipv4 값을 정확히 입력한다. 레코드 유형은 A 그대로 선택한다. 그 뒤 레코드 생성을 누르자.
(레코드 유형은 기본값인 A를 선택하고, ipv4값을 정확히 입력하자. 레코드이름에 www를 붙여주면, 내 도메인 앞에 www.todayvisible.com 으로 접속할 수 있다. 입력을 하지 않으면 todayvisible.com 으로 접속이된다.)
위 과정을 완료하였다면 브라우저에 내가 구입한 도메인 주소를 입력해보자. 이미지와같이 내가 생성한 ec2에 접근할 수 있다.
(내가 구입한 도메인주소로, 이전에 생성한 api-server ec2에 접근 성공!)
다음으로
이렇게 하여 ec2를 통해 백엔드 api 배포한 서버를, 구입한 도메인으로 연결 및 접속하기가 마무리 되었다. 다음으로는 도메인에 HTTPS를 어떻게 적용하는지 학습할 예정이다.
다음 글 : [aws] elb(load balance)에 https 연결하기 (feat. ec2)
-
[aws] ec2를 통해 백엔드 api 서버 배포하기 (2)
intro : 백엔드 api 서버를 배포하는 방법에 대해서 알아보자.
이전 글 [aws] ec2를 통해 백엔드 api 서버 배포하기 (1) 과 이어집니다.
EC2 설정하기
이전글에서 인스턴스를 생성하였고, 이번글에서는 EC2가 생성되었다는 가정하에 이어서 글을 작성한다.
Step4. 생성된 EC2 살펴보기
만약 이전글을 보고 EC2 인스턴스를 정상적으로 생성하였다면 다음과 같이 EC2 인스턴스 항목에 아래의 이미지를 확인 할 수 있다.
(시간이 조금 걸릴수도 있다. 보통 5분 내외로 이렇게 생성된 인스턴스 목록이 보인다.)
인스턴스 아이디 항목이 파란색으로 링크가 있는데 그걸 클릭하면 다음과 같은 화면이 보여진다.
(가장 중요한 정보는 퍼블릭 ipv4와, 인스턴스 상태이다.)
퍼블릭 ipv4란?
퍼블릭 ipv4는 EC2 인스턴스가 생성되면서 부여받은 IP 주소이다. 인스턴스에 접근하려면 이 IP 주소로 접근하면 된다.
인스턴스 상태란?
인스턴스 상태는 말그대로 EC2가 어떠한 상태인지를 나타내는데, 만약 실행중 이라고 떠 있다면, 컴퓨터가 정상적으로 실행중임을 뜻한다.
Step5. EC2 접속하기
이제 본격적으로 EC2에 접속할건데, 최상단 우측의 빨간색 박스로 연결 버튼이 있는데 클릭을 해보자.
(연결 버튼을 클릭하자.)
그럼 아래와 같은 이미지가 보이는데, 기본적으로 선택되어 있는 항목은 변경하지 말고, 연결 버튼만 클릭한다. (사실 SSH를 통해 연결하는 방법을 주로 사용하기는 하지만, 기본적인 EC2 인스턴스 연결 방법을 통해 먼저 접속해 보겠다.)
(연결 버튼을 클릭하자.)
그럼 다음과 같이 새창이 생성 되면서 리눅스 화면을 AWS 콘솔 웹에서 확인할 수 있다. 기본적인 명령어 pwd 입력하여 출력결과를 확인해보자.
(셍성된 인스턴스에 pwd 명령어를 입력해보자.)
Step6. 탄력적 IP 연결하기
탄력적 IP가 왜 필요할까?
우리가 위 단계를 통해 인스턴스를 생성하여 할당받은 IP는 임시 IP이다. EC2 인스턴스를 중지시켰다가 다시 실행시키면 IP가 변경되어 있다. 그래서 중지시켰다가 다시 재 실행하여도 변경되지 않는 고정 IP가 필요하다. 이게 바로 탄력적 IP 이다. 인스턴스를 생성하고 나서 필수적으로 설정해야하는 탄력적 IP를 진행해 보도록 하겠다.
(네트워크 및 보안의 탄력적 IP를 클릭하자)
그럼 아래와 같은 페이지로 이동하는데 우측 상단의 주황색 버튼 탄력적 IP 할당을 클릭한다.
(탄력적 IP 할당을 클릭하자.)
이후 페이지에서도 기본값을 변경하지 않고, 할당 버튼을 클릭하자.
(할당 버튼을 클릭하자)
탄력적 IP 주소가 정상적으로 할당된 모습이다.
(탄력적 IP 주소 할당 성공!)
할당된 탄력적 IP 주소를 우리가 만든 인스턴스에 연결을 해볼건데 다음과 같이 탄력적 IP 주소 연결 버튼을 클릭한다.
(인스턴에 탄력적 IP 주소를 연결해보자.)
이때 인스턴스 연결항목에서 내가 탄력적 IP주소와 연결하고자 하는 인스턴스를 반드시 선택하고 연결 버튼을 클릭한다.
(연결하고자 하는 인스턴스를 반드시 선택해야한다.)
이제 스프링부트를 배포하기까지 모든 준비가 끝났다. 준비된 환경에서 스프링부트를 우리가 만든 인스턴스에 배포하고 접속해보자.
백엔드 api-server EC2 인스턴스에 배포하기
Step1. jdk 17 install
가장 먼저 다음 명령어를 우리가 생성한 EC2 ubuntu에 입력하여 jdk를 설치한다. jdk를 17 버전으로 설치하는 이유는 우리가 배포할 스프링부트의 버전이 3.0 이상의 버전이기 때문이다. 다음 프로젝트를 예시로 배포하길 추천한다. (본인이 만든 프로젝트를 배포해 봐도 됩니다.)
// 1번 명령어
sudo apt update
// 2번 명령어
sudo apt install openjdk-17-jdk -y
다음 명령어로 jdk가 정상 설치되었는지 확인한다.
// 자바 버전이 아래와 같이 출력된다.
java --version
// openjdk 17.0.13 2024-10-15
// OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu124.04)
// OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu124.04, mixed mode, sharing)
Step2. sample 프로젝트 git clone
jdk 설치가 완료되었다면, git 명령어를 통해 프로젝트를 설치해보자.
// EC2 배포 테스트를 위한 sample 프로젝트이다.
git clone https://github.com/sbi1024/api-server-ec2.git
Step3. sample 프로젝트 build 하기
git 명령어로 다운받은 프로젝트를 api 폴더로 이동하여 build를 진행한다.
// api-server-ec2 폴더로 이동
cd api-server-ec2
// 혹시 빌드된 파일이 있다면 지우고, 빌드한다.
./gradlew clean build
// 만약 권한문제가 발생한다면 다음과 같은 명령어를 실행한다.
chmod +x gradlew
(다음과 같이 화면에서 실행된다. 시간이 조금 걸리는거 같다.)
Step4. sample 프로젝트 build 파일 실행하기
먼저 build된 파일이 존재하는 위치로 이동해야 하는데, 다음과 같은 위치에 build 된 파일이 존재한다. ~/api/build/libs/ 아래 이미지에서도 확인 할 수 있고, 정상적으로 폴더를 이동하였으면 build된 2개의 파일이 존재하는데 SNOPSHOT.jar 파일을 실행한다. (plain은 안정화된 단계에서 주로 사용하고, snapshot은 개발 및 테스트 단계에서 사용한다.)
// build 된 파일이 존재하는 폴더로 이동
cd ~/api-server-ec2/build/libs
// 빌드된 SNAPSHOT.jar 파일 실행
sudo java -jar api-server-ec2-0.0.1-SNAPSHOT.jar
(java -jar 명령어를 통해 실행하려면 폴더를 이동해야한다.)
위 명령어를 통해 정상적으로 실행하였다면 다음과 같이 출력된다. 인텔리제이에서 백엔드 서버를 개발하였을때 자주보던 출력문구들이다.
(80 포트로 잘 실행된 것을 알 수 있다.)
80 포트로 실행된 것을 확인하였으면, 본인의 ipv4 주소로 브라우저에 입력하여 접속해보자. 80포트이기때문에 ip주소값만 브라우저에 입력하여도 정상적으로 접근이 된다.
(이미지의 문구를 정확히 확인하였다면 정상적으로 배포가 되었음을 알 수 있다.)
EC2 종료하기
지금까지 EC2 인스턴스를 설정하고 생성하여 스프링부트를 배포하고 접속까지 해보았다. 이제 우리가 만든 인스턴스를 종료하는 방법을 알아보자.
EC2 인스턴스 종료하기
인스턴스를 종료하는건 생성하는거보다 간단하다. EC2 인스턴스 항목에서 인스턴스 상태를 인스턴스 종료(삭제) 를 클릭한다.
(삭제 버튼 클릭)
여기서도 종료(삭제) 버튼을 클릭한다.
(종료(삭제) 버튼 클릭)
인스턴스는 위 단계로 종료(삭제)가 되지만, 아직 탄력적 IP주소를 릴리즈 하지 않았다. 아래의 단계를 거쳐서 탄력적 IP 주소도 릴리즈 하자.
EC2에 연결하였었던 탄력적 IP 주소 릴리즈
작업버튼을 클릭하고, 탄력적 IP 주소 릴리즈 버튼 클릭하자
(탄력적 IP 주소 릴리즈 버튼 클릭!)
묻지도 따지지도 말고 릴리즈 버튼을 클릭하자.
(릴리즈 버튼 클릭!)
위 두개의 단계를 거치면 AWS를 통해 실행하고 있는 그 어떤것도 없기 때문에 비용이 나가지 않게된다. (프리티어라고 해서 무조건적으로 무료로 제공해주는건 아니다. 제한사항이 존재한다.)
다음으로
이렇게 하여 ec2를 통해 백엔드 api 서버 배포하기가 마무리 되었다. 다음으로는 도메인 연결하기 (Route53)에 대해서 학습할 예정이다.
다음 글 : [aws] ec2 인스턴스에 도메인(route53) 구매해서 연결하기 (feat. ec2)
-
[aws] ec2를 통해 백엔드 api 서버 배포하기 (1)
intro : 백엔드 api 서버를 배포하는 방법에 대해서 알아보자.
배포란 무엇인가 ?
배포란, 다른 사용자들이 인터넷을 통하여 우리가 만든 서비스를 이용할수 있게 하는 것을 말한다. 쉽게 이야기하면 내가 만든 웹 사이트나 서버를 다른 사용자가 사용하려면 인터넷 상에 배포가 되어 있어야 한다. 배포를 하게되면 localhost가 아닌, IP(124.87.9.8)나 도메인(www.naver.com)과 같이 고유한 주소를 받게 되고, 다른 컴퓨터에서 그 주소로 접속할수 있게 된다. 이게 바로 배포이다.
EC2란?
EC2는 Elastic Compute Cloud의 약자로 C가 2번 들어가서 EC2로 명명되었다. 컴퓨터를 빌려서 원격으로 접속해 사용하는 서비스 이다. 쉽게 이야기하면 하나의 컴퓨터를 의미한다.
EC2를 왜 사용해야 할까?
서버를 배포하기 위해서는 컴퓨터가 필요하다. 내 노트북을 통해서도 배포할 수 있다. 다만 24시간 내내 컴퓨터를 켜 두어야 하고, 전기세도 많이나갈것이다. 또한 다른 사용자들이 내 컴퓨터에 접속할수 있어야하니 보안적으로도 굉장히 취약할 것이다. 그렇기에 이러한 불편한 점을 해소시켜주는 기능이 제공되는 AWS EC2를 사용하는 것이다. 이외에도 오토스케일, 로드밸런싱 등 다양한 부가 기능을 제공하기도 한다.
프론트 서버도 EC2에 배포하나요?
프론트 서버도 EC2에 배포할 수 있다. 다만 vercel, netlify, AWS S3를 주로 사용한다. EC2는 백엔드 서버를 배포하는데 주로 사용 된다.
EC2 설정하기
가장먼저 다음과 AWS 링크를 이동하여 회원가입을 진행하고, 로그인을 진행한다. 로그인 진행 후 접속하면 다음과 같은 화면을 마주하게 된다.
(최상단 우측의 리전(Region)을 선택하자.)
Step1. EC2 리전(Region) 선택하기
리전(Region) 이란 ?
인프라를 지리적으로 나누어 배포한 각각의 데이터 센터를 말한다. 좀 더 쉽게 설명하면 내가 컴퓨터를 빌려서 원격으로 접속할 컴퓨터의 위치 즉 지역을 의미한다.
리전(Region)의 특징
AWS는 전세계적으로 다양한 Region을 보유하고 있다. 각 Resion은 고유한 이름이 있다. (버지니아 북부는 us-east-1, 오하이오는 us-east-2 등 고유한 이름을 보유한다.)
리전(Region)을 선택하는 기준
사람들이 애플리케이션을 사용할 때는 네트워크를 통해 통신하게 된다. 이 때 사용자의 위치와 애플리케이션을 실행시키고 있는 컴퓨터의 위치가 멀면 멀수록 속도가 느려진다. 따라서 애플리케이션의 주된 사용자들의 위치와 지리적으로 가까운 리전을 선택하는게 유리하다.
다음과 같이 리전(Region)을 아시아 태평양(서울) 으로 선택하자. 다른나라로 선택하면 안된다. 그 이유는 아래에서 자세하게 설명한다.
(최상단 우측의 리전(Region)을 선택하자.)
많이 하는 실수 (주의사항)
AWS는 리전마다 EC2가 각각 관리되고 있다, 즉 서울에서 EC2를 만들었는데 리전을 버지니아 북부로 변경하면 나의 EC2가 보이지 않는다는 말이다. 이럴때는 당황하지 말고 AWS 콘솔창에서의 리전 설정값을 잘 확인해보자.
(하나의 Region에 고유한 이름이 여러개 있다.)
Step2. EC2 셋팅하기 - 기본 설정
AWS 콘솔창의 검색창에서 EC2 로 검색한다. 아래 이미지와 같이 검색 후 클릭하여 이동한다.
(최상단 좌측에 검색하는 창이 있다.)
그 이후 다음과 같은 화면이 나오는데 여기서 인스턴스 시작 버튼을 클릭한다.
(인스턴스 시작 주황색 버튼을 클릭한다.)
이름 및 태그
그러면 아래와 같이 화면이 나오는데, 가장 먼저 해야할 부분은 이름 및 태그 부분에 EC2 인스턴트 끼리 식별할수 있는 이름을 작성한다. 이름을 신중히 작성하는게 좋은데, 그 이유는 인스턴스는 결국 컴퓨터이고 해당 컴퓨터가 어떤 역할을 하는지 이름으로 식별할 수 있기 때문이다. 만약 개발용으로 사용할 서버와, 실제 배포용으로 사용할 서버가 이름이 같다면 구별하기 힘들지 않겠는가? 그러니 나의 상황에 맞게 이름을 작성한다. 나 같은 경우는 테스트용으로 단순히 api-server 라고 지정하였다.
(이름은 내가 식별할 수 있게만 작성하면 된다.)
애플리케이션 및 OS 이미지(Amazon Machine Image)
다음으로는 애플리케이션 및 OS 이미지를 선택한다. Mac os와 Window os가 익숙하겠지만, 서버용으로 사용할 OS는 리눅스가 최적화 되어있다. 그 이유로는 Mac, Window 같은 os는 컴퓨터를 쉽게 사용할 수 있도록 부가적인 기능을 제공하기에 리눅스에 비해 용량도 많이 차지하고 성능적으로 떨어진다. 그렇기에 서버를 배포할때 필요한 기능만 포함되어 있는 os를 선택하는게 유리하기에 Ubuntu를 쓴다.
(서버용으로 사용할 OS는 리눅스를 보통 사용한다.)
인스턴스 유형
다음으로 인스턴스 유형을 선택해야 한다. 인스턴스 유형이 뭔지 알면 해당 값을 설정하는데 있어서 아주 큰 도움이 되는데, 쉽게 설명하면 내가 빌릴 인스턴스 즉 컴퓨터의 사양을 뜻한다. 즉 좋은 사양의 인스턴스를 빌릴지, 좀 사양적으로 부족한 인스턴스를 빌릴지 이 Step에서 선택하는 것이라고 볼 수 있다. 다만 나는 t2.micro 를 선택하여 프리티어 즉 요금이 부과되지 않는 유형을 선택하였다. 또한 이 유형은 하루 평균 2000명 정도 사용되는 사이트에서도 충분히 운영 가능함이 보장된 유형이기에 첫 서버 배포를 할때 사양을 낮은 단계에서 운용하고, 차후에 상황에 맞에 유형을 높은 버전으로 변경하는 것을 추천한다.
(첫 시작은 t2.micro로 시작해도 충분하다.)
키 페어(로그인)
다음으로 키페어(로그인) 부분에서 새 키 페어 생성을 눌러준다. 그럼 아래와 같은 이미지처럼 화면이 나오는데, 키 페어 이름을 설정하고 키 페어 생성 버튼을 눌러주면 파일이 다운로드 된다. 다운로드된 파일은 내가 생성한 인스턴스 EC2에 접속할때 필요한 파일이며, 해당 파일을 통해서 SSH 로그인이 가능하다.
(이름 및 태그에서처럼 내가 식별할 수 있도록 이름을 지정한다.)
네트워크 설정
다음으로 아래의 네트워크 설정에서 편집 버튼을 클릭한다. 편집 창에서 방화벽(보안그룹)항목이 중요한 부분이니 하기에서 먼저 개념에 대해서 이해하고 편집창에서 어떤식으로 값을 설정하는지 알아보도록 하겠다.
(우측 상단의 편집 버튼 클릭)
하기 이미지는 편집 버튼을 클릭하면 바뀌는 화면이다.
(편집 버튼 클릭하면 열리는 창)
방화벽(보안그룹) 설정 전 보안그룹의 개념에 대해서 알아보자.
보안그룹이란, AWS 클라우드에서의 네트워크 보안을 의미한다. EC2 인스턴스를 집이라고 생각한다면, 보안 그룹은 집 밖에 쳐져있는 울타리와 대문같은 개념이다. 인터넷에서 일부 사용자가 우리가만든 EC2 인스턴스를 접근한다고 가정해보자. 인스턴스에 방화벽 역할을 할 보안 그룹을 만들고 규칙을 설정하는데 이때 인바운드 규칙(외부에서 EC2로 보내는 트래픽)과 아웃바운드 규칙(EC2에서 외부로 보내는 트래픽)을 설정하여, 특정 사용자만 접근할 수 있도록 설정할 수 있다. 이때 만약 내가 인바운드 규칙을 내 PC 아이피에서만 접근할 수 있도록 설정한다면, 일부 사용자는 우리가 만든 EC2 인스턴스에 접근할 수 없다.
보안 그룹을 설정할때는 허용할 아이피(IP)와 포트(PORT)를 설정할 수 있다.
이어서 보안그룹을 설정하는 화면을 다시 보자면, 먼저 보안 그룹 이름을 설정한다, 나는 api-server-security-group 이라고 명명하였다. 아래 이미지를 보면 기본적으로 ssh 접속이 허용되어 있는데, 어느곳에서든 22번 포트로 해당 인스턴스를 접근하는것에 대해 열려있다는 것을 뜻한다. 왜냐하면 SSH를 통해 내가 어디서든지 원격 접속을 하기 위해 허용되어야 한다고 볼 수 있다. 또한 이 server는 불특정 다수에게 접근을 허용해야 하기에, 보안 그룹 규칙 추가 버튼을 클릭하여 HTTP로 접근하고자 하는 사용자들에게 접근을 허용할 수 있도록 추가 해주어 설정을 마무리 한다.
(SSH 22포트, HTTP 80포트를 인바운드 규칙으로 허용해줌)
IP의 개념
IP는 특정 컴퓨터의 주소를 뜻한다.
PORT의 개념
한 컴퓨터 내에 실행되고 있는 프로그램을 뜻한다.
스토리지 구성
EBS는 Elastic Block Storage의 약자이다. 인스턴스도 하나의 컴퓨터이다 보니 파일을 저장할 공간이 필요한데, 이 저장공간을 EBS라고 부른다. 즉 EBS란 EC2안에 부착된 하드디스크 라고 생각하면 된다. EBS 보다 더 포괄적인 용어로는 스토리지, 볼륨 이라고 부른다. 기본적으로 아래 이미지의 GB 부분이 8GB로 설정되어 있는데 30GB로 변경해주자. 프리티어는 30GB까지 허용해준다, 또한 범용 SSD GP3로 변경한다.
(프리티어는 30GB 까지 허용해준다.)
Step3. EC2 인스턴스 생성
이후 우측의 인스턴스 시작 버튼을 클릭하면. 기본설정에 기반한 인스턴스가 생성되고 AWS 콘솔창에서 내가 생성한 인스턴스를 확인 할 수 있다.
(주황색 인스턴스 시작 버튼을 클릭하자.)
다음으로
다음 글에서는 생성된 EC2에 접속하고 EC2에 다양한 부가적인 설정을 진행하며, 스프링부트를 EC2 환경에 배포하는걸 해보도록 하겠다. (비용나가지 않게 하는 방법도 포함)
다음글 : [aws] ec2를 통해 백엔드 api 서버 배포하기 (2)
Touch background to close