[네이버 클라우드 서포터즈] 배포 환경 구축편

himitery·2022년 10월 14일
0
post-thumbnail

10월 04일에 네이버 클라우드에서 개발 서포터즈를 위해 300만원의 크레딧을 지원해주셨습니다! 👍
올해까지 크레딧을 사용할 수 있어서, '오늘의 빵' 서비스의 서버를 배포하는데 매우 넉넉한 것 같습니다.

'오늘의 빵' 서비스의 기술스택은 이전에 설명드렸던 부분에서 조금 달라진 부분이 있습니다.
먼저 Mobile Application 부분에서 Flutter를 사용하기로 계획 했었지만, React Native로 사용 기술을 변경하게 되었습니다. 주된 이유는 Flutter에서 GraphQL을 사용하는 것보다 React Native에서 GraphQL을 사용한 경험이 더 좋았기 때문입니다. 개인적으로 Apollo Client를 사용하였을 때, Cache를 조작하는 방법이 React Native를 사용하게 만든 가장 큰 이유가 된 것 같습니다.
다음으로는 DatabaseMySQL에서 PostgreSQL로 변경하게 되었습니다.

변경된 기술스택을 기준으로 배포 환경을 구축하였습니다.
이전의 대부분의 프로젝트에서는 Github Actions로 CI/CD를 구축해서 사용했었습니다. 서버를 Github Actions의 Runner로 등록하였고, 해당 Runner 내에서 Docker Image를 새로 가져오고 서비스를 새로 시작하는 방법을 적용했습니다. 이러한 방법을 사용한 이유는 환경을 구축하는 시간이 매우 짧고 간편하기 때문입니다. 보통 실제 배포를 통해 서비스 하려는 목적이 아닌 학교에서 프로젝트를 진행하거나 대회에 참여하기 위한 목적이었기 때문에 가능했던 배포 방법이었던 것 같습니다.
그래서 이번에는 기존 방법과는 다르게 Kubernetes를 이용하여 배포를 진행하기로 하였습니다. Kubernetes를 이용한 배포 환경은 이전에 학생 개발자로 일했던 스타트업과 당근마켓 개발 인턴에서 경험 했었습니다. 그때의 경험이 매우 좋았었기 때문에 항상 Kubernetes를 이용해서 배포 환경을 직접 구축해보고 싶었는데, 비용 문제와 시간 문제로 못하고 있다가 이번 기회에 해보게 되었습니다.

아래는 이번 배포 환경 구축에서 사용한 기술입니다.

  • [NCP] Kubernetes Service
  • [NCP] Container Registry
  • [NCP] Object Storage
  • [NCP] VPC
  • [NCP] Load Balancer
  • [NCP] Cloud DB for Redis
  • [NCP] Cloud DB for PostgreSQL
  • Docker
  • Github Actions
  • ArgoCD
  • Elasticsearch
  • Fluent-bit
  • Kibana

아무래도 Kubernetes와 인프라에 대한 개념이 부족한 상태로 시작했던 것과 학교 수업을 들으면서 진행을 했기 때문에, 환경을 구축하는데 3일정도의 시간이 소요 되었던 것 같습니다.



ArgoCD를 통해 확인한 배포 상태입니다.
Application Server는 Replica set을 3으로 설정하여, 항상 3개의 POD를 가지도록 하였습니다. 3개의 POD를 외부에서 접근할 수 있도록 service에서 LoadBalancer를 설정하였습니다. 각 POD에 직접 접근하는 것이 아닌 LoadBalancer를 연결해주었기 때문에, 사용자의 요청을 자동으로 분산해서 각 POD로 보낼 수 있도록 하였습니다. 여기서 NLB(Network LoadBalancer)를 설정해주었는데, '오늘의 빵' 서비스 환경에서는 ingress를 통해 더 복잡한 설정이 가능한 ALB(Application LoadBalancer)의 사용이 불필요하다고 생각하여 NLB를 사용하게 되었습니다.
로깅을 위한 EFK에서 Elasticsearch와 Kibana를 처음에는 helm를 이용해서 배포를 하였지만, Kibana의 접속 포트를 80번 포트로 바꿀 수 없는 점과 xpack을 이용한 인증을 설정하는게 어렵다는 점으로 인해 Application Server와 마찬가지로 yml 파일로 직접 정의를 해주었습니다.
Kibana 또한 LoadBalancer를 통해 접근이 가능하기 때문에 로그인을 통한 인증이 가능하도록 하였습니다. 사실 VPN을 설정해서 외부의 접근은 차단하고 ArgoCD와 Kibana에 접근할 수 있도록 할 수도 있었지만, 서비스의 비용을 보고 바로 포기했습니다.🥲

추가로 Fluent-bit가 Spring boot의 로그를 수집할 수 있게 하기 위해서 Logback을 설정해주었습니다.

  • build.gradle
implementation 'org.fluentd:fluent-logger:0.3.4'
implementation 'com.sndyuk:logback-more-appenders:1.8.7'
  • logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender class="ch.qos.logback.more.appenders.DataFluentAppender" name="FLUENT_TEXT">
    <label>logback</label>
    <port>24224</port>
    <remoteHost>localhost</remoteHost>
    <tag>debug</tag>
  </appender>
  <appender class="ch.qos.logback.core.ConsoleAppender" name="CONSOLE">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>
        %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
      </Pattern>
    </layout>
  </appender>

  <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
  <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>

  <root level="info">
    <appender-ref ref="CONSOLE"/>
    <appender-ref ref="FLUENT_TEXT"/>
  </root>
</configuration>



Kibana를 통해 확인한 로그입니다.
Elasticsearch와 Kibana에서 xpack 설정을 통해 인증 기능을 활성화 했기 때문에, 접속하게 되면 아이디와 패스워드를 입력받게 됩니다. 로그인을 하고 접속하게 되면, 바로 로그를 확인할 수 있는 Discover 화면이 보이도록 하였습니다. 필터를 설정해서 '오늘의 빵'의 Spring boot 서버에서 발생한 오류만 볼 수 있게 설정하였고, "GraphQL Error"라는 검색어로 직접 로그를 검색할 수도 있습니다.

처음으로 Kubernetes를 이용해 배포 환경을 설정해보면서 어려웠던 점도 많았던 것 같습니다. 그래도 막상 설정하고 보니 개발을 진행하는데에 있어 매우 만족하였습니다.
서버에서 새로운 기능을 작업하고 main 브랜치에 merge를 하면 자동화된 배포 시스템을 통해 배포가 진행되고, ArgoCD를 통해 배포 상태를 확인합니다. 또한 Kibana로 서버의 로그를 한눈에 확인할 수 있기 때문에 항상 서버에 접근하는 번거러운 작업이 없어져서 개발하기에 편해진 것 같습니다.
다만 생각했던 것보다는 비용이 많이 들고 있습니다.. 300만원이면 충분하고 남을 것 같아서 자원을 넉넉하게 사용했더니 하루에 약 5만원 정도의 비용이 나가고 있는 것 같습니다.

이제 배포 자동화도 구축이 되었으니, 남은 기간동안 앱과 서버의 기능 개발에 집중하려고 합니다! 😁

0개의 댓글