Micro Service, Docker로 할 수 밖에 없었던 사연
올해 초부터 북경에서 업무를 시작한 이후에 여기서 하고 있는 일에 대해 정리를 해보려고 여러번 시도를 했었는데 여러 이유들 때문에 정리하지 못했었습니다. 첫번째 이유는 한국, 북경 크게 다른 것도 없고 두번째는 제대로 같이 일을 하지도 하지 않은 상태에서 글을 쓴다는 것에 대한 찜찜함이 그 이유였던 것 같습니다. 이제 9개월 정도 지난 시점에서 여기 개발 조직과도 같은 생각을 하게 되었고 여러 이야기를 나누고 경험을 한 것 같아서 글로 정리를 해볼까 합니다. 그 첫번째 글로 현재 서비스의 주요 구성이 되는 Docker, Micro Service, Event Driven에 대해 살펴보겠습니다.
신규 사업에 대한 도전! 그러나 개발 조직은?
처음 시스템의 아키텍처와 구성을 봤을 때 조금은 이상하다고 생각했었습니다. 서비스는 아주 작은 단위로 쪼개져 있고 이렇게 쪼개어진 서비스들은 Docker 에서 실행되고 있었으며, 각 서비스들간의 호출은 Kafka를 사용하여 Event 방식으로 처리되고 있었습니다. 북경으로 합류하기 전에는 기술력이 그렇게 높지 않은 개발 조직이고 각 개발자의 개발 역량도 높지 않다고 들었기 때문입니다.
팀 적응을 위해 이것 저것 물어보고 몇개 기능을 개발하면서 이런 구성을 선택한 이유를 알게 되었습니다. 그 이유는 간단 했었습니다. 개발 조직 전체의 역량과 관련되어 있었습니다. 새로운 서비스를 만들려고 도전을 시도한 시점의 개발 조직은 다음과 같은 상황이었습니다.
- 개발자는 40 ~ 50명 정도
- 대부분의 기술은 C#, Form 기반의 Client/Server, Stored Procedure를 이용한 개발 환경, 웹 개발 경험이 거의 없음
- C#의 풍부한 기능을 사용하기 보다는 Stored Procedure에 의존
- 새로운 시스템 또는 서비스를 개발한 경험 보다는 기존에 만들어진 프로그램을 수정, 신규 기능 추가 위주의 업무 경험
- 시스템 모델링 경험 부족
- 개발 조직을 이끌고 갈 Senior 개발자의 부재
- 인프라 운영 경험이 있는 직원이 없음
이런 상태에서 오프라인 커머스 시장에 새로운 활력을 주는 클라우드 서비스를 신규 사업으로 확장하고자 SaaS 서비스를 만들기로 결정하였습니다.
설계는 커녕 개발도 어렵다.
새로운 서비스를 만들고 운영하기 위한 아키텍팅, 설계, 개발, 운영 어느 하나라도 경험이 있는 부분이 없었습니다. 그것도 단순히 요구사항만 만족시키면 되는 것이 아니라 서비스 수준이 높은 클라우드 서비스를 만들어야 하는 미션이었습니다.
어쩔 수 없는 선택
일단 운영, 인프라 이런 문제는 차치하더라도 기능이라도 개발을 하는 것이 우선이었습니다. 하지만 설계 능력이 부족한 상황에 이들을 이끌고 갈 Senior 개발자가 없는 상태에서 신규 서비스 개발은 거의 불가능에 가까웠습니다. 그래서 선택한 것이 마이크로 였습니다. 제가 마이크로 서비스 아키텍처 라고 하지 않고 그냥 "마이크로"라고 한 것이 핵심이었습니다.
각 개발자에게는 다음과 같은 방식의 미션이 부여 되었습니다.
- "이번주에는 사용자의 입력을 받아 DB 테이블에 저장하는 API 하나만 만들자"
복잡한 문제 해결 경험이 부족하니 주어진 문제 하나만 해결하라는 것입니다. 어떤 언어를 사용하든 상관없고 가장 잘 사용하거나 사용하고 싶은 언어로 만들면 되었습니다. 어차피 하나의 정보만 입력하면 되니 모델링은 필요 없었습니다. 만들 프로그램은 유연할 필요도 없고, 유지보수성을 생각할 필요도 없다고 하였습니다. 코드 내에 하드 코딩된 정보가 있어도 상관이 없었습니다.
동작하는 코드를 만들어라.
이것이 첫번쨰 미션이었습니다.
이렇게 만들어진 API에 화면을 붙이고 몇개의 API를 더 만들어 한달만에 실제로 동작하는 하나의 서비스를 만들었습니다. 물론 어떤 것을 만들어야 하는지를 정의하는 사람은 있었습니다. 2016년 봄 북경에 오신 안영회 님이 무엇을 만들어야 하고 다음에는 무엇이 연결되어야 하고 하는 등의 중요 설계 작업을 진행했었습니다.
즉 아키텍처, 시스템 구성, 모델링, 개발 프로세스를 고민하고 만들었다기 보다는 현재의 조직 구성원으로 서비스를 만들 수 있는 가장 최선의 방법을 선택한 것입니다. 복잡한 것은 만들기 어려우니 아주 잘게 쪼개고, 잘 만들고 있는지도 모르겠으니 일주일에 한번씩 확인하는 방식이었던 것입니다. 안영회 님이 이야기하는 "아기 발걸음" 으로 시작한 것입니다.
다시 개발하기
첫번째 미션이 "동작하는 코드를 만들어라" 였다면 두번째 미션은
다시 개발하라
였습니다.
코드의 품질도 상관없고, 성능, 데이터 정합성 이런 것을 전혀 고려하지 않고 만든 첫번째 서비스는 당연히 운영 중에 많은 문제를 발생시킵니다. 하지만 첫번째 미션을 성공하면서 개발팀은 웹 개발에 대한 경험을 했고, 자신이 만든 프로그램이 어떤 기능을 수행하는지 실제 돌아가는 서비스를 통해 확인할 수 있었습니다. 어느 정도 성과는 있었지만 최소한의 품질은 있어야 했기 때문에 대책이 필요 했습니다.
이 경우 리팩토링을 선택할 수도 있는데 현재 돌아가는 서비스를 개선하기 위해 리팩토링을 선택하기 보다는 아예 새로 만드는 것을 선택했습니다. 리팩토링이 뭔지도 모르니 그냥 새로 짜는 것이 더 좋다고 판단한 것입니다.
그리고 재개발해도 크게 문제가 되지 않은 것이 개발자 한명 한명 입장에서 보면 몇개의 API만 새로 만들면 되기 때문입니다. 그리고 API의 In/Out만 동일하면 다른 서비스와의 관계도 고려할 필요가 없기 때문입니다. 이것은 큰 부담이 되지 않고, 많은 시간이 걸리지도 않습니다. 이제 조금 성장했고 무엇을 만들어야 하는지 알고 있기 때문에 새로 개발할 때에는 더 좋은 코드를 만들수 있게 되었습니다. 그렇다고 여전히 아주 잘 만들지는 못합니다.
이제 이 개발 조직은 재개발이 일상이 되었습니다. 그냥 동작하는 코드를 만들고, 그 다음은 다시 개발하고, 또 다시 개발하고...
애자일이 일상으로
이렇게 기능을 작게 쪼개서 만들고, 자신들이 재대로 만들고 있는지를 모르니 매주 마다 점검받고 짧은 배포가 일상이 되다 보니 정작 본인들은 모르겠지만 애자일이 일상이 되었습니다. 물론 흔히 말하는 애자일의 일반적인 모습과는 다를 수는 있지만 기민하게 움직이고, 점검하고, 액션하는 큰 흐름에서는 비슷하게 움직이고 있습니다.
여기 개발 조직이 이렇게 운영되고 있는 동안 이 회사의 다른 조직은 변하지 않아서 시스템 개발 요구사항을 주면서 6개월의 WBS(Work Breakdown Structrue)를 요구 받기도 하였습니다. 이제 이 개발 조직은 그런거는 아무 의미가 없고 언제든지 변할 수 있으며, 우리가 측정 가능한 것은 기껏해야 2주 이내라는 것을 알게 되습니다. 이제는 그런 요구사항을 낸 상대방에게 Bullshit이라고 외치고 있습니다.
개발은 했지만 운영은?
다음 고민은 운영에 대한 부분이었습니다. DB, Linux 서버 운영 등의 경험자가 없으니 당연히 클라우드 사용하는 방향으로 결정되었습니다. 중국에서는 알리 클라우드라고 알리바바에서 운영하는 클라우드 서비스가 가장 많이 사용하는 클라우드 서비스입니다. 가상머신, 데이터베이스, 스토리지, Mongo, Redis 등 아마존에서 제공하는 것과 비슷한 기본 구성들은 모두 제공되고 있었습니다.
Linux 그게 뭔가요?
데이터베이스 등은 알리 클라우드에서 기본적으로 제공하는 서비스를 사용하면 되지만, Linux 서버에 웹서버, 애플리케이션 서버, Kafka 등을 설치하는 등의 작업을 할 수 있는 인력이 없었습니다. 지금까지는 대부분의 개발자가 Windows 기반이었기 때문입니다. 그래서 선택된 것이 Docker 입니다. 왜 Docker를 선택했는지 물어보니 다음과 같은 답변을 들을 수 있었습니다.
- 프로그램 개발 하는 것 처럼 configuration 만 하면 서버를 쉽게 구성할 수 있다.
- Linux 커맨드 등을 잘 알지 못해도 이미 구성되어 있는 Docker 이미지를 사용하면 대부분은 해결이 가능하다.
- .Net, Go 등 다양한 환경이 있는데 이런 환경을 쉽게 관리하는 것이 가능하다.
- Kafka, ElasticSearch 등에 대한 설치, 운영 경험 등이 없는데 Docker 이미지를 사용하면 어렵지 않게 구성할 수 있다.
즉, Linux 환경을 모르고 있었던 것이 Docker를 사용하게 된 결정적인 이유가 되었습니다. 이 선택으로 앞에서 선택한 Micro 서비스와 맞물려 아주 잘 돌아가는 인프라 환경을 구성할 수 있게 되었습니다.
Docker 구성도 한번에 끝난 것이 아니라 어려번 개선 작업을 통해 현재는 Kubernetes 기반으로 운영되고 있습니다. 이것도 시스템 개발하는 것도 비슷한 방법으로 진화시켜 나갔습니다. 한번 구성해보고 안되면 다시 재구성하고 하는 방식이었습니다. 처음부터 알고 시작하는 것이 아니었으니 처음 구성할 때에는 엉성하고 부족한 부분이 있었지만 점차 개선되면서 현재의 운영 구성까지 오게 되었습니다.
인프라 운영은 여전히 어려워
Docker가 많은 부분은 해결해 주었지만 그래도 여전히 인프라 운영은 어렵습니다. 장애가 발생했을 때 어디서 무엇때문에 발생했는지 찾기 어렵고 여기서 복잡한 마이크로 서비스들 간의 관계까지 추가 되면 더욱 어렵습니다. 기본 모니터링 및 알람 체계는 알리클라우드에서 제공하는 기능을 사용하고 있어 서버 장애, CPU 상황, 디스크 부족 등에 대한 상황은 모니터링이 되지만 Docker container 각각에 대한 모니터링은 여전히 어렵습니다. K8에서 기본 제공하는 기능과 Grafana 등을 이용해서 Container 자체에 대한 모니터링을 수행하고 있습니다.
그리고 Docker 기반으로 운영되다 보니 1년 이상 서비스 운영을 했음에도 불구하고 인프라 운영 인력들이 Linux 자체에 대한 이해나 명령어에 대해 익숙하지 않다는 것은 또 다른 문제입니다. 서비스가 성장하여 많은 사용자가 사용하게 되면 더 복잡하고 플기 어려운 문제가 나타날텐데 이를 위해서라도 Container 그 아래를 봐야 하는데 당장 문제가 발생하지 않으니 준비를 하지 않고 있는데 이 부분도 풀어야 할 숙제 중의 하나입니다.
글을 마치며
이제 9개월 남짓 지났고 만들어야 할 것은 여전히 많고 서비스의 정식 오픈을 한참 멀었습니다. 이제 구성원들도 자신들이 무엇을 만들고 있는지를 알고 무엇을 공부해야 하는지를 조금 알아가고 있는 것 같습니다.
- 첫발을 내딛는 순간 어딘가에는 해결책이 있다. 단지 첫발을 내딛는 것이 두려울 뿐 (인디아니존스, Lead of Faith, https://www.youtube.com/watch?v=JZzZERmk05o)
- 좋은 아키텍처, 남들이 하는 아키텍처, 책이나 인터넷에 나오는 아키텍처가 중요한 것이 아니라 우리 조직 구성원들이 현재 시점에서 가장 잘 할 수 있는 아키텍처가 가장 좋은 아키텍처이다.
- 그래도 좋은 아키텍처를 따라 가려는 방향성은 가지고 있어야 한다.
- 어떻게 만드는 것보다 무엇을 만들것인가가 백만배 천만배 더 중요하다.
- 개발자들 마음속에는 항상 "제대로 된 것을 만들고 싶은 욕구가..." ('장기하와 얼굴들' 탄생 비하인드 스토리, https://www.youtube.com/watch?v=HGCV9RdJSUg)
- 만들고 난 후에 뒷방으로 던져 놓는 것이 아니라 끊임없는 개선이 중요하다.
- 개발 완료는 이제 막 출발선에 서 있는 상태이다.
(혹시 글을 읽으시는 분들이 제가 북경의 한 개발 조직을 이렇게 좋은 방향으로 만들고 있다고 오해하실 것 같아 부연 설명 드립니다. 저는 이렇게 좋은 방향으로 바뀌어 가고 있는 중간에 합류하였습니다. 여기 글의 상황은 제가 합류하기 이전의 상황이고 여전히 진행 중인 상황입니다. 이 글은 그런 상황을 정리한 글입니다.)
다음 글은 개발 문화가 어떻게 바뀌어 가고 있고, 코드 리뷰를 어떻게 적용했는지에 대한 글입니다.