IT STUDY LOG

Sprint - 3 Tier 아키텍처 배포 본문

devops bootcamp 4/pair/team log

Sprint - 3 Tier 아키텍처 배포

roheerumi 2023. 4. 17. 19:41

#학습 목표

  • Sprint Repository의 소스코드를 이용하여, 어떤 구조로 구성되어 있는지 확인합니다.
  • HTTP 스프린트의 테스트를 모두 통과해야 합니다.
  • 웹 애플리케이션이 배포 상태에서 잘 작동해야 합니다.

 

#해결 과제

  • EC2, S3, RDS와 Repository의 소스코드를 가지고 웹 애플리케이션을 배포하기 위해 어떤 아키텍처를 가져야하는지 이해해야 합니다.
    • 아키텍처에 따라 어떤 과정을 먼저 진행해야 할지 확인합니다.
  • 먼저 각 client , server 디렉토리에서 dependencies를 npm install 을 통해 설치합니다.
  • 클라이언트와 서버 디렉토리에 각각 위치한 .env.example 파일을 보며 어떤 환경변수들이 정의되어 있는지 확인합니다.
  • .env.example 파일을 .env 파일로 생성하여 REACT_APP_API_URL에 EC2에 배포한 서버 주소로 설정합니다.
  • S3를 통해 client 디렉토리에 있는 소스코드를 먼저 정적 웹 호스팅 방식으로 배포합니다.
  • .env 파일의 테스트에 필요한 환경변수를 채워넣습니다.
  • client 디렉토리에서 npm run test1 명령을 사용해 테스트를 전부 통과하는지 확인하고, 웹 애플리케이션이 정상적으로 배포되어 작동하는지 확인합니다.
  • 테스트가 모두 통과되면 제출하고, 다음 HTTPS 스프린트로 넘어갑니다.

 

#실습 자료

레파지토리 : Sprint Repository

 

#과제 항목별 진행 상황

💡 클라이언트 배포 (S3)

S3 콘솔을 통해 버킷 생성

- 버킷 이름 작성, AWS 리전 변경 후 버킷 만들기 버튼 클릭

- 클라이언트 배포가 완료되면 다음과 같은 화면이 출력

 

정적 웹 사이트 호스팅 활성화

- 버킷 목록에서 버킷 이름 클릭 → 속성

- 정적 웹사이트 호스팅 편집 버튼 클릭

- 정적 웹 사이트 호스팅 → 활성화

- 호스팅 유형 → 정적 웹사이트 호스팅

- 인덱스 문서 → 웹 사이트의 홈이 될 문서 파일 이름으로 변경

- 변경 사항 저장 버튼 클릭

 

퍼블릭 액세스 차단 설정 편집

 - 버킷 목록에서 버킷 이름 클릭 → 권한

- 퍼블릭 액세스 차단 편집 버튼 클릭

- 모든 퍼블릭 액세스 차단 체크 해제

 

버킷 콘텐츠를 공개적으로 사용 가능하도록 설정하는 버킷 정책 추가

- 버킷 정책에서 편집 버튼 클릭

- 정책 예제 복사 (위에 있는 버킷 이름 복사 붙여넣기)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::Bucket-Name/*"
            ]
        }
    ]
}

- 변경 사항 저장 버튼 클릭 

 

client 폴더 npm install

$ npm install

 

client 폴더 빌드

$ npm run build

 

빌드 된 파일 및 폴더 업로드 업로드 버튼 클릭

 

build 폴더의 폴더 및 파일을 끌어 넣거나 파일 추가, 폴더 추가 버튼을 이용하여 업로드

- 업로드 버튼 클릭

정적 웹 호스팅 기능을 이용하여 클라이언트 코드를 배포

- 버킷 → 속성 → 정적 웹 사이트 호스팅에 있는 URL을 통해 올린 파일 테스트 가능

 

💡 서버 배포 (EC2)

EC2 콘솔을 통해 EC2 인스턴스를 생성

  • https://console.aws.amazon.com/ec2/에서 Amazon EC2 콘솔에서 인스턴스 시작
  • 키 페어 만들기 : SSH 접속을 위해 Key Pair 생성 필요하며 키페어가 없으면 EC2 인스턴스에 접속 불가
    1. EC2 콘솔 탐색 창의 [Network & Security]에서 [Key Pairs]를 선택
    2. **Create key pair(키 페어 생성)**를 선택
    3. 이름에 키 페어를 설명하는 이름을 입력(키 이름에는 최대 255자의 ASCII 문자를 포함할 수 있습니다. 선행 또는 후행 공백을 포함 불가)
    4. **키 페어 유형(Key pair type)**에서 RSA 또는 ED25519를 선택
    5. **프라이빗 키 파일 형식(Private key file format)**에서 프라이빗 키를 저장할 형식을 선택
      • OpenSSH에서 사용할 수 있는 형식으로 프라이빗 키를 저장하려면 pem을 선택
      • PuTTY에서 사용할 수 있는 형식으로 프라이빗 키를 저장하려면 ppk를 선택
    6. 퍼블릭 키에 태그를 추가하려면 **태그 추가(Add tag)**를 선택하고 해당 태그의 키와 값을 입력
    7. **키 페어 생성(Create key pair)**를 선택
    8. 브라우저에서 프라이빗 키 파일이 자동으로 다운로드되며 안전한 장소에 프라이빗 키 파일을 저장 (🚧이때가 사용자가 프라이빗 키 파일을 저장할 수 있는 유일한 기회)
    9. 프라이빗키에 소유자만 읽을 수 있도록 권한 설정
    10. $ chmod 400 <키_이름>.pem
  • 인스턴스 만들기
    1. Name and tags : 이름 입력
    2. 애플리케이션 및 OS 이미지 : Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
    3. 인스턴스 유형 : t2.micro
    4. 키 페어(로그인) : 만든 키 페어 선택
    5. 네트워크 설정(Network settings) : 기존 보안 그룹이나, 공통 보안 그룹의 기존 보안 그룹 목록에서 보안 그룹을 선택
    6. 인스턴스의 다른 구성 설정에 대한 기본 선택 사항을 유지하고 인스턴스 시작

EC2 인스턴스 생성 후 SSH 프로토콜을 통해 인스턴스에 접속

  1. 터미널 창에서 ssh 명령을 사용하여 인스턴스에 연결
  2. 프라이빗 키(.pem)의 경로와 파일 이름, 인스턴스의 사용자 이름 및 인스턴스의 퍼블릭 DNS 이름 또는 IPv6 주소를 지정
# (퍼블릭 DNS) 인스턴스의 퍼블릭 DNS 이름을 사용하여 연결하는 경우

ssh -i */path/key-pair-name*.pem <인스턴스_유저명>@*instance-public-dns-name*

# (IPv6) 또는 인스턴스에 IPv6 주소가 있는 경우 인스턴스의 IPv6 주소를 사용하는 경우

ssh -i */path/key-pair-name*.pem  <인스턴스_유저명>@*instance-IPv6-address*

The authenticity of host 'ec2-198-51-100-1.compute-1.amazonaws.com (198-51-100-1)' can't be established.
ECDSA key fingerprint is l4UB/neBad9tvkgJf1QZWxheQmR59WgrgzEimCG6kZY.
Are you sure you want to continue connecting (yes/no)?

인스턴스에 접속한 후, 필요한 개발 환경(git, npm, node) 등을 구축

- apt 패키지 업데이트

$ sudo apt-get update
$ sudo apt-get upgreade

- git 설치

$ sudo apt-get install git

- nvm 설치

$ curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh> | bash 

# 재부팅 [<https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-instance-reboot.html>](<https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-instance-reboot.html>)
# or 이후 출력된 환경변수 내용을 복사해 쉘에 붙여넣기

$ nvm --version

- node.js 설치 후 npm 재설치

$ nvm install --lts # 최신 버전 설치
$ node -v

$ sudo apt-get install npm -y

 

EC2에 브라우저를 통해 접근하기

  1. EC2 콘솔에서 해당 인스턴스 클릭
  2. 퍼블릭 IPv4 주소로 접속

 

간단한 서버 애플리케이션을 생성하고 EC2 인스턴스에 코드 가져오기

- git 설정

$ git config --global user.name "username"
$ git config --global user.name "email@email.com"
$ git config --global core.editor vim
$ git config --list
user.name=username@gmail.com
core.editor=vim
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true

- ssh-keygen을 통해 공개키쌍 생성 후 pub키를 git settings에 등록

# SSH 키쌍 생성
# 입력값 없이 enter시 키 생성
$ ssh-keygen
#.. 중략 ..#
+---[RSA 3072]----+
|   ..o==.oo      |
|   .o+o+o+       |
|    o.o.=        |
|   + o  ..       |
|    * E S...     |
|   ... o =o      |
|  . .+=.=+.      |
|   ooo==*..      |
|  ..o+oo *o      |
+----[SHA256]-----+

# 홈 디렉토리에 숨겨진 디렉토리로 ssh 생성
$ ll -a
... 상략 ...
drwx------  2 roheerumi roheerumi  4096  3월 20 10:31 .ssh/
... 하략 ...

# ssh 디렉토리에서 키 조회
$ cd .ssh/
-rw-------  1 roheerumi roheerumi 2602  3월 20 10:31 id_rsa # 비밀키 - 공개해서는 안됨
-rw-r--r--  1 roheerumi roheerumi  570  3월 20 10:31 id_rsa.pub # 공개키
roheerumi@devops:~/.ssh$ cat id_rsa.pub 
# 공개키 내용 출력 후 복사 

 

서버를 실행시키고 브라우저에서 서버에 접속

- 터미널을 종료해도 서버가 계속 돌아가게 실행

# 80포트는 well-known 포트로 관리자 권한으로 실행 필요
# & 옵션으로 백그라운드에서 실행되도록 변경
$ sudo npm node app.js &

 

S3에 연결 후 브라우저에서 접속

S3에 올린 정적 웹사이트 .env 파일의 REACT_APP_API_URL이 EC2 서버를 바라보도록 URL 수정

REACT_APP_API_URL="http://<EC2주소>"
S3_ADDRESS="http://<S3주소>"
HTTPS_ADDRESS="https://<도메인주소>"
ELB_DNS_ADDRESS="http://<Elastic Load Balancer 주소>"
HTTPS_ARCHITECTURE_IMAGE="<S3에 업로드한 https 아키텍처 이미지 주소>"

S3와 EC2 연결을 위해 IAM 역할 생성

역할 생성

  1. IAM 콘솔 접속
  2. 역할을 선택한 다음, 역할 생성을 선택
  3. AWS 서비스를 선택한 다음 사용 사례에서 EC2를 선택
  4. 다음: 권한을 선택(IAM 정책 작성: Amazon S3 버킷에 대한 액세스 권한 부여 방법 및 Amazon S3의 자격 증명 및 액세스 관리를 참조) : AmazonS3FullAccess 관리형 IAM 정책 사용
  5. 다음: 태그를 선택한 후 다음: 검토를 선택
  6. [역할 이름(Role name)]을 입력하고 [역할 생성(Create role)]을 선택

 

EC2 인스턴스에 IAM 인스턴스 프로파일 연결

  1. Amazon EC2 콘솔 접속
  2. 인스턴스 선택
  3. IAM 역할을 연결할 인스턴스를 선택
  4. 작업 탭을 선택하고 보안을 선택한 다음 IAM 역할 수정을 선택
  5. 방금 생성한 IAM 역할을 선택하고 [저장(Save)]을 선택

 

S3 버킷에 대한 권한 확인S3 버킷에 대한 액세스 확인

  1. Amazon S3 콘솔 접속
  2. 정책을 확인할 S3 버킷을 선택
  3. 권한을 선택
  4.  [Bucket Policy]를 선택합니다.
  5.  Effect: Deny가 포함된 문을 검색
  6. 버킷 정책에서 버킷에 대한 IAM 인스턴스 프로파일 액세스를 거부하는 Effect: Deny 문을 편집하거나 제거(지침:IAM 정책 편집을 참조)

 

S3 버킷에 대한 액세스 확인

  1.  EC2 인스턴스에 AWS CLI를 설치
  2.  EC2 서버에서 다음 명령을 실행하여 S3 버킷에 대한 액세스를 확인
 

S3 버킷에 대한 EC2 인스턴스 액세스 권한 부여 | AWS re:Post

Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에서 Amazon Simple Storage Service(Amazon S3) 버킷에 액세스할 수 없습니다. EC2 인스턴스에서 S3 버킷에 대한 읽기/쓰기 액세스를 활성화하려면 어떻게 해야 하나

repost.aws

$ aws s3 ls s3://<버킷명>

 

S3 엔드포인트로 접속 시 정상적으로 EC2 서버로 요청 송신되는 것 확인

 

💡 데이터베이스 연결 (RDS)

RDS 콘솔로 접속해 데이터베이스 생성

  • 데이터베이스 생성 방식 선택 : 표준생성
  • 엔진 옵션 : MYSQL
  • 엔진 버전 : 8
  • 템플릿 : 프리티어
  • 가용성 및 내구성 : 단일 DB 인스턴스 (다중AZ는 고비용)
  • 설정
    • 인스턴스 식별자 : RDS 이름
    • 자격 증명 설정
      • 마스터 사용자 이름 : root, master, admin 등
      • 마스터 암호 : 8자이 이상으로 변경
  • 인스턴스 구성 : db.t3.micro
  • 스토리지
    • 스토리지 유형 : 범용SSD
    • 할당된 스토리지: 20
    • 스토리지 자동 조정: 체크
    • 최대 스토리지 임계값: 1000
  • 연결
    • 컴퓨팅 리소스: EC2 컴퓨팅 리소스에 연결
    • 네트워크 유형: IPv4
    • 퍼블릭 액세스: 아니요
    • VPC보안그룹: 새로생성
      • 보안 그룹 이름 : rds-mysql-sequrity-group
    • 추가 구성
      • 데이터베이스 포트: 3306
  • 데이터베이스 인증: 암호 인증
  • 추가 구성
    • 데이터베이스 옵션
      • 초기 데이터 베이스 이름 : test (미지정시 생성 안함)
      • 마이너 버전 자동 업그레이드 미사용

 

EC2에 접속해 mysql 설치 후 접속

- mysql 설치

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install mysql-server

- mysql 연결 (mysql 비밀번호 입력 후 접속)

# -h : host 옵션으로, rds 엔드포인트 주소를 입력
# -u : user 옵션으로, rds 생성시 마스터 계정명 입력
# -p : password 옵션으로, rds 생성시 마스터 암호 입력
$ mysql -h <host> -u <user> -p

# (옵션) RDS 생성 시 DB를 생성하지 않았다면 test 데이터베이스 생성
mysql > CREATE DATABASE test

- 서버 .env 파일에 DB 연결 정보 입력

DATABASE_HOST=<rds 주소>
DATABASE_USER=<마스터 계정명>
DATABASE_PASSWORD=<마스터 암호>
DATABASE_PORT=3306

 

데이터베이스 연결 후 화면 출력

- 서버 실행

$ sudo node app.js & 

 

#TROUBLE SHOOTING

💡 client 빌드 실패

원인

- 모듈 중 webpack은 md4 해시를 사용하는데 (취약) node.js 17버전 이후로부터 md4를 지원하지 않아 발생

{
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

해결 방안

- node.js를 17버전 이하로 downgrade

$ npm install webpack@latest

#14.15.4버전 설치
$ nvm install 14.15.4

#14.15.4 버전 사용 
$ nvm use 14.15.4

 

#References

Comments