티스토리 뷰

프로젝트 소개

 

👐🏻 플리빗은 세상과 SNS로 대화하는 현세대의 소통 방법을 개선하고자 하는 Q&A 플랫폼입니다.
궁금증을 질문하고 답변을 통해 자신을 표현하여, 소통 과정에서 느끼는 니즈를 충족시키고 어려움을 해결합니다.

 

 

저희 프로젝트의 서비스 소개글은 아니니 이 부분은 빠르게 스킵하도록 하겠습니다!!

더 자세한 내용을 보시고 싶으시면 아래 링크에 들어와주세요!

https://github.com/Team-baebae

https://www.flipit.co.kr/

 

 

 

프로젝트 설계

 

이번 프로젝트를 설계하면서 정말 많은 고민을 했습니다. 어떻게 하면 좀 더 안정적이고 확장성 있는 설계를 할 수 있는지 정말 많은 자료를 찾아보고 네이버 클라우드 공식문서도 많이 봤던거 같아요.

 

기본적으로 Q&A 플랫폼을 기반으로하기 때문에 실시간 알림 기능도 들어가야 했고, 사용자가 몰렸을때를 대비한 안정성부분도 생각했어야 했습니다. 또한, 개발기간이 그렇게 길지 않았기에 러닝커브를 최소화한 방향으로 설계를 시작하였습니다.
따라서, 저희 백엔드 팀에서 설계를 진행하며 생각을 했을때, 서버 요구사항은 다음과 같았습니다.

 

  • 트래픽이 몰릴때 안정적인 확장 가능해야함
  • 외부에 서버 정보 노출을 최소화 하여 보안 강화
  • 사용자에게 빠르고 정확한 실시간 알림 전송
  • 배포 다운타임 최소화로 사용자 편의성 증가
  • 개발 러닝커브 최소화한 방법

이런 요구사항들을 충족시키기위해 다양한 아키텍처를 생각하면서 설계를 시작했습니다.

우선, 안정적인 확장을 적용하기위해 AutoScaling과 Kubernates등의 기술들을 고민을 하였고,
실시간 알림 전송 기능을 적용하기위해 Message Queue, FireBase 등을 고민을 하였으며,
다운타임을 최소화한 무중단 배포를 적용하기위해 Jenkins, Github Action, Source Deploy등의 다양한 기술들을 고민을 하였습니다.
이외에도, 보안을 강화하기 위해 VPC 및 SSL인증 부분도 많은 고민을 하였습니다.

 

프로젝트 설계는 블로그 및 네이버 클라우드 공식 문서 등 다양한 자료를 참고하여 진행었으며,
이러한 결과로 나온 아키텍처는 아래에서 사진과 함께 자세히 설명드리도록 하겠습니다.

 

 

 

 

 

 

 

클라우드 아키텍처 및 설명

 

이번에 Green Developers 프로그램을 참여하면서 정말 많은 Ncloud의 서비스들을 활용하였습니다.
우선 먼저 저희 프로젝트의 아키텍처에 대해서 보여드리고 하나씩 설명을 드리겠습니다.

FLipit 서비스 아키텍처

 

저희의 아키텍처는 위와 같습니다.
아키텍처 설계때,  시스템의 안정성과 확장성을 우선적으로 중점을 뒀고,
시스템의 안정성과 확장성 만큼 중요한게 빠른 기간내에 개발이 가능할 정도의 적정 수준의 러닝커브였기 때문에 이 부분도 놓치지 않으려고 노력하며 설계를 했습니다.

이 아키텍처 정보를 기반으로 VPC부터 차례대로 자세한 설명을 하도록 하겠습니다.

 

 

 

 

VPC

VPC(Virtual Private Cloud)는 퍼블릭 클라우드 환경에서 사용할 수 있는 고객 전용 사설 네트워크입니다. 다른 네트워크와 논리적으로 분리되어 있어 IT 인프라를 안전하게 구축하고 간편하게 관리할 수 있습니다. 또한 기존의 데이터 센터 네트워크와 유사하게 구현할 수 있습니다. - Ncloud 공식문서 - 

 

 

VPC는 쉽게 말해,  클라우드 환경에서 public과 private subnet으로 나눠 가상으로 사설 네트워크 처럼 환경을 구축할 수 있는 서비스를 뜻합니다.
VPC를 적용해 외부로의 요청은 Internet GateWay통해 Public Subnet에 존재하는 Application에만 들어올 수 있고, 그 외의 Private Subnet에 존재하는 Application에는 접근을 하지 못하게 할 수 있습니다.

여기서 다음과 같은 의문점이 들 수도 있습니다.

 

"그냥 네이버에서 기본적으로 제공되는 ACG(Access Control Group)를 사용하면 해결되는거 아닌가??"

 

물론 ACG를 이용해서 어느정도 안전한 보안환경을 구축할 수 있습니다.

다만, 그냥 공개된 공간에서 ACG만을 의존해 보안을 구축하게된다면 다음과 같은 문제점이 발생할 수 있습니다.

 

  1. 외부에 모든 서버의 공인 IP가 노출되며, 외부에서 직접적으로 접근이 가능해짐.
  2. 외부에서 노출된 공인 IP기반으로 DDOS 공격 및 포트스캐닝 공격이 가능해짐.
  3. 클라우드 규모가 커질 수록, 공인 IP 관리 비용이 늘어남.
  4. 복잡해지는 ACG 규칙으로 관리가 어려워짐.

이렇게 ACG만으로 보안을 구축하는건 보안 관점에서 매우 위험한 일이고, 비효율적입니다.
따라서, 저희 백엔드팀은 Ncloud의 VPC 서비스를 이용해서  기본적인 네트워크 환경을 구축했습니다.

VPC의 세부 정보는 다음과 같습니다.

 

  • Public Subnet 
    • Load Balancer
    • Bastion Host Server
    • NAT GateWay
  • Private Subnet
    • AutoScaling Group
    • Server
    • MySql DB
    • Redis DB

위 처럼 기본적으로 보안이 중요한 실제 운영 서버와 DB들은 Private Subnet에 두어 외부로 노출이 되지 않게끔 설계를 하였으며, Load Balancer를 Public Subnet에 두어, 앞단에서 Internet GateWay를 통해 들어오는 요청들을 받아, 각 Server에게 트래픽을 분산시킬 수 있도록 적용하였습니다.


또한, 테스트서버 겸 Bastion Host 역할을 하는 Server를  Public Subnet에 두었습니다. 이 Server는 실제 운영하는 서버가 아닌, 운영 서버 배포전에 문제가 없는지  백엔드에서 QA를 진행하는 서버입니다.
또한 추가적으로,  Private Subnet은 외부접속으로부터 막혀있어, ssh 접속이 되지않기때문에 로컬에서 접속이 어렵습니다.
이때 이 Bastion Host가 점프 서버의 역할을 하여 로컬에서 ssh 접속을 할 수있게끔 하는 역할을 하도록 하였습니다.

 

이런식으로 저희 서버에선 VPC가 구축되어 있으며, NAT GateWay 부분은 아래에서 따로 설명을 드리겠습니다.

 

 

 

 

Load Balancer

Load Balancer는 수신 트래픽을 다수의 서버로 분산시키는 서비스입니다. 등록된 멤버 서버로 수신 트래픽을 분산시켜 가용성을 높이고 시스템 가동률을 조절하는 역할을 수행합니다. 이로 인해 워크로드의 가용성을 향상시켜 예기치 못한 서버의 장애 또는 예정된 변경 작업 등에 대하여 중단 없이 대응할 수 있도록 지원합니다. - Ncloud 공식문서 - 

 

Load Balancer는, 서버로 들어오는 트래픽을 분산시켜 안정성과 확장성을 보장시켜주는 서비스입니다.

Ncloud에서 제공하는 Load Balancer의 종류는 여러개가 있습니다. Network Load Balancer, Network Proxy Load Balancer, Application Load Balancer, Inline Load Balancer가 있는데요.
저희는 여기서 Application Load Balancer를 사용했는데, 이유는 다음과 같습니다.

 

  1. 웹 기반 서버이다 보니 80포트(HTTP), 443포트(HTTPS)만 사용함
  2. SSL을 Load Balancer에 적용시켜야함.
  3. 추후에 서버가 복잡해질 시, URL정보를 기반으로 트래픽을 나눌 가능성 존재

위와 같은 이유로 Application Load Balancer를 적용하였습니다.
좀 더 자세히 설명을 하자면, 저희 서버는 웹 기반의 서버입니다. 즉, OSI 7 계층 기준으로 7계층(Application)의 정보를 활용하는 서버입니다. 따라서 들어오는 트래픽들은 거의 HTTP, HTTPS 기반의 트래픽일 거고, 그 아래의 Transport , Network Layer를 기반으로 트래픽을 나누는 상황은 나오지 않기에 Application Load Balancer외에 다른 Load Balancer는 저희에게 필요하지 않았습니다.
또한, 저희는 DNS와 Certificate Manager를 통해 Load Balancer에 추가적인 설정을 해야하는데, 여기서 SSL 인증서를 추가하기 위해선 7계층에서 활동하는 Application Load Balancer가 필요했습니다.

 

따라서, 저희는 이러한 생각을 바탕으로 Application Load Balancer를 활용하였으며, Public Subnet에 두어, 외부로부터 트래픽을 받을 수 있도록 설정하였습니다.

 

 

 

 

DNS & Certificate Manager

Global DNS는 인터넷에서 사용하는 도메인 이름을 실제 접속 주소로 식별할 수 있도록 도와주는 서비스입니다. 개인이 직접 운영하기 어려운 DNS(Domain Name System) 서버를 클라우드 형태로 제공하여, 사용자가 서비스 운영에 필요한 도메인을 쉽고 편리하게 관리할 수 있습니다. - Ncloud 공식문서 -

Certificate Manager는 연계 서비스(Load Balancer, CDN+ 등)에서 사용할 인증서를 발급, 등록하고 관리할 수 있는 서비스입니다. - Ncloud 공식문서 -

 

저희는 앞서 말씀드렸듯이, 사용자의 정보를 통신을 통해 주고받기 때문에 HTTPS 통신이 필수적이였으며, 또한 실제 사용자분들의 접근성을 향상시키기 위해 도메인을 적용시켜야 했습니다.
이에, 이걸 적용시키기 위해 다양한 서비스들을 비교한 결과 Ncloud에서 제공하는 Global DNS와 Certificate Manager를 적용을 하였습니다.
이유는 다음과 같습니다.

 

  1. 같은 Ncloud 서비스 이다보니 개발 편의성 증가
  2. 가비아의 경우 네임서버에서 DNSSEC이 적용되지않아 보안취약점 존재

위와 같은 이유로 Ncloud의 서비스를활용하였으며, 각각 적용하여 Load Balancer에 적용을 하였습니다.

저도 이번에 개발을 하다 처음알게된 사실인데 가비아에서 기본적으로 제공하는 자체 네임서버의 경우 다음과 같이 DNSSEC을 적용하지않는다 라는 정보가 나와있습니다. 

 

DNSSEC이란 DNS를 더 안전하게 만들어주는 기술입니다. 즉, 브라우저에서 웹사이트의 도메인 이름을 입력하면 DNS가 이 도메인 이름을 숫자로 된 IP 주소로 바꾸게 되는데, 해커들이 이 과정에서 끼어들어 이상한 IP 주소를 주입할 수 있습니다.이렇게 되면, 우리가 의도하지 않은 위험한 웹사이트에 접속이 될 수도 있습니다.
이러한 공격방법을 DNS 스푸핑 공격 이라고하는데 DNSSEC은 DNS 데이터에 디지털 서명을 추가하여 공개키/개인키 구조로 검증을 할 수 있게 합니다.

 

저희의 서버의 경우 10~20대 초반의 연령대가 주 타켓입니다. 따라서 이러한 DNS 스푸핑 공격으로 인해, 불건전한 사이트 등에 접속을 하게 된다면 굉장히 치명적일 것이라 생각을 하였습니다. 따라서, 이러한 공격을 막기위해 가비아에서 구매한 도메인에 NCP의 DNS를 적용시켰고, 이로인해 이러한 보안 취약점을 개선시킬 수 있었습니다.

여기서 추가적으로, 다음과 같은 의문점이 들 수도 있습니다.

 

"Server에는 적용 안하고 왜 Load Balancer에만 적용을 시키는가?"

 

저희는 앞에서 VPC를 적용하여 외부 트래픽은 Load Balancer가 받고, 뒷단의 Private 서버들에게 트래픽을 분산시켜 전달하는 구조입니다.
여기서, Load Balancer는 외부와 직접 통신을 하기때문에, 통신의 내용이 외부 인터넷에 노출되는 상황입니다.
따라서, 악의적인 사용자가 있다면 중간에서 패킷을 탈취해서 내부 내용을 볼 수도 있고, 직접 패킷의 내용을 수정할수도 있습니다. 이를 막기 위해 SSL 인증을 적용시켜 인증키로 패킷 내부 내용을 암호화 하여 외부에서 제 3자가 패킷의 내부 내용을 볼 수 없도록 하는 것입니다.


하지만 Load Balancer가 Server에게 트래픽을 분산시킬때의 상황은 반대로 외부 인터넷이 아닌 내부 사설 인터넷망에서 통신이 이루어 집니다. 즉, 이 패킷들은 외부에 노출될 위험이 없다는 뜻입니다. 따라서 내부에서 일어나는 통신들은 암호화가 전혀 필요없기 때문에 내부 Server는 SSL 적용을 하지 않는 것 입니다. 또한 추가적으로, 내부에선 외부 사용자가 직접 접속하는게 아니므로, 도메인 적용도 할 필요가 없습니다.


따라서, 저희는 앞단의 Application Load Balancer에게만 SSL 적용 및 도메인 적용을 하였습니다.

 

 

 

 

AutoScaling

Auto Scaling은 모니터링 결과나 사용자 설정에 따라서 가상 서버 수를 늘리거나 줄여 수요 변화에 탄력적으로 대응할 수 있도록 돕는 서비스입니다. - Ncloud 공식문서 -

 

저희 서비스를 기획하면서, 서버쪽에서 해결해야할 과제가 있었습니다. Q&A기반의 서비스이다 보니 새학기 시즌에 사용자들이 몰릴 가능성이 있다 라는 것이였습니다.
물론 새학기 시즌 전에 직접 Load Balancer에 추가 Server를 붙여 Scale-Out를 하는것도 괜찮은 방법입니다.
다만, 이렇게 했을때마다 이럴때마다 업데이트 뿐만 아니라, 테스트도 진행해야 했기 때문에 시간 및 인력이 낭비된다 라고 생각을 했습니다. 또한 추가적으로 이렇게 Scale-Out을 진행 했지만, 예상만큼 사용자가 들어오지 않는다면, 그만큼 서버 비용도 낭비되는 것이라고 판단을 했습니다.

이에, 저희 백엔드 팀은 이 문제를 해결하기위해 서버의 성능을 트래픽 증감에 따라 탄력적이고 안정적으로 운영할 순 없을까??라는 생각을 바탕으로 다양한 자료를 참고하였습니다.
여기서 대안책은 AutoScaling과 Kubernates 였습니다. 이 두가지 대안책을 가지고 백엔드 팀에서 회의를 해본 결과, Kubernates를 적용하여 컨테이너로 나눠 개발하기엔  우리의 비즈니스 로직이 그렇게 크지도 않고, 또한 1달 반동안 개발하기에 러닝커브가 너무 높다 라는 결론이 나왔습니다.
따라서, Kubernates를 적용하기보단 AutoScaling을 통해서 서버의 안정성을 높였습니다.

 

AutoScaling을 적용하기 위해서 기존에 생성했던 Server를 기반으로 Server Image를 생성을 하고, 이 Image 파일을 기반으로 Source Deploy를 실행시키기 위한 init Script를 작성하여 Launch Configuration을 생성하였습니다.

 

따러서 저희는 이 Launch Configuration을 기반으로 AutoScaling Group을 생성하여 쉽게 Server를 똑같은 환경으로 생성할 수 있었습니다.

 

 

 

 

Object Storage

Object Storage는 사용자가 언제 어디서나 원하는 데이터를 저장하고 탐색할 수 있도록 파일 저장 공간을 제공하는 서비스입니다. - Ncloud 공식문서 -

 

저희 서비스의 비즈니스 로직상 사용자들의 피드에 존재하는 사진들을 저장하는 저장소가 필요했습니다.
따라서 파일 저장소인 Object Storage를 사진파일 저장소로 활용하였습니다.
AWS S3와 코드가 호환이 되기 때문에 별 어려움 없이 Spring 서버를 통해 개발을 할 수 있었습니다.

 

추가적으로, CI-CD를 진행할때 중간 빌드파일 저장소로 Object Storage를 활용했는데, 이때 AWS CLI와 호환된다고 공식문서에 나와있기 때문에 Github Action에서 AWS CLI를 통해  Object Storage에 빌드 파일을 저장했습니다.
다만, 이부분에서 AWS CLI Credentials에서 오류가 일어나 트러블 슈팅을 하는데에 애를 먹었던 부분이 있었습니다.
이부분은 아래에서 자세히 설명드리겠습니다.

 

 

 

 

Source Deploy

SourceDeploy는 새로 작성되거나 업데이트된 소스들을 자동으로 서버에 배포하고 적용해 주는 배포 자동화 서비스입니다. SourceDeploy를 사용하여 미리 설정된 사용자 기반 명령어들을 통해 소스 배포, 실행 및 검증을 자동화할 수 있고 배포 중 서비스 중단 시간을 최소화할 수 있습니다. 또한, SourceDeploy는 배포 실행 관리자를 통해 배포 실행을 제어할 수 있어, 필수적으로 필요한 배포만 적용하여 서비스의 품질을 보장할 수 있습니다. - Ncloud 공식문서 -

 

Source Deploy는 저희 서비스에서 정말 필수적인 서비스였습니다. 서버의 안정성과 확장성 생각하여 AutoScaling을 도입을 하였는데, AutoScaling의 빌드 시간이 평균 3~5분정도로 매우 오래걸렸습니다.
따라서, 실제 운영 환경에서 서버 업데이트시마다 5분정도의 다운 타임이 있었고, 이 시간동안 사용자는 저희의 서비스에 접속을 하지 못하는 문제가 발생하였습니다. 물론 여기서 배포 이후에 버그가 발생하면 그만큼 다운타임은 늘어날 것이고, 롤백도 어려워 실제 운영 상황에서 AutoScaling을 그냥 사용하는 것은 위험하다고 판단을 하였습니다.

 

따라서, AutoScaling에 무중단 배포를 적용시키기로 결정을 하였고, 그에 대한 자료를 찾던중 Source Deploy로 AutoScaling Group 무중단 배포가 가능하다는 정보를 얻었습니다.
Source Deploy없이 무중단 배포를 구현하기 위해선, LoadBalancer에 Ncloud API를 통해 새로 배포된 서버의 HealthCheck가 정상적으로 작동된 것을 확인한 이후에, 직접 Target Group을 바꾸는 방식으로 구현을 해야하는데, 이과정이 굉장히 안정성이 떨어진다고 생각을 했습니다. 또한, 기존에 트래픽이 늘어나 Scale-Out이 진행된 상황에서 무중단 배포를 진행한다고 하면 굉장히 예외상황이 많다고 생각을 했습니다.

 

Source Deploy를 활용하기 위해, Github Action을 활용하였습니다. CI 단계에서 성공적으로 빌드파일을 Object Storage 에 저장을 하게 되면, 이 이후에 Github Action에서 쉘 스크립트를 통해 Source Deploy에 API 호출을 통해 원격 실행을 하게 됩니다.
이때, API 호출 할때 필수적으로 API 키를 통한 Naver Signiture방식 서명이 필요합니다. 이것을 구현하기위해 쉘 스크립트를 작성하였으며, HTTP 요청방식 +  API_URL + 현재 TimeStamp + nCloud Access Key 정보를 조합한 이후, Secret Key로 SHA256방식 암호화를 하여 API 호출을 하였습니다. 


따라서, Source Deploy를 이용해 AutoScaling Group 자체를 블루/그린으로 배포하는 방식으로 구현하였으며, 서버의 다운 타임을 1~2초 이내로 성공적으로 줄일 수 있었고, 서버의 안정성과 확장성을 확보 할 수 있었습니다.

 

 

 

 

NAT GateWay

NAT Gateway는 클라우드 플랫폼 내부에 있는 여러 대의 비공인 IP를 가진 고객의 서버가 공인 IP 주소를 가진 외부 서버와 통신할 수 있도록 연결하는 NAT 서비스입니다. 비공인 IP 주소를 가진 다수의 서버가 하나의 NAT Gateway를 공유하거나, 여러 개의 NAT Gateway를 만들고 서버 그룹별로 각각의 NAT Gateway를 사용할 수도 있습니다. 고객이 사전에 등록한 외부의 공인 IP 주소를 가진 호스트에만 접속할 수 있도록 설정해 보안을 강화할 수 있습니다. 또한 Auto Scaling 서비스와 연결하여 새로 증설되는 서버가 자동으로 NAT Gateway를 이용하도록 설정할 수 있습니다.
- Ncloud 공식문서 -

 

저희 시스템 아키텍처를 보시면 VPC에 Internet Gateway 뿐만 아니라, NAT Gateway도 추가 되어 있습니다. 저희의 아키텍처 구조상 Private Subnet에 존재하는 서버는 내부 사설 IP만 가지기 때문에 외부와 연결될 수가 없습니다. 따라서 이 서버가 공인 IP를 가지고 라우팅이 외부와 연결이 되어있어야 외부와 통신이 가능해집니다.
저희는 Private Subnet에 존재하는 서의 통신을 가능하게 하기위해 NAT Gateway에 공인 IP를 추가하고, Private Subnet안의 라우팅 테이블에 연결 하였으며, 이를 이용해 서버에서 카카오, Naver Clova 등의 서비스에 HTTP기반 요청을 보낼 수 있었습니다.

그러면 여기서 두가지의 의문점이 들 수도 있습니다.

 

"이미 Internet Gateway가 존재하는데 이걸 활용해서 통신을 하면 되는거 아닌가?"

"NAT Gateway를 이용해 Private Subnet을 연결하면 결국 외부로 서버 자원을 노출시켜 보안취약점이 생기는거 아닌가?"

 

우선 첫번째의 대답을 하자면, 현재 Internet Gateway는 로드밸런서와 연결되어 있고, 그 로드밸런서가 내부 서버와 연결되어있습니다. 즉, Private Subnet에 존재하는 내부 서버들이 Internet Gateway를 통해 연결되려면, 로드밸런서를 거쳐야만 통신을 할 수 있는데, 서버 -> 로드밸런서 -> Internet Gateway 이런과정이 불가능하고, 로드밸런서에서 그런 기능도 제공하고 있지 않습니다. 따라서 Public Subnet에서 직접 Internet Gateway와 연결되어 있는 상황이 아니라면, Internet Gateway를 통해  통신을 하는건 불가능합니다.

 

두번째의 대답을 하자면, NAT Gateway 경우는 내부의 요청을 하나로 모아서 외부로 보내는 역할은 하지만, 외부의 요청을 내부로 들여보내는 역할은 하지 않습니다. 즉, 내부 -> 외부는 가능하지만, 외부 -> 내부는 불가능합니다.
이에 대한 예시를 들어보면, 각 집마다 존재하는 공유기를 예시로 들 수 있습니다. 저희가 집에서 보통 하나의 공인 IP를 할당받아 공유기를 사용하고, 여기서 여러개의 사설 IP로 나뉘어져서 스마트폰, 컴퓨터 등에 할당을 합니다. 여기서 저희가 컴퓨터를 할때, Naver 검색, 카카오톡 등의 외부로 다양한 요청을 보낼 순 있지만, 반대로 외부에선 저희 컴퓨터로 직접적인 요청을 불가능합니다. 이와 똑같은 원리로 NAT Gateway도 외부에서 내부로 직접적인 요청은 불가능합니다.
(물론 포트포워딩을 이용하면 가능하긴 합니다 ㅎㅎ)

 

따라서, 저희는 NAT Gateway를 활용해서 Private Subnet에 존재하는 내부 서버들의 보안을 지키면서 외부와 통신을 할 수 있게 아키텍처를 구성하였습니다. 

 

 

 

 

DB

MySQL 데이터베이스를 손쉽게 구축하고, 네이버의 최적화 설정을 통해 안정적으로 운영하며, 장애 발생 시 자동으로 복구합니다. -Ncloud 공식문서-

 

저희는 Ncloud에서 총 2가지의 DB를 사용합니다. 하나는 Mysql, 나머지 하나는 Redis입니다.
우선 Mysql은 저희 서버의 메인 DB를 구축하기위해 사용을 하였습니다. 따라서, 저희의 ERD를 기반으로 관계형 데이터베이스 구축을 Ncloud의 Mysql을 활용하여 구축하였습니다. 데이터 자동 백업 및 성능 최적화가 되어있어서 손쉽게 고가용성과 성능 안정성을 보장할 수 있었습니다.

 

Redis는 저희 서버의 Token값 캐싱에 활용하였습니다. 저희 서버는 로그인용  JWT Token과 푸시 메세지 발급용 FCM Token을 사용합니다. 즉, 2가지의 토큰을 관리하면서 DB에 있는 Tokne값을 조회하는 경우가 발생합니다. 사용자가 얼마 없을땐 그렇게 부하가 크진 않겠지만, 아무리 Ncloud의 Mysql이 성능최적화가 잘되어있다해도, 관계형 DB의 특성상, 사용자가 많아질 경우 조회시에 부하가 크다고 생각을 하였습니다.


따라서, 이런 토큰값의 경우 Redis에 이중 저장을 하여 토큰값 조회가 일어날때 1차적으로 먼저 Redis를 조회하고 존재하지 않을 시에만 Mysql DB를 조회하는 방식으로 수정하여 성능을 최적화 하기 위해 Redis를 활용하였습니다.

 

 

 

 

 

Naver Clova Studio

CLOVA Studio는 초대규모(Hyperscale) AI 기술인 HyperCLOVA 언어 모델을 활용하여 사용자가 입력한 내용에 따라 AI 기술을 통해 생성된 문구를 출력하는 네이버 클라우드 플랫폼의 서비스입니다.  -Ncloud 공식문서-

 

저희가 기획단계에서 고민을 했던 부분이 있습니다. 상대방에게 질문을 할때 어떤 질문을 해야할지 모르는 사용자가 있을 것이며, 이러한 사용자들에게 편의성을 제공할 수 없을까? 라는 고민을 했습니다.
이러한 상황에서 AI기술을 바탕으로 다양한 예시 질문들을 생성해주면 사용자 편의성이 증가할 것이라 생각을 했고, 이에 알맞은 AI 기술들을 조사한 결과 Naver Clova Studio를 활용해서 다양한 예시 질문들을 생성해주자 라는 결론이 나왔습니다.

 

Naver Clova Studio의 장점은 다음과 같습니다. 

 

  1. 한글에 특화된 AI 모델
  2. 간편하게 API처럼 호출 가능
  3. 프롬프트 기법 활용으로 서비스에 맞게 쉽게 빠르게 튜닝 가능

우선 다양한 AI 모델이 있지만 Naver Clova Studio가 가장 한글에 특화된 AI 모델이라고 생각을 했습니다.
또한, 다양한 AI모델을 기반으로 테스트를 해본결과 가장 한글 텍스트를 자연스럽게 생성하는 모델이었습니다.

그리고 API 호출을 통해서 간편하게 사용할 수 있기에 러닝커브가 적다 라는 장점이 저희에게 매우 크게 다가왔습니다.
플레이그라운드를 통해 테스트를 하며 프롬프트를 작성하였고,  이를 기반으로 테스트 앱을 생성하여 코드를 복붙만 하면 바로 API호출을 할 수 있기 때문에 간편하게 개발할 수 있다는 점이 정말 편리했습니다.
마지막으로, 프롬프트로 직접 예시를 만들 수 있어 파인튜닝 없이 튜닝 효과를 낼 수 있다 라는점이 가장 큰 장점으로 느껴졌습니다.

 

따라서, 다양한 프롬프트를 통해 손쉽게 다양한 질문을 생성할 수 있었습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ncloud 버그 해결기

 

Ncloud를 이용해 개발을 하면서 마주한 버그들이 있었습니다. 

관련 레퍼런스가 부족하다보니, 직접 계속 테스트 해보면서 버그를 해결했습니다.
이러한 부분이 혹시나 저와 같은 문제를 겪고있는 다른 Ncloud 사용자분들에게 도움이 되거나, 추후 Ncloud에 개선방향에 도움이 될까 싶어 공유합니다..!!

<이 부분은 Ncloud에서 발생한 문제가 아니라, 제가 이해도가 부족해서 발생한 문제 일 수도 있습니다. 참고 부탁드립니다.>

 

 

 

Object Storage의 AWS CLI 연동

 

네이버의 공식문서를 보면 아래처럼 Object Storage를 AWS S3 CLI를 통해서 제어를 할 수 있다고 나와있습니다.

 

따라서, 아래 처럼 AWS CLI를 통해 Naver API Key를 기반으로 인증을 손쉽게 할 수 있으며, Object Storage를 제어할 수 있습니다.

 

 

이 공식문서의 정보를 바탕으로 저희도 쉽게 AWS CLI에 인증을 할 수 있었습니다.

 

 

 

다만, 저희 백엔드 팀에서 Object Storage는 제어는 CI가 정상적으로 수행되고 빌드파일을 저장할 때 필요했습니다.

따라서, 깃허브 액션으로 직접 AWS CLI를 활용했고,  보통은 AWS CLI에서 Configure를 수행하기 위해 많은 개발자들이 aws-actions를 주로 사용하기 때문에 저희 팀도 아래의 코드처럼 aws-action의 aws credentials@v4를 사용했습니다. 

 

 

과거에 AWS S3를 깃허브액션에서 제어했을땐, 당연히 정상적으로 되었고, 로컬에서 테스트 해본 결과 aws configure이 네이버 Object Storage에도 정상적으로 작동을 했기 때문에 당연히 작동될 것이라고 생각을 하였습니다.
하지만 저희 백엔드 팀에서의 예상과 다르게 계속해서 token 인증 실패가 발생하였고, 저희의 코드 문제다 라고 생각을 해 계속 코드의 문법을 바꿔보면서 진행을 했지만, 계속해서 실패를 하였습니다.

 

 

이처럼 계속해서 Invalid Token오류가 났으며, 50회 정도의 테스트의 결과 aws-action을 이용하는건 불가능하다 라고 판단을 하였습니다. 따라서, 아래의 코드처럼 aws-actions를 활용하는것이 아닌 직접 환경변수를 설정함으로써, 해결을 하였습니다.
저두 이번에 처음알았지만 aws configure를 하지않고 그냥 환경변수를 설정하는것 만으로도 AWS CLI를 인증할 수 있었고, 이에 따라 Object Storage 직접 AWS CLI를 통해 제어를 할 수 있었습니다. 

 

 

아직 정확한 원인은 모르겠지만 aws-action에서만 invalid token 오류가 나는걸로 보아 추측컨데, 현재 aws-actions/configure-aws-credential에서 자체적으로 토큰 형식(길이,구조)을 기반으로 1차 검증을 진행하고 있는데, 현재 Naver API Key 구조와 AWS IAM Key구조가 달라서 생기는 문제가 아닐까 생각을 하였습니다.
이 부분은 정말 나중에 시간이 지나고 나면 다시 원인을 찾아보고 해결해보고 싶은 문제입니다.

 

 

 

 

 

 

Source Deploy 배포시 빌드파일 저장문제

Source Deploy를 이용해 AutoScaling 배포를 할시 아래사진처럼 배포 전, 배포, 배포 후로 나눠서 빌드 명령어를 커스텀하여 실행할 수 있습니다.

 

 

여기서 저희는 스프링 기반의 서버를 구축하였기 때문에, Object Storage에서 .zip파일을 기반으로 스프링 빌드파일인 jar 파일을 서버로 가져옵니다. 이 이후에 jar 파일을 백그라운드로 실행하기만 하면 되었습니다.
다만, Source Deploy를 그냥 실행해본결과 아래 사진처럼 랜덤한 파일 이름이 생성이되고, 이 공간에 jar파일이 자동으로 저장이 되는것을 확인했습니다. 

 

위처럼 자동으로 jar파일이 생성이 되는것을 확인할 수 있었는데, 중간에 '174074' 처럼 파일이름이 랜덤하게 바뀌면서 저장이 되었습니다.
이렇게 될경우 저희가 배포스크립트를 미리 작성할 수가 없기때문에 저희가 원하는 위치에 jar 파일을 저장하고 싶었습니다.

따라서, '파일 배포' 라는 것을 커스텀해서 저희가 원하는 위치에 jar 파일을 저장하려고 시도를 하였습니다.
하지만, 저희가 못찾은 것일 수도 있지만 이거와 관련된 자료가 없었습니다. 관련 블로그도 찾아봤고, Ncloud 공식문서도 찾아봤지만 이것을 어떻게 활용하는지 정확한 예시가 없었고, 설명도 확인할 수 없었습니다.
따라서, 저희가 직접 테스트를 해보며 '파일 배포'를 커스텀하려고 했지만 아래처럼 계속 실패하였습니다.

test-package 배포 경로 수정

 

위처럼 다양한 소스 파일 경로를 입력하면서 테스트를 해봤지만 계속해서 찾을수 없다라는 오류가 떴습니다.
계속해서 시도를 해봤지만 계속 실패를하였고, AutoScaling에 한번 배포할때마다 5분정도 시간이 소요되었기 때문에 계속해서 테스트를 진행을 할 수 없는 상황이었습니다.
따라서 '파일 배포'를 커스텀하는것은 포기하고, 배포 후 실행에서 직접 파일명을 find 명령으로 찾는 방법으로 개발을 하였습니다.

find 명령으로 파일 실행

 

이런식으로 Source Deploy를 성공적으로 적용시켰지만, 이 방식이 완벽한 방법은 아니다 라고 생각을 합니다.
따라서, 추후에 기회가 된다면, '파일 배포'를 커스텀하는 방식을 다시 시도해보려 합니다.
좀 더 관련 자료나 예시가 있었으면 좋았을 텐데... 라는 아쉬움은 남아있습니다. 

 

 

 

 

 

Naver Signiture 서명 방식

현재 Ncloud의 서비스들을 API 호출을 통해서제어를 하기 위해선 API 호출할때 각종 인증 정보를 보내야합니다.

저희는 깃허브 액션으로 SourceDeploy에게 신호를 보내기 위해 API 호출이 필요했습니다.

아래 페이지에서 각 서비스의 API에 대한 정보 및 방법에 대한 가이드 정보가 있습니다.

 

https://api.ncloud-docs.com/docs/ko/home

 

HOME

 

api.ncloud-docs.com

 

이렇게 API 호출할 때, 필요한 Header 정보는 다음과 같습니다.

 

  • 현재 timestamp 값
  • Naver Access Key
  • Naver Signiture V2 서명 값

여기서 Naver Signiture V2 서명값을 다음과 같습니다

HTTP 메서드  + Api URL 정보 + 현재 timestamp 값 + Naver Access Key

 

이 정보들을 다 합한 값을 Naver Secrets Key를 바탕으로 SHA256 방식으로 암호화를 한 값이 서명값입니다.

이 서명값을 기반으로 API 호출때 인증이 되기 때문에 매우 중요합니다.

 

이 과정이 꽤 복잡한 과정이기 때문에 쉘 명령어로 해결할 수 없었기에, 저희는 쉘 스크립트 파일을 만들어서 요청을 할 수 있게 하였습니다. 아래가 저희의 쉘 스크립트 파일입니다.

 

#!/bin/bash

# Function to sign the request
function Sign_Request() {
    local api_server=$1
    local api_url=$2
    local apicall_method=$3
    local ncloud_accesskey=$4
    local ncloud_secretkey=$5

    local unixtimestamp=$(echo $(($(date +%s%N)/1000000)))
    local message="${apicall_method} ${api_url}\n${unixtimestamp}\n${ncloud_accesskey}"

    local signature=$(echo -n -e "$message"|iconv -t utf8 |openssl dgst -sha256 -hmac "$ncloud_secretkey" -binary|openssl enc -base64)

    echo -e "x-ncp-apigw-timestamp:$unixtimestamp\nx-ncp-iam-access-key:$ncloud_accesskey\nx-ncp-apigw-signature-v2:$signature"
}

# Sample API server and URL
api_server = <API URL 정보>
api_url = <API 세부 URI 정보>
apicall_method = <HTTP 메서드>
ncloud_accesskey = <Access Key>
ncloud_secretkey = <Secret Key>
api_full_url="${api_server}${api_url}"

# Get the headers from the Sign_Request function
headers=$(Sign_Request "$api_server" "$api_url" "$apicall_method" "$ncloud_accesskey" "$ncloud_secretkey")

# Prepare header arguments for curl
header_args=()
while IFS= read -r line; do
    header_args+=("-H" "$line")
done <<< "$headers"

# Make the API request
curl -X "$apicall_method" "$api_full_url" "${header_args[@]}"

 

이렇게 로컬에서 쉘스크립트를 통해 직접 테스트를 하여, 성공적으로 작동하는 것을 확인하였고, 이 이후에 바로 깃허브 액션에 적용시켜 해결을 하려 했습니다.

이 파일을 깃허브 액션에 생성하기 위해서 깃허브액션 Secrets 에 key:value 형식으로 이 파일의 내용을 저장하였습니다.
이렇게 성공적으로 되나 싶었지만.... 아래와 같은 오류가 발생하였습니다.

 

'

정말 처음보는 오류라서, 계속 헤맸습니다. 분명히 값들도 다 정확히 매핑 시켜놨고, 로컬에선 잘돌아 가는데 깃허브 액션에서만 오류가 발생하였습니다. 

 

결국 계속해서 디버깅을 해본결과 아래 처럼 특정 값들이 빈값으로 들어온다 라는것을 확인했습니다.

 

위와 같은 현상이 일어난 이유는 저희의 쉘 스크립트 코드에 $라는 문자가 들어갔기 때문입니다. 저희 쉘스크립트 코드에서 환경변수로 설정을 하려고 일부로 $를 사용해서 코드를 작성을 한건데, 이게 깃허브액션에서도 $가 환경변수로 작동해서 쉘스크립트 코드 안의 환경변수가 아닌, 깃허브액션 Sercerts 값을 참조했고, 참조한 결과 해당 값이 존재하지않아 빈값을 주입하고 있었던 버그가 있었습니다.

이에 저희는 파일내용 자체를 깃허브 액션 Secrets를 사용하는게 아니라, 내부 변수들만 Secrets으로 넣어두고 스프링 서버 내에 쉘스크립트 파일을 넣었습니다. 따라서, 깃허브 액션에서는 이 코드를 git pull 받아 쉘스크립트 파일로 가서 설정된 환경 변수만 주입하면 되었습니다.

 

완성된 쉘스크립트 코드

 

이렇게 API 호출과 관련된 버그를 해결하였습니다.
처음엔 깃허브액션에서 사용하기 위해 Naver CLI 없이 사용하는 간단한 방법을 찾다가, 오히려 돌아온 느낌이었으며,
개인적으로, API호출과 관련된 action 코드가 있었으면 좋았을거 같다는 아쉬움이 있었습니다.

 

 

 

Private Subnet SSH 접속

이 부분은 사실 버그라기보다는 VPC내에 Private Subnet안의 서버에 SSH 접속을 하기위해서 어떤 방법을 사용해야하나 라는 저희의 고민이 담긴 문제였습니다. 기본적으로 Private Subnet 안에 있는 서버들은 외부로 노출되지않기 때문에 저희 로컬 에서도 원격으로 SSH 접속을 할 수 없었습니다. 따라서 기존의 SSH 접속방법으로는 접속이 불가능하고 다른 방법으로 접속을 해야 합니다. 저희가 생각했던 방법은 크게 3가지였습니다.

 

  1. Public Subnet에 Bastion Host를 두어, 경유를 거쳐 SSH 접속을 하는 방법
  2. VPC에 VPN Gateway추가 및 터널링을 통한 접속
  3. NAT Gateway에 포트포워딩을 통한 SSH 접속

위의 방식처럼 3가지의 방법을 생각을 했는데, 제일 비용부담이 적은것은 3번째 방식이였습니다. NAT Gateway의 포트를 내부 서버 22번 포트로 포워딩하여 내부로 SSH 접속을 할 수 있게 하면 추가 요금도 없어서 부담이 제일 적을 것이라 생각을 하였습니다.
다만, 이러한 방식의 경우 외부에 특정 포트가 노출이 되는것이기 때문에 보안 취약점이 생긴다는 단점이 있었습니다. 관련 자료를 찾아보니 Ncloud에서도 이러한 문제점 때문인지 NAT Gateway를 포트포워딩하는 기능은 제공하고 있지않았기에, 이 방식은 적용할 수 없었습니다.

 

이게 1,2번 두가지 방식이 있는데, 두 가지 방식 다 비용 부담이 컸었습니다. 첫번째 방식은 Server의 기본요금 자체가 커, 시간당 최소 120원 이상의 가격이 들었고, 두번째 방식은 VPN Gateway를 뚫는거 자체가 시간당 138원이 들었습니다. 
이미 운영 서버와 DB에 가격부담을 느끼고 있던터라, 여기에 적지않은 요금을 투입하는거 자체가 저희 팀에 큰 부담으로 느껴졌고, 또한, 단지 SSH접속만을 위해서 VPN을 사용한다는거 자체가 조금 말이 안된다 라고 생각을 했습니다. 

이에 저희는 평상시엔 네이버 웹페이지에 있는 서버 접속 콘솔을 이용하기로 하고, 긴급한 버그 해결이라던지, 아니면 대규모 수정을 해야할 부분이 있다 라고 할때만 따로 Test Server를 생성하여 Bastion Host 역할을 할 수 있게 하자 라는 결론이 나왔습니다.

이 부분은 결국 근본적으로 해결을 하지못한 상황입니다. 혹시나 다른 해결책이 있으시면 알려주세요 ㅎㅎ

 

 

 

 

 

 

 

 

 

Ncloud 사용중 만족했던 점 & 아쉬웠던 점

 

우선 Ncloud를 사용하면서 만족했던 점은 다음과 같습니다.

 

  • 한글로 되어있는 공식문서
  • 높은 AI 편의성

Ncloud를 활용하면서 정말 편했던 점은 공식문서가 한글로 되어있다는 점이었습니다. 따라서 공식문서를 기반으로 쉽게 개발환경을 세팅할 수 있었습니다.
또한, 추가적으로 Naver Clova Studio에서 플레이그라운드로 AI를 사용할떄 정말 많은 편리함을 느꼈습니다.
타 AI기술과 다르게 직접 웹을 통해 튜닝하고, 테스트를 해 볼 수 있다는 점이 정말 편했습니다.
이를 기반으로 저희 백엔드 팀에서 AI 지식이 많이 없음에도 불구하고 빠르게 개발이 가능했습니다.

 

 

반대로 Ncloud를 사용하면서 아쉬웠던 점은 다음과 같습니다.

 

  • 관련 레퍼런스 부족
  • Server 및 DB의 과도한 최저성능 및 요금

Ncloud를 사용하면서 정말 많이 느꼈던게, AWS Cloud에 비해 블로그같은 레퍼런스가 찾기가 매우 어려웠습니다. 물론 사용자 차이로 인해 당연히 자료가 부족한게 당연하겠지만... 한번 버그가 일어나면 공식문서 외에는 참고할 자료가 없었습니다. Object Storage나, Source Deploy같은 서비스의 경우는 AWS와 비슷하겠지.. 하면서 S3 및 Code Deploy 관련 자료를 찾아보면서 해결했어야 했습니다. 따라서 이러한 참고 자료를 좀더 다양하게 존재했으면 좋겠다... 라는 아쉬움이 있었습니다.

 

또한, 아래의 자료가 현재 NaverCloud의 Server 및 DB의 요금페이지 입니다.  

https://www.ncloud.com/product/compute/server

https://www.ncloud.com/product/database/cloudDbMysql

위의 사이트에서 보면 아시겠지만 VPC 기준으로 Server의 기본 요금은 119원, MySQL DB의 기본 요금은 256원 입니다.
아직 학생의 입장이라, 서버와 DB의 최저 성능이 너무 높게 느껴졌고, 그로인한 요금에 대한 부담이 크게 다가왔습니다.
특히 VPC 경우, 직접 Private Subnet에 ssh 접속을 하지 못하다 보니 Bastion Host용 서버가 필요한데, 이 접속용 서버로 vCPU 2, 메모리 8GB, 디스크 50GB가 너무 오버스펙이라는 생각이 들었습니다..ㅠㅠ
따라서, VPC 용도로 프리티어 같은 낮은 성능의 Server를 1개 정도 생성할 수 있도록 하면 괜찮지 않았을까.... 라는 아쉬움이 있었습니다.

 

 

 

 

 

 

Green Developers 프로그램 참여 소감

 

이번에 동아리에서 우연히 네이버의 Green Developers 프로그램에 참여하게 되었는데, 클라우드에 관심 있는 개발자에겐 정말 너무 좋은 기회다 라고 생각합니다.


사실 처음에는 그냥 Server와 DB만 사용할 목적으로 신청을 했지만, 홈페이지를 보니 정말 다양한 Ncloud의 서비스가 있었습니다. 따라서, 이번 기회에 다양한 클라우드 제품들을 써볼까 싶어 Ncloud의 모든 서비스들을 분석하였고, 또한 제한된 크레딧 내에서 어떻게 하면 효율적인 비용으로 아키텍처를 구성할 수 있을까 고민을 많이 하면서 개인적으로 성장을 많이 했다고 생각합니다.

 

특히 관련 레퍼런스가 적다보니 조금은 힘들었지만 AI 및 관련자료 없이 혼자서 고민을 하는 시간이 많았어서 더욱 더 많이 배우고 기억할 수 있었던 값진 기회였던거 같습니다.
이번에 이렇게 좋은 기회를 주셔서 너무 감사드리고, 이번 경험을 바탕으로 다음에 다른 Developers 프로그램이 있다면 참여하여 학습을 해보고 싶습니다!!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함