들어가며…

안녕하세요👋, 개발자 최승환 입니다!! 🧑🏻‍💻 이 문서는 저희 서버 개발팀의 인프라 이전 경험을 공유하기 위해 작성하게 되었습니다!

앞으로 이 문서를 시작으로, lagacy Cloud 환경에서 AWS EKS 환경으로 인프라 이전을 했던 경험들을 공유 할 예정입니다. Kubernetes, EKS에 관심이 있으시거나, 스타트업 팀에서는 Kubernetes 를 어떻게 운영하고 있는 지 궁금 하셨던 분들에게 도움이 되었으면 좋겠습니다. 🙇🏻‍♂️

(인프라 이전 작업은 제가 이직한 후 3개월이 지난 시점부터 진행하게 되었는데요, 때문에 저의 회사 적응과 함께 한 작업이기도 합니다.😄 인프라 작업을 하면서 이전에 어렴풋이 알고 있던 것들이나 잘 모르던 부분들을 배우게 되는 점이 많아 참 좋았고, 일을 한다기 보다는, 제가 좋아하는 CS 지식들을 마구마구 공부한다는 느낌이 많이 들어 좋았던 것 같습니다!)

인프라 이전 경험에 관한 글은 Kubernetes와 이에 관련된 기술 배경 지식부터 ~ hands-on 으로 EKS 환경을 구축해가는 과정들을 정리해 갈 예정입니다.


기존 환경의 문제점

우선 기존 레거시 인프라 환경에서 어떤 문제가 있었고, 무엇을 개선하고자 하였는 지 알아보아야 할 것 같습니다.

컨테이너화 되어 있지 않음

저희 웹(API)서버KT Cloud VM(virtual machine) 환경에 코드를 배포하여 PM2를 이용해 서버 인스턴스를 띄우는 방식으로 구축되어 있었습니다.

이는 Node.js 서버를 구축할 때 일반적이고 기본적인 방식으로, 보통 중소 규모의 서비스나 혹은 간단하고 빠르게 배포하고 싶은 토이 프로젝트의 경우 이와 같은 방식으로 인프라를 구성하게 될 것입니다. 더욱이, PM2싱글 스레드로 동작하는 Node.js 앱을 멀티 프로세스 방식으로 동작할 수 있게 해주는 훌륭한 도구이기도 합니다.

하지만 저희 팀에서의 첫번재 문제점은 기존 웹서버Node 10 버전으로 구현되어 있는 레거시 환경이라는 것에 있었습니다.

Node 버전이 낮아 최신 버전에서의 퍼포먼스 향상을 적용할 수 없다는 문제 이외에도, Node 버전이 낮음으로 VMUbuntu 버전을 올릴 수 없는 문제도 있었고, Ubuntu의 버전을 올리지 못하여 MongoDB의 버전 또한 올릴 수 없는… 레거시 환경이 꼬이고 꼬일 대로 서로 엮여 있었기에, 컨테이너화를 통해 각각의 독립적인 환경 구축이 시급하였습니다.

또한 현재 쓰고 있던 구버전의MongoDB에서 원인은 정확히 알 수 없었으나, connection의 release가 제대로 되지 않아 메모리가 계속 상승하다가 mongoDB를 운용 중이던 VM이 터져버리는 문제가 있었습니다. 때문에 MongoDB 버전 업그레이드가 필요 하였고, (인프라 작업 의사 결정 당시엔 mongoDB 버전 문제일 줄 알았으나, 서버 코드 상의 오류 였습니다.)

팀 내 개발자들이 Windows, Mac 각각 다른 환경에서 개발을 하고 있었기에, 애플리케이션의 독립적인 환경을 보장하기 위해 컨테이너화가 필요 하였습니다.

서버 자원의 증감이 유연하지 못함

트래픽에 따른 서버 자원의 증감이 유연하지 못한 문제점도 있었습니다. 유저들에게 마케팅용 푸쉬 알람을 보냈을 때 순간 트래픽이 급증 하였는데, 이와 같은 상황에서 서버 자원을 늘리는 일이 자동화 되어 있지 않았고, 유저의 트래픽이 몰릴 때 서버가 불안정한 이슈도 있었습니다.

항상 최대 트래픽을 받을 수 있는 서버 자원을 띄워 놓아야 함

위 ‘서버 자원의 증감이 유연하지 못하다’는 이슈와 마찬가지로, 불시에 유저 트래픽이 늘어날 지도 모르는 상황이다보니 항상 최대 수용량 만큼의 서버 자원을 띄워 놔야 했습니다. 이는 서버 비용의 낭비이기도 합니다.

모니터링 도구가 없음

한 곳에서 로그를 수집해주는 (예를 들어 ELK ) 도구가 없어 레거시 환경에서는 서버에 이슈가 발생 했을 시, 각각의 VM에 따로 쉘 접속을 하여 PM2 log 를 찍어 봐야 했습니다. 로그의 상세한 분석을 위한 로그 쿼리 조작에도 어려움이 있었고 장애 발생 시각을 지정하여 로그를 분석하는 것도 불가능 하였습니다. 또한 각각 서버 인스턴스에 개별적으로 접속해야 하는 불편함, 시간 낭비도 있었습니다.

서버의 매트릭 정보를 수집하는 데에도 문제점이 있었습니다. KT Cloud 자체적으로 제공해주는 VM 분석 도구에서 CPU, Memory 사용률은 제공 되었으나, VM 정보가 수집 될 뿐, Node.js 서버 인스턴스의 매트릭 정보가 수집되는 것은 아니었고, CPU, Memory, 네트워크 Byte In/Out 이 항목들만 수집되다 보니 좀 더 세부적이고 정확한 매트릭 정보의 수집이 필요 하였습니다. 추가로, 수집 되는 지표의 가장 최소 단위가 15분 이라는 단점도 있었습니다.

위 문제점들은 Container / Kubernetes를 도입 하였을 때의 장점이기도 함

역으로, 위 문제점들은 서버의 컨테이너화컨테이너 오케스트레이션 도구인 Kubernetes를 도입 하였을 때의 개선점이자 장점이기도 합니다.

Kubernetes를 도입하여 앱 서비스들은 개별의 컨테이너 환경을 구축하여 독립적이고 보장 받은 환경에서 동작하도록 할 수 있게 되었고, Kubernetes의 오토스케일링(HPA, CA), Replicaset 을 통해 서비스(Pod) 을 유연하게 관리할 수 있게 되었습니다.

또한 Kubernetes 생태계에서 주로 사용 되는 모니터링 도구인 Prometheus, Grafana, Loki 를 도입하여 서버의 매트릭 정보 수집과 로그 데이터 수집을 시스템화 하여 관리할 수 있게 되었습니다.

팀 내 인프라 담당자나 Kubernetes에 깊은 이해도를 갖은 팀원이 없었기에, 단계 별로 하나 하나 학습해가며 인프라를 구축해가야 했습니다만, 덕분에 제가 이미 시스템이 갖추어진 대기업에 다니고 있었다면 겪지 못했을 경험들과 개발 고민들을 할 수 있었던 좋은 기회였던 것 같습니다.

인프라 작업 초기, Kubernetes 도입 여부를 검토하던 시점에선 높은 학습 곡선으로 인해 도입 여부를 많이 고민하기도 하였지만, 현재 EKS에 Production 환경까지 구축한 시점에선 Kubernetes를 사용하여 얻은 기술적 만족감이 대단히 높은 상태입니다.

또한 Kubernetes 도입을 고민하는 다른 스타트업 팀에서도 Kubernetes를 도입 하였을 때의 얻는 기술적 이점들을 생각해보면, 도입하지 않을 이유가 없다고 생각됩니다. 물론 초기에 발생되는 러닝 커브가 있긴 하겠지만, 학습에 필요한 처음 한 달을 지나고 나면, 앞으로 우리 팀이 달려가야 할 긴 여정에 비추어 보았을 때, 그 가치를 충분히 발하고도 남을 거라 생각됩니다.

그럼 다음 장에서부터 Kubernetes의 배경 지식들에 관해 알아 보도록 하겠습니다.


CNCF (Cloud Native Computing Foundation)

Untitled

우선 가장 먼저 Cloud-NativeCNCF(Cloud Native Computing Foundation) 에 대해 얘기 해야 할 것 같습니다.

Cloud-Native란 애플리케이션 인프라 환경을 구축함에 있어 Cloud 기술을 최대한 활용하여 구축하는 것을 뜻합니다. 애플리케이션의 인프라 환경을 Cloud-Native 하게 구축하게 되면 위에서 얘기 했던 것과 같이 애플리케이션 운용에 있어 여러 장점들이 있습니다.

Untitled

Cloud-Native 환경에서는 모든 애플리케이션은 컨테이너 형태로 관리되게 됩니다. 컨테이너란 우리가 화물 선박 등에서 떠올리는 그 컨테이너와 동일합니다. Cloud 환경에서는 컨테이너의 내용물이 화물이 아닌 응용 프로그램이 되게 됩니다.

컨테이너라는 이름에서도 알 수 있듯이, 컨테이너는 인프라 환경이 구축된 곳이라면 어디에든 쉽게 배포할 수 있습니다. CI 과정에서 테스트/검증 된 애플리케이션을 잘 동작하는 것이 보장된 독립적인 환경으로 컨테이너화 합니다. 그리고 이 컨테이너Image 형태로 Build한 후, Image 저장소에 배포합니다. 그 후, AWS, GCP와 같은 Cloud 환경에서 저장소에 올라간 Image를 내려받아 Docker와 같은 컨테이너 런타임 도구로 컨테이너를 동작 시키게 됩니다.

Cloud-Native 의 가장 큰 특징은 민첩성유연성 입니다.

위 일련의 과정들은 Cloud-Native 한 애플리케이션의 배포 과정 입니다. 계속적으로 등장 하는 컨테이너란 키워드에 주목할 필요가 있습니다. 컨테이너Cloud-Native 환경에서 관리 대상이 되는 리소스의 최소 단위라고 할 수 있습니다. 그리고 이 컨테이너로 인해 Cloud-Native 한 인프라는 민첩성유연성을 제공할 수 있습니다. 더 이상 애플리케이션은 머신 환경에 종속적이지 않습니다. 캡슐화 되어 있습니다. 애플리케이션의 수정 사항이 발생 했을 경우, 단순히 이미지화 된 컨테이너Cloud에 배포 하기만 하면 됩니다. 뿐만 아니라 Cloud의 이전 역시 컨테이너 를 옮겨 가듯이 단순한 방법으로 이전할 수 있습니다.

Cloud-Native 인프라 환경은 애플리케이션에만 국한되는 것이 아닌, 개발 조직과도 연관이 있습니다.

개발 패러다임과 기술의 발전에 따라 Frontend - Backend 두 진영으로 개발 팀과, 포지션이 분리 되었듯이, Cloud 분산 환경에서 도메인에 따른 마이크로 서비스 가 가능해졌고 개발 조직에 민첩함을 관건으로 한 애자일 개발 방법론의 적용이 수월 해졌습니다.

‘기술의 발전’과 ‘패러다임’의 관계는 어느 분야에서나 밀접하게 나타나는 것 같습니다. 그리고 이러한 기술 발전에 긍정적인 영향을 주려는 단체가 있습니다. 바로 CNCF(cloud native computing foundation) 입니다.

CNCF(cloud native computing foundation)는 위에서 설명 하였던 Cloud-Native 생태계 기술들을 오픈 소스로 관리하고 지원해주는 단체 입니다. CNCF는 컨테이너 오케스트레이션 툴인 Kubernetes 1.0 버전과 함께 발표 되었습니다. Kubernetes는 구글에서 만들었지만, 구글은 CNCF 재단에 Kubernetes의 운영권을 넘기기로 결정합니다. 이는 마치 Android 의 사례와 유사해 보입니다.

현재에도 그렇지만, 미래에는 Cloud가 더욱 더 우리의 삶에 영향을 많이 주게 될 것입니다. 구글은 기술 판매의 단기적인 영업 이익을 기대하기 보단, 높은 기술 점유율에서 파생되는 다른 부가 가치로 영업 이익을 실현해 가려는 것일 겁니다. (실제로 Kubernetes… 너무 좋습니다…)

사족이 길었습니다. CNCF는 다른 오픈 소스 커뮤니티가 그러 하듯이 Vender 중립적이게 Cloud 기술들을 관리 합니다.

Untitled

CNCF landscape 페이지에서 Cloud 기술 동향을 볼 수 있습니다. 생각보다 다양한 기술들이 CNCF 재단에서 관리되고 있다는 것이 놀라웠습니다. 앞으로 Cloud 기술 스택을 선택할 때 좋은 참고가 될 듯 합니다.

CNCF와 같은 오픈 소스 커뮤니티 문화가 개발 문화의 큰 장점이라 생각 합니다. 서로 기술을 공유하며 긍정적 시너지를 발하는 것이 참 멋진 것 같고, 오픈 소스에 기여하거나 정보를 공유 함으로써 기술 발전에 이바지 하고 있다는 공학인으로서의 사명감까지 드는 것이 참 멋진 일인 것 같습니다! 😄👍, 이것이 제가 기술 문서를 작성하는 이유이기도 합니다.

그럼 Cloud-Native 가 무엇인지와, Cloud 기술들을 관리하는 CNCF에 관하여 알아 보았으니, 본격적으로 CNCF의 첫번째 졸업 작품인 Kubernetes에 관해 알아보겠습니다.