Webcraft 배포 실습

jar 빌드 (로컬)

과제로 제출한 버전이 아닌 제공된 버전을 사용한다.

설정 파일 확인 (application.properties)

spring.application.name=webcraft
spring.datasource.url=jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:webcraft}?createDatabaseIfNotExist=true
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:12345678}
spring.jpa.hibernate.ddl-auto=update
spring.data.redis.host=${REDIS_HOST:localhost}
spring.data.redis.port=${REDIS_PORT:6379}
spring.data.redis.ssl.enabled=${REDIS_SSL:false}

webcraft.chat.pubsub-enabled=true
  • 기본적으로 로컬의 DB를 사용하도록 Fallback 설정이 되어있다.

보안그룹 생성

RDS 생성

이전 실습과 달리, 프라이빗 서브넷으로만 서브넷 그룹을 구성한다.
외부 액세스를 허용하지 않고, 앞서 생성한 db용 보안그룹을 할당해준다.
이렇게 하면 webcraft-app 보안 그룹을 할당받은 EC2에서만 RDS에 접근이 가능해진다.

Elasticache 생성

이전 실습과 동일한 세팅으로 생성(Elasticache는 이전에도 프라이빗 액세스만 가능하도록 생성하였음)
단, 보안그룹은 RDS와 마찬가지로 webcraft-app으로 지정해야 함

EC2 설정

자세한 방법은 이 글 참조

기존 설정 유지

  • AMI: Amazon Linux 2023 (Arm)
  • 인스턴스: t4g.small
  • 퍼블릭 IP 자동 할당

보안 그룹 수정

키 페어 교체

  1. 새로운 키페어 생성

  2. 공개 키값 확인

  3. 기존 키페어로 접속, 편집기로 .ssh/authorized_keys 열기

  4. 기존 값 제거 후 새 공개키 값으로 교체

  5. 기존 키로는 접속되지 않고, 새 키로 접속이 가능한 것을 확인

jar EC2에 올리기

자세한 방법은 이 글 참조

  • 이전 실습에서 올린 app.jar는 삭제하였음

Parameter Store 설정

자세한 방법은 이 글 참조

  • application.properties에 정의되어있던 모든 환경변수들에 대해 파라미터를 설정

앱 실행

파라미터를 Parameter Store에서 가져와 환경변수로 주입한 뒤 앱을 실행한다.

#!/bin/bash

# 1. AWS Systems Manager Parameter Store에서 설정값 불러오기
export DB_HOST=$(aws ssm get-parameter --name "/webcraft/prod/DB_HOST" --query "Parameter.Value" --output text)
export DB_PORT=$(aws ssm get-parameter --name "/webcraft/prod/DB_PORT" --query "Parameter.Value" --output text)
export DB_NAME=$(aws ssm get-parameter --name "/webcraft/prod/DB_NAME" --query "Parameter.Value" --output text)
export DB_USERNAME=$(aws ssm get-parameter --name "/webcraft/prod/DB_USERNAME" --query "Parameter.Value" --output text)
export DB_PASSWORD=$(aws ssm get-parameter --name "/webcraft/prod/DB_PASSWORD" --query "Parameter.Value" --output text)

export REDIS_HOST=$(aws ssm get-parameter --name "/webcraft/prod/REDIS_HOST" --query "Parameter.Value" --output text)
export REDIS_PORT=$(aws ssm get-parameter --name "/webcraft/prod/REDIS_PORT" --query "Parameter.Value" --output text)
export REDIS_SSL=$(aws ssm get-parameter --name "/webcraft/prod/REDIS_SSL" --query "Parameter.Value" --output text)

# 2. 불러온 환경 변수를 적용하여 애플리케이션 실행
java -jar webcraft.jar

결과

다중 접속까지 이루어지는 것을 확인할 수 있었다.

트러블슈팅: REDIS_SSL

  • 위 스크립트로 스프링 앱 실행 시 Redis 연결 타임아웃이 발생했다.
RedisCommandTimeoutException: Connection initialization timed out after 1 minute(s)
  • nc -zv 테스트 결과 EC2에서 ElastiCache 6379 포트로의 네트워크 통신은 정상이었으나, ElastiCache에 설정된 암호화 방식과 애플리케이션의 접속 방식이 일치하지 않아 핸드셰이크 단계에서 응답이 멈춘 것으로 파악되었다.

  • 문제는 REDIS_SSL을 false로 주입했다는 것이다. 옵션을 false로 두면 일반 Plain TCP로 연결을 시도하고, true일 경우 TLS 기반 암호화 터널로 접속을 시도한다.

  • Elasticache는 전송 중 암호화 옵션이 활성화 되어 있었다.

  • 이 경우 Elasticache는 TLS 연결 요청만 수락한다. 따라서 클라이언트가 평문 패킷을 보내면 응답하지 않아 타임아웃이 발생했던 것이다.

  • Parameter Store에서 해당 값을 true로 수정하여 문제를 해결하였다.

  • 기존 Fallback은 로컬 환경을 상정한 것이라 암호화 없는 옵션으로 설정되어있던 것으로 보인다. 배포 환경에서는 암호화된 통신을 활성화하는 것이 일반적이다.

0개의 댓글