소프트웨어 인도의 어려움

지난 1년간 대법원의 각 시스템에 대한 유지보수 프로세스를 관리하는 ‘통합운영관리시스템’을 개발하는 프로젝트에 참여하게 되었다. 우리회사의 Vizend 제품을 이용하여 대법원의 유지보수 프로세스를 지원하도록 커스터마이징하는 업무를 진행하였는데 어려움 중 하나는 바로 소프트웨어의 지속적인 인도를 할 수 있도록 지원하는 것이었다.

일반적인 프로젝트에서라면 폭포수와 같은 개발방법론을 통해 대부분 한 차례만 소프트웨어를 인도하고, 그 후 유지보수 프로세스에 의해서 변경절차를 거치지만 이번 프로젝트의 경우 아래와 같은 사항을 고려했다.

  1. 지속적인 출시
  2. 짧은 출시기간
  3. 빠른 배포시간
  4. 쉬운 백업,복구

대법원의 시스템은 크게 사법, 등기, 가족관계로 나누어지고, 각 부문별로 100여개 이상의 개별 시스템이 존재하는 상황이었기 때문에 단계적으로 출시(release)가 이루어져야 했다. 또한 단계적 적용에 따른 기간은 시험적용 1달, 안정화 1달로 2달 간격으로 출시해야 했다. 단계적 적용기간 중에도 사용 중 나온 결함 또는 피드백을 바탕으로 최소 주 1회 이상의 출시가 발생하고, 긴급사항일 경우 언제든 수정하여 반영할 수 있는 환경을 마련해야 했다.

배포 시점은 출근 전, 점심시간, 퇴근 이후 등 다양했고, 긴급사항일 경우 업무 중간에도 배포할 수 있어야 했기 때문에 빠르게 배포할 수 있어야 했으며, 이를 위해서는 배포 자동화 환경이 필요했다. 그리고 잦은 출시 작업으로 인하여 예기치못한 문제가 발생했을 경우를 위해 백업 데이터를 바탕으로 신속히 이전 버전으로 신속히 복구를 할 수 있어야 했다.

지금까지 해왔던 지속적인 통합(Continuous Integration) 개념만으로는 해결이 힘들기 때문에 지속적인 인도(Continuous Delivery) 개념을 도입해야 했고, 이를 위한 환경 및 절차를 마련해야 했다.

지속적인 인도

지속적인 인도 개념을 잘 이해하기 위해서 지속적인 배포, 배포 파이프라인, 지속적인 인도에 대한 것을 함께 알아보자.

지속적인 통합(Continuous Integration)이란 팀의 구성원들이 자신들의 작업을 각자 하루에 적어도 한 번씩 통합하는 소프트웨어 개발 프랙티스를 의미한다. 반복가능하고 오류가 발생하기 쉬운 프로세스를 자동화하여 소프트웨어 통합을 별 것 아닌 일로 만들고자 하는 것이 목적이며, 이를 위해서는 빌드 프로세스 및 테스트 자동화 환경을 만드는 것이다. 일반적인 지속적인 통합 환경은 아래와 같다.

[그림1. 지속적인 통합]

배포 파이프라인(Deployment Pipeline)이란 추상화 단계로 볼 때 소프트웨어를 버전 관리 시스템으로부터 사용자에게 전달하는 프로세스의 자동화된 모습을 의미한다. 단대단(end-to-end) 자동화를 빌드, 배포, 테스트, 출시 프로세스에 적용하면 고품질의 복잡한 시스템을 지금까지의 경험에 비해 비용과 위험도를 확연히 낮춰 생산, 테스트, 배포를 할 수 있는데 이것이 바로 배포 파이프라인의 목적이다.
배포 파이프라인에서의 변경의 이동을 시퀀스 다이어그램으로 가시화하면 아래와 같다.

[그림2. 배포 파이프라인 시퀀스 다이어그램]

아래 그림은 전형적인 배포 파이프라인으로 필수 접근 방법을 담고 있다. 물론 실제 파이프라인은 프로젝트의 실제 소프트웨어 전달 프로세스를 반영한다.

[그림3. 기본적인 배포 파이프라인]

지속적인 인도(Continuous Delivery)란 소프트웨어가 언제든지 릴리즈될 수 있는 방식으로 소프트웨어를 구축하는 소프트웨어 개발 분야를 의미한다. 애자인 선언의 첫 번째 원칙인 ‘최상위의 목적은 빠르고 지속적으로 가치 있는 소프트웨어를 인도함으로써 고객을 만족시키는 것이다.’라는 개념을 이루는 것이 목적이며, 이를 위해서는 기본적으로 지속적인 통합 및 배포 파이프라인를 구축해야 한다.

적용사례

지속적인 인도 개념을 프로젝트에 도입하기 위해서는 해당 프로젝트의 개발 및 운영 환경을 구축하고, 지속적인 통합 환경과 배포 파이프라인을 적용할 수 있는 배포 절차를 마련하는 것이 중요하다.

통합운영관리시스템은 자바 기반의 웹 애플리케이션이며, 대법원에서 지원가능한 범위 내에서 개발 및 운영환경을 구성했다. 프로젝트팀에게 지원가능한 범위는 운영환경으로 사용할 서버 1대와 운영환경과 거의 같은 통합테스트용 서버 1대를 지원받았다. 통합테스트용 서버의 경우 하드웨어 자원이 굉장히 열악한 환경이었기 때문에 지속적인 통합 환경을 구축하기에는 무리가 있어서, 회사의 지원을 받아 별도의 데스크탑으로 개발서버를 구축하였다.

[그림4. 개발환경 요약]

지속적인 통합 환경을 구축하기 위해서 형상관리로는 SVN, 빌드 및 컴포넌트 라이브러리 관리를 위해 메이븐(Maven)을 사용하였다. 또한 CI도구로 젠킨스(Jenkins)를 사용하였으며, 테스트 프레임워크로 JUnit, EasyMock, DBUnit 등을 사용하였다. 마지막으로 품질분석도구인 SonarQube를 통해서 정적 분석을 하고, 컴포넌트 크기를 가시적으로 확인해 특정 컴포넌트가 급격히 커지는 것을 방지하였다.

[그림5. 품질분석도구 SonarQube]

지속적인 통합 환경을 갖추었기 때문에 빌드 및 테스트 자동화 환경이 갖추어졌다. 하지만 웹 애플리케이션을 실제 서버에 배포하는 작업을 위해서는 배포 파이프라인을 구축해야 한다. 이를 위해서 CI도구인 젠킨스와 쉘 스크립트 등을 사용하여 완벽하지는 않지만 배포 자동화를 구축하였다. 배포 자동화를 위해서는 아래와 같은 사항을 고려하였다.

  1. 버튼 한번으로 war를 해당 서버에 전송해야 함.
  2. 콘솔 명령이 아닌 버튼 한번으로 서버를 재시작할 수 있어야 함.
  3. DB 스키마 또는 데이터 변경을 위해서 배포절차를 수동으로 변경할 수 있어야 함.
  4. 백업/복구가 자동으로 되어야 함.

개발서버와 통합테스트/운영서버는 서로 다른 전략을 사용하였다. 개발서버의 경우 DB 스키마 및 데이터를 개발 중 계속 바뀌었으며, 배포 시에는 DB 변경사항을 고려하지 않아도 되었다. 또한 CI서버와 개발서버가 물리적으로 동일한 서버에 존재하여 CI서버에서 개발서버에 대한 조작이 쉬웠고, 백업/복구 작업은 필요하지 않았다.
통합테스트/운영서버의 경우 DB 변경사항을 적용하기 위해서는 콘솔 명령을 통한 SQL 실행권한이 없어 수작업으로 DB 변경사항을 적용하였다. CI서버와 통합테스트/운영서버는 물리적으로 서로 다른 서버에 존재하여 원격접속을 해야하는데 ssh가 아닌 telnet만 허용되었기 때문에 원격으로 콘솔명령을 통한 단계적 쉘 스크립트 실행은 실패할 가능성이 높아 수작업으로 진행하였다. 절차를 표현하면 아래와 같다.

[그림6. 개발서버 배포 절차]
[그림7. 통합테스트/운영서버 배포 절차]

CI를 통한 자동화가 어려운 단계는 쉘 스크립트를 통한 반 자동화를 진행하였다. 서버를 재시작하고, 배포된 애플리케이션을 백업/복구하는 것, 그리고 ‘통합운영관리시스템’을 통해 유지보수가 이루어지는 100여개가 넘는 시스템의 SVN 레파지토리에 대한 생성 및 계정관리에 대한 것까지 쉘 스크립트를 통하여 관리하였다.

DB 백업의 경우 dump 권한도 없었기 떄문에 개발서버에 있는 오라클에 백업용 DB 스키마를 생성한 후 DB Link를 통한 select insert 작업으로 백업을 하였다. 수행절차는 다음과 같다.

  1. 백업용 DB와 운영 DB의 모든 테이블 및 컬럼 속성 비교 후 동기화
  2. 배업용 DB의 외래키 비활성화
    - 데이터 발생 순서에 관계없이 복사하기 위함
  3. DB Link를 통하여 운영 DB에서 백업용 DB로 데이터 복사
  4. 백업용 DB와 운영 DB의 테이블별 데이터 수 비교
  5. 백업용 DB의 외래키 활성화

단순히 배포가 끝나고 서버가 정상적으로 시작되었다고 해서 애플리케이션이 정상적으로 동작한다고 보장할 수 없다. 운영서버의 경우 데이터를 임의로 발생시킬 수 없기 때문에 로그인을 한 후 특정 메뉴를 수작업으로 확인하여 대략적인 정상 여부를 판단하기도 한다. 매번 수작업으로 진행하게 되면 모든 메뉴를 확인할 수 없는데다가 시간이 많이 걸린다. 따라서 모든 메뉴에 대한 조회를 자동화하기 위해 soapUI를 사용하였다. 모든 메뉴를 soapUI에 등록하고, 관리자로 로그인 하는 행위를 가장 처음에 실행시키면 관리자로 로그인하여 모든 메뉴에 대한 조회작업을 자동화 할 수 있다. 이를 통해 운영서버에 배포 이후 최소한의 정상 동작 여부를 판단하는 근거로 사용하였다.

[그림8. soapUI를 통한 메뉴점검 테스트]

고민사항

프로젝트에서 제한된 시간 내에 배포 파이프라인을 비롯한 지속적인 인도 개념을 적용하는 데는 많은 어려움이 따른다. 그럼에도 불구하고 아쉬움이 남고, 좀 더 고민해야 할 내용이 존재한다.

  1. 프로젝트와 운영에서의 일관성 있는 배포 파이프라인 구축 방안
    - 형상관리구조와 소프트웨어 버전관리 정책
    - 산출물에 대한 관리
    - 출시 체크리스트
  2. 배포 파이프라인과 프로젝트/유지보수 프로세스의 연결
  3. 배포 파이프라인에 따른 적절한 도구 선택 가이드
  4. 개발 및 운영환경에 대한 R&R이 문제가 될 경우 대안책
  5. 개발환경에 따른 배포 파이프라인 전략
    - 이중화 또는 클러스터링 환경에서의 배포 전략
    - 서로 다른 시스템의 동시 배포 전략

결론

Continuous Delivery 서적에는 다음과 같이 말하고 있다.

소프트웨어를 고객에게 인도하지 못하면 고객은 수익을 창출하지 못한다. 대부분의 조직이 소프트웨어를 실환경에 출시하는 작업을 주로 수동으로, 에러가 발생하기 쉬운 위험한 프로세스로 처리하고 있다. 따라서 소프트웨어를 개발자로부터 실제환경으로 인도하는 배포 과정을 신뢰할 수 있고, 예측 가능하며, 가시화된 그리고 잘 이해된 대규모 자동화 프로세스로 위험을 정량화할 수 있게 만드는 것이 중요하다.

어려운 환경 속이라도 Continuous Delivery에 대한 것을 고민하고 계속적으로 발전시켜 실제 프로젝트 환경에 적용하려는 노력이 중요하다. 누군가는 해야할 일이다.

참고자료