lecture Home > Professional Secrets

안재우(Lancers) 님의 .NET pub

   강좌 최초 작성일 : 2007년 01월 10일
   강좌 최종 수정일 : 2007년 01월 11일

   강좌 읽음 수 :

   작성자 : Laners(안 재)
   편집자 : Taeyo(김 태영)

   강좌 제목 : 웹 애플리케이션 이관/배포 가이드

강좌 전 태오의 잡담>

안재우님은 현재 닷넷엑스퍼트의 책임 컨설턴트로 근무하고 계시며, .NET 아키텍처 및 컨설팅과 관련한 일을 하고 있습니다. 워낙 유명한 분인지라 아시는 분들은 아실 것이라 생각하는데요. 이미 제 사이트에 Advice to beginner 코너를 진행하고 계시기도 합니다.

이번에는 .NET pub 이라는 공간을 만들어 안재우님의 여러가지 .NET 관련 이야기(아키텍처나 설계와 관련한)를 전달해 볼까 합니다.

참고로, 안재우님의 블로그는 http://blog.naver.com/saltynut 입니다



웹 애플리케이션은 애플리케이션 자체를 개발해나가는 것도 중요하지만, 이를 실제 서버에 어떻게 배포할 것이며, 그 배포 과정을 관리하는 것도 매우 중요합니다. 사이트의 업데이트가 상당히 잦거나, 여러 대의 웹 서버를 사용하는 웹 팜(Web Farm) 환경에서는 특히 이러한 배포 작업이 복잡해질 수 밖에 없습니다.

보통 개발 도중이나 소규모 사이트에서는 변경 내용을 실 서버에 바로 반영을 하기도 합니다. 그러나 충분한 테스트와 검증 과정을 거치지 않고 바로 실 환경에 적용을 할 경우, 여러 가지 문제가 발생할 소지가 많습니다. 급할수록 돌아가라는 말이 괜히 나온 게 아니겠죠? 규모가 작고 변경 내용이 크지 않아서 곧바로 문제를 추적할 수 있는 경우에는 상관없지만, 규모가 크고 변경 사항이 잦은 경우에는 일단 저질러 놓고 문제를 수정하는 것은 쉽지가 않습니다. 변경 사항을 추적하고 문제 발생 시 조치 요령이 체계적으로 수립되어 있어야 합니다.

이를 위해서는 개발 환경에서 변경된 내용을 실 서버에 곧바로 반영하는 형태는 지양되어야 합니다. 뻔한 내용이지만 충분한 테스트를 통해 검증이 된 후에만 실 서버에 반영해야 한다는 것입니다. 이러한 검증을 위해서 반드시 선행되어야 하는 조건들이 있는데 다음과 같습니다.

1. 반드시 별도의 테스트 인원을 운영하라.

테스트를 개발자에게만 맡겨서는 당연히 검증이 제대로 이루어질 리가 없습니다. Test-Driven Development가 분명히 좋은 개발방법이긴 합니다만, 개발자의 관점에서만 보게 되므로 개발자가 수행할 수 있는 테스트에는 한계가 있습니다.

테스터는 기능이나 요구사항이 구현이 목적이 아닌 품질 보증(QA : Quality Assurance)를 수행하는 직책입니다. 테스터는 상당히 중요한 직책이며, 단 1명이 되더라도 반드시 개발과는 별도의 인원으로 구성되어야 합니다. 사용자 관점에서 테스트를 수행해야 하지만, 단순히 클릭만 하는 것이 아니라 스스로 다양한 시나리오와 테스트 계획을 수립해서 가능한 한 많은 경우의 수를 뽑아내야 합니다.

2. 이관(Staging) 단계를 반드시 두도록 하라.

개발 환경에서 바로 실 서버로 변경 사항을 반영하는 것은 상당히 위험합니다. 개발 환경과 실 서버의 환경이 서로 상이할 수도 있고, 항상 개발 환경에서는 이상 없던 것이 실 서버 환경에서 발생하는 경우가 많습니다.

이를 위해서는 그 중간 단계인 이관(Staging) 단계를 반드시 둬야 합니다. 보통 이관 단계에서는 실 서버와 동일 혹은 거의 유사한 환경 하에 있는 스테이징 서버(Pre-Production 서버라고 부르기도 함)로 우선 변경 사항을 적용한 후, 스테이징 서버에서 충분한 검증이 이루어지고 나면 실 서버로 적용하게 됩니다.

많은 사람들은 개발/테스트 서버와 스테이징 서버를 혼동하곤 합니다. 개발/테스트 서버는 주로 개발 단계의 영역이지만, 스테이징 서버는 운영 단계에 속합니다.

3. 개발과 운영을 완전히 분리하라.

개발과 운영은 분명히 전혀 다른 영역입니다. 따라서 개발과 운영은 철저하게 격리되어서 나누어져야 합니다. 그럼에도 불구하고, 많은 웹 사이트들에서는 개발자가 실 서버에 접근할 권한을 가지고 있는 경우가 많습니다. 이렇게 되면 바쁘고 귀찮다는 이유로 이관 단계를 무시해버리고 바로 실 서버에 적용해버릴 가능성이 점점 더 커지게 됩니다.

개발 인원은 절대 실 서버에 접근할 수 있는 권한을 가지고 있어서는 안 됩니다. 실 서버는 운영 팀만의 영역이며, 반드시 정식으로 이관 단계를 통과한 변경사항만 받아들여져야 합니다. 이 점은 웹 서버뿐만 아니라 DB 서버의 경우에도 마찬가지입니다.

4. 운영에도 버전 관리가 필요하다.

개발 시에 소스 세이프와 같은 형상 관리 도구를 사용해서 백업 및 버전 관리를 수행하는 사람들이나 조직들은 많지만, 운영 상의 변경 사항 적용에 대한 버전 관리를 수행하는 사람들은 생각보다 많지 않습니다.

변경 사항을 적용했을 때 문제가 생겼다면, 다른 무엇보다 가장 먼저 해야 할 조치는 변경 사항을 적용하기 전으로 되돌려서 원상 복귀를 시켜놓는 것입니다. 문제를 찾아서 수정하는 것은 그 다음 해야 할 일입니다.

1~4번까지의 항목들을 지키는 회사와 지키지 않는 회사의 차이를 예를 들어 보도록 하겠습니다. 국내에서 몇 손가락 안에 든다는 회사들에서 실제로 일어나는 상황입니다.

A 사이트의 경우, 1~4번까지의 항목을 거의 철저하게 준수하고 있는 사이트입니다. 사소한 변경 사항 하나가 있을 때도 철저한 테스트를 거쳐서 적용되며, 테스트 및 이관 단계를 위한 장비들이 어지간한 사이트들의 실 서버 수보다도 많습니다. 테스트 전담 인원만도 개발 인력 수의 50% 이상입니다. 아무리 긴급한 일이라고 하더라도 개발 팀은 죽었다 깨도 실 서버에 접근할 수 없습니다. 또한 문제가 생겼을 때는 즉각적으로 복구할 수 있는 준비와 조치 프로세스가 갖추어져 있습니다.

이에 비해 C 사이트는 그 규모에 비해 믿어지지 않을 정도로 1~4번 항목들을 제대로 지키지 않는 사이트입니다. 쉽게 말해서 그렇게 하고 있으면서 어떻게 사이트가 굴러가고 있는지 신기할 따름입니다. 얼마 전 이 사이트 관계자로 들은 사건을 얘기해보면, 일정 기간 동안 잠시 이벤트를 하기 위해서 사이트를 수정했다고 합니다. 기획/마케팅 팀에서 쪼아대니 서둘러서 바로 실 서버에 적용을 해버렸다고 합니다. 그런데 문제는 이벤트 기간이 끝나고 나서 다시 원상 복귀를 시켜야 하는데, 적용 이전 상태를 백업을 하지 않았다는 것입니다. 결국 이전 상황으로 돌려놓기만 하면 되는데 다시 일일이 찾아서 원래대로 수정하는데 한참 동안 시간이 소요되었다고 하더군요. 사고를 친 개발자는 엄청난 문책을 받았고요.

그런데 이런 것은 그 개발자 개인의 잘못이 아닙니다. 그건 개발자의 잘못이 아니라 이관/배포에 대한 정책이 없는 회사 탓인 거죠. 이 사이트의 경우 단순히 이번 사건뿐만 아니라, 개발 팀과 운영 팀이 제대로 구분되어 있지 않으며 개발 팀이 실 서버에 직접 접근해서 수정해버리는 일이 허다합니다. 스테이징 단계도 존재하지 않으며, 버전 관리 및 백업 역시 없습니다. 앞으로도 이런 일이 또 일어날 가능성은 불을 보듯 뻔합니다.

그렇다면 바람직한 개발/테스트/이관/배포 프로세스는 어떻게 되어야 할까요? 먼저 이러한 프로세스를 약간 상위 레벨에서 보도록 하겠습니다.

  1. 개발 팀은 개발 간 소스세이프와 같은 형상 관리 도구 서버를 사용해서 소스의 백업, 버전 관리 등을 수행합니다.
  2. 정해진 주기에 따라 소스세이프 상의 최신 소스를 가져다 자동화된 빌드를 수행합니다. 예를 들어 매일 밤 12시에 Daily 빌드를 수행해도 되고, 명시적인 수작업에 의해 빌드가 되어도 됩니다. 중요한 것은 이 빌드는 개발자 개인 PC에서 수행되는 빌드가 아니라 별도의 공용 빌드 머신에서 수행되어야 한다는 것입니다.
  3. 새로운 빌드는 테스트를 위해 스테이징 서버로 옮겨지고, 테스트 팀에게 테스트를 의뢰하게 됩니다.
  4. 테스트 팀은 새로운 빌드가 있을 때마다 정해진 테스트 프로세스를 수행한 후, 문제점을 추적하고 테스트 결과를 제출합니다.
  5. 테스트가 통과되었거나 합당한 수준에 올라왔다면, 관리자는 실 서버로의 적용을 승인하게 됩니다.
  6. 운영 팀은 스테이징 서버의 내용을 실 서버에 복사하기 위해 배포 서버로 옮겨 놓습니다.
  7. 웹 팜으로 구성되어 있는 경우, 다운 타임을 최소화하기 위해 서버들을 각 서버 혹은 그룹 단위로 묶어서 일부를 L4에서 뺀 후 배포를 수행한 후 다시 복귀시키는 롤링 업그레이드를 실시합니다. 상황에 따라서는 명시적으로 서버 점검 중이라는 메시지를 둔 후 일괄 업그레이드를 하기도 합니다.
  8. 실 서버로의 적용이 완료됩니다. 이후 운영 팀은 운영 상황을 모니터링해서 문제 발생 시 보고합니다.

이 중 배포 프로세스를 좀 더 세부적으로 도식해보면 다음과 같습니다. 물론 어디까지나 이건 배포 프로세스의 한 가지 예라는 것을 감안하세요.

  1. 개발 팀은 최신 버전에 대한 빌드를 수행한 후 배포 서버의 Latest 폴더에 복사해 둔 후, 운영 팀에게 새로운 빌드가 나왔다는 것을 통지하게 됩니다.
  2. 운영 팀은 배포를 수행하기 위해 배포 버전 번호를 만들게 됩니다. GUID를 사용하든 뭘 써도 상관 없긴 합니다만, 보통 일자와 일련 번호의 조합이 될 것입니다(예 : 2007011001)
  3. 배포 번호 이름으로 된 폴더를 만들고 Latest 폴더의 내용을 백업해 둡니다. 백업이라기 보다는 보관(Archieve)라는 용어가 더 맞을 것 같기도 하네요.
  4. 이제 실제로 웹 서버에 배포를 수행합니다.
  5. 모든 웹 서버에 배포가 완료되었다면, 배포가 끝난 것입니다. 하지만 배포 도중에 문제가 생기거나 배포 후 문제가 생기는 경우에는 이전 버전으로 롤백을 수행합니다.

이로써 정책 상의 선행 조건, 상위 레벨의 개발/이관/배포 프로세스, 상세 배포 프로세스에 대해서 어느 정도 알아본 셈입니다. 사실 첫 번째와 두 번째 요소는 정책적인 문제이므로 어떻게 되든 결정을 하고 거기에 따르면 됩니다. 그런데 세 번째 요소인 상세 배포 프로세스에는 몇 가지 생각해봐야 할 점들이 존재합니다.

첫째, 배포 번호를 부여하고 보관하는 과정을 자동화할 수 있는 방법은 없는가라는 것입니다. 이처럼 반복적인 작업은 자동화는 것이 바람직하겠죠.

둘째, 웹 서버가 몇 대 되지 않는다면 상관없지만, 다수의 웹 서버를 보유한 웹 팜 환경 등에서 실제 복사 및 동기화하는 과정을 간편하게 할 방법은 없을까라는 것입니다. 대형 사이트들의 경우에는 미러링 장비를 사용하거나 통합 스토리지를 활용하기도 하고, Microsoft의 Application Center와 같은 솔루션을 사용하기도 합니다. 하지만 이런 것이 없다면 단순히 일일이 수동으로 네트워크 복사를 하거나 Robocopy 등을 사용하는 것이 유일한 방법이었습니다.

셋째, 문제가 생겼을 경우 보관된 이전 버전으로 롤백하는 것이 필요하겠죠? 롤백 작업 역시 수동으로 하는 것보다는 뭔가 자동화된 과정을 통해 지원되었으면 하는 생각이 들게 됩니다.

결국 배포 프로세스를 지원하는 도구가 필요한 셈입니다. 위에서 얘기한 생각해봐야 할 점들은 이러한 배포 도구가 가져야 하는 기본적인 기능들이 됩니다. 대략적으로 배포 도구가 가져야 하는 기능들을 정리해보면, 다음 정도가 될 듯 합니다.

  • 자동 배포 버전 부여 기능
  • 배포 버전에 따른 보관(Archieve) 기능
  • n 개의 웹 서버에 대한 복사 및 동기화를 지원
  • 배포 상태 모니터링 기능
  • 유사시 보관된 버전으로 롤백시킬 수 있는 기능
  • 이미 이러한 기능들을 하드웨어나 솔루션을 가지고 있다면 그래도 참 좋은 회사에 다니고 계신 겁니다. 그래서 그렇지 못한 분들(저희 회사도 포함됩니다 -_-)을 위해서 다음 번에는 이러한 기능을 지원할 수 있도록 다음과 같이 간단한 배포 도구를 만들어 보도록 하겠습니다. 밑바닥부터 만드는 것은 아니고, 실제 복사 및 동기화에 대한 기능은 Robocopy라는 훌륭한 도구를 활용할 것입니다. 뭐, Robocopy를 써 보신 분들은 대충 어떻게 만들면 될 것 같다는 상상이 드시죠? ^^

     

    강좌 목록으로..