바로 이동

클라우드 기반으로 재설계

DevOps Research and Assessment(DORA)팀의 연구에 따르면 일류 DevOps팀은 하루에도 수 차례 배포하고 1일 이내에 다수의 변경사항을 프로덕션으로 릴리스하지만 변경 실패율이 0~15% 밖에 되지 않습니다.

이 백서에서는 팀 규모가 커지더라도 새로운 기능을 빠르게 제공하고 소프트웨어 품질을 개선하며 안정성 및 가용성 수준을 높일 수 있는 클라우드 기반 패러다임으로 애플리케이션을 재설계하는 방법에 대해 설명합니다.

클라우드 기반 아키텍처로 이전해야 하는 이유

많은 기업이 모놀리식 아키텍처를 사용해 커스텀 소프트웨어 서비스를 빌드하고 있습니다. 이러한 접근 방식에는 모놀리식 시스템의 설계 및 배포가 비교적 간단하다는 이점이 있지만 그 효과는 초기에 국한될 뿐입니다. 애플리케이션이 점점 더 복잡해지면 개발자 생산성과 배포 속도를 유지하기가 어려워지고 변경에 많은 비용과 시간이 들며, 배포 위험이 큰 시스템이 될 수 있습니다.

서비스와 담당 팀이 성장하다 보면 점점 복잡해지고 발전과 운영이 어려워지는 경향이 있습니다. 테스트 및 배포, 새로운 기능 추가, 안정성 및 가용성 유지가 더욱 힘들어질 수 있습니다.

Google의 DORA 팀에서 실시한 연구에 따르면 규모와 영역을 불문하고 모든 조직에서 높은 수준의 소프트웨어 배포 처리량과 서비스 안정성 및 가용성을 달성할 수 있습니다. 우수한 성과를 내는 팀은 하루에도 여러 번 배포할 수 있고, 하루 중에 다수의 변경사항을 프로덕션에 적용하고, 1시간도 안 되어 서비스를 복원하지만 변경 실패율이 0~15%에 불과합니다1.

또한 실적이 우수한 팀에서는 팀 규모가 커져도 높은 수준의 개발자 생산성을 달성할 수 있습니다. 이는 개발자당 일일 배포 수로 측정한 결과입니다. 이 내용은 그림 1에 나와 있습니다.

이 백서의 나머지 부분에서는 애플리케이션을 현대적인 클라우드 기반 패러다임으로 마이그레이션하여 이러한 결과를 얻는 방법을 설명합니다. 이 백서에 설명된 기술 관행을 구현해 달성할 수 있는 목표는 다음과 같습니다.

  • 개발자 생산성 향상: 팀 규모가 커지더라도 생산성을 높일 수 있습니다.
  • TTM(time to market) 단축: 새로운 기능 추가 및 결함 수정이 보다 신속하게 이루어집니다.
  • 가용성 향상: 소프트웨어 업타임을 높이고 배포 실패율을 낮추며 이슈 발생 시 복원 시간을 단축합니다.
  • 보안 강화: 애플리케이션에서 공격에 취약한 부분을 줄이고 공격 및 새롭게 발견된 취약점을 보다 쉽게 감지하고 재빠르게 대응할 수 있도록 합니다.
  • 확장성 향상: 클라우드 기반 플랫폼 및 애플리케이션으로 필요에 따라 손쉽게 수평 확장 또는 축소가 가능합니다.
  • 비용 절감: 능률적인 소프트웨어 배포 프로세스로 새로운 기능을 제공하는 데 드는 비용이 절감되고 효과적인 클라우드 플랫폼 사용으로 서비스 운영 비용 역시 크게 절감됩니다.

1 https://cloud.google.com/devops/에서 이 4가지 주요 측정항목을 기준으로 팀 실적을 확인해 보세요.

X축과 그 이상으로 구성된 개발자 수에 따라 개발자 생산성을 확장하는 능력에 따라 소프트웨어 배포가 어떻게 이루어지는지 보여주는 그래프
그림 1: 팀의 소프트웨어 배포 실적이 개발자 생산성 확대 능력에 미치는 영향(출처: 2015년 State of DevOps Report)

클라우드 기반 아키텍처 소개

모놀리식 애플리케이션은 단일 단위로 빌드, 테스트, 배포해야 합니다. 애플리케이션의 운영체제, 미들웨어, 언어 스택이 애플리케이션마다 맞춤설정되거나 커스텀 구성되는 경우가 많습니다. 또한 일반적으로 빌드, 테스트, 배포 스크립트 및 프로세스가 애플리케이션마다 고유합니다. 새로운 애플리케이션에서는 단순하고 효과적인 방법이지만 애플리케이션이 성장하면 시스템을 변경, 테스트, 배포, 운영하기가 어려워집니다.

또한 시스템이 성장함에 따라 서비스를 빌드, 테스트, 배포, 운영하는 팀의 규모와 복잡성도 커집니다. 일반적인 접근 방식은 기능별로 팀을 나누는 것이지만 리드 타임과 배치 크기가 커지고 상당량의 재작업으로 이어지는 팀 간 핸드오프를 유도한다는 결점이 있습니다. DORA 연구에 따르면 실적이 우수한 팀은 소프트웨어를 개발하고 배포할 때 단일 교차 기능팀으로 진행할 가능성이 2배 더 높습니다.

이 문제에는 다음과 같은 증상이 포함됩니다

  • 빌드 프로세스가 길고 손상되는 경우가 많음
  • 통합 및 테스트 주기가 빈번하지 않음
  • 빌드 및 테스트 프로세스를 지원하는 데 필요한 작업이 늘어남
  • 개발자 생산성 저하
  • 예정된 다운타임이 필요해 근무 시간 외에 수행해야 하는 힘든 배포 프로세스
  • 테스트 및 프로덕션 환경 구성을 관리하는 데 많은 작업이 필요함

클라우드 기반 패러다임에서는 다릅니다.³

  • 복잡한 시스템은 컨테이너화된 런타임에 독립적으로 테스트 및 배포할 수 있는 서비스로 분할됩니다(마이크로서비스 또는 서비스 지향 아키텍처).
  • 애플리케이션에서 데이터베이스 관리 시스템(DBMS), blob 스토리지, 메시징, CDN, SSL 종료 등 표준 플랫폼에서 제공하는 서비스를 사용합니다.
  • 표준화된 클라우드 플랫폼에서 배포, 자동 확장, 구성, 보안 비밀 관리, 모니터링, 알림과 같은 여러 운영 문제를 해결해 줍니다. 애플리케이션 개발팀에서 필요에 따라 이러한 서비스에 액세스할 수 있습니다.
  • 애플리케이션 개발자에게 표준화된 운영체제, 미들웨어, 언어별 스택이 제공되며 이러한 스택의 유지보수 및 패치를 플랫폼 제공업체 또는 별도의 팀이 대역 외에서 처리합니다.
  • 단일 교차 기능 팀이 각 서비스의 전체 소프트웨어 배포 수명 주기를 담당할 수 있습니다.

3 '클라우드 기반'의 의미에 대한 완전한 설명은 아닙니다. 클라우드 기반 아키텍처 원칙에 대한 논의를 참고하려면 https://cloud.google.com/blog/products/ application-development/5-principles-for-cloud-native-architecture-what-it-is-and-how-to-master-it 페이지를 방문하세요.

이 패러다임은 여러 이점을 제공합니ca다

빠른 배포 안정적인 출시 비용 절감
서비스가 작고 느슨하게 결합되어 해당 서비스와 관련된 팀이 자율적으로 작업할 수 있습니다. 덕분에 개발자 생산성과 개발 속도가 향상됩니다. 개발자가 프로덕션과 유사한 테스트 환경에서 신규 및 기존 서비스를 빠르게 빌드, 테스트, 배포할 수 있습니다. 배포부터 프로덕션까지의 활동이 단순하고 원자적입니다. 덕분에 소프트웨어 배포 프로세스 속도가 크게 향상되고 배포 위험이 줄어듭니다. 플랫폼에서 공유 표준 서비스를 제공하고, 공유되는 물리 인프라에서 애플리케이션이 실행되어 테스트 및 프로덕션 환경의 비용과 복잡성이 크게 절감되었습니다.

보안 강화 높은 가용성 규정 준수 간소화 및 비용 절감

이제 공급업체에서 DBMS 및 메시징 인프라 등의 공유 서비스를 최신 상태로 유지하고 패치를 적용하며 규정 준수를 책임집니다. 또한 표준화된 방식으로 애플리케이션을 배포하고 관리하므로 애플리케이션에 패치를 적용하고 최신 상태로 유지하기가 훨씬 쉬워집니다.

운영 환경의 복잡성 감소, 구성 변경의 용이성, 플랫폼 수준의 자동 확장 및 자동 복구 처리 기능으로 인해 애플리케이션의 가용성과 안정성이 향상되었습니다. 대부분의 정보 보안 제어를 플랫폼 레이어에서 구현할 수 있어 훨씬 저렴하고 쉽게 규정 준수를 구현하고 입증할 수 있습니다. 많은 클라우드 제공업체가 SOC2 및 FedRAMP 등의 위험 관리 프레임워크로 규정 준수를 유지하고 있습니다. 이 프레임워크를 기반으로 배포된 애플리케이션의 경우 플랫폼 레이어에서 구현되지 않은 나머지 제어에 대한 규정 준수만 입증하면 됩니다.

  

하지만 클라우드 기반 모델에는 몇 가지 절충점이 있습니다.

  • 요즘은 모든 애플리케이션이 분산 시스템이므로 운영 과정에서 많은 수의 원격 호출이 발생합니다. 따라서 네트워크 장애 및 성능 문제를 처리하는 방법과 프로덕션에서 문제를 디버깅하는 방법을 신중하게 생각해야 합니다.
  • 개발자가 플랫폼에서 제공하는 표준화된 운영체제, 미들웨어, 애플리케이션 스택을 사용해야 합니다. 이 때문에 로컬 개발이 어려워집니다.
  • 설계자가 시스템 설계에 eventual consistency 수용 등의 이벤트 기반 접근 방식을 채택해야 합니다.

클라우드 기반으로 마이그레이션

서비스를 클라우드로 이전할 때 '리프트 앤 시프트' 접근 방식을 채택하는 조직이 많습니다. 이 접근 방식에서는 시스템을 약간만 변경하면 되지만 기존 데이터 센터에 비해 우수한 API, 서비스, 관리 도구를 제공함에도 불구하고 클라우드가 기본적으로 기존 데이터 센터처럼 취급됩니다. 리프트 앤 시프트는 위에서 설명한 클라우드 기반 패러다임의 이점을 하나도 제공하지 않습니다.

많은 조직이 애플리케이션을 클라우드 기반 아키텍처로 이전하는 비용과 복잡성 때문에 리프트 앤 시프트 방식에 머물러 있습니다. 따라서 애플리케이션 아키텍처에서 프로덕션 운영, 전체 소프트웨어 배포 수명 주기에 이르는 모든 것을 재고해야 합니다. 많은 대기업이 다년간의 '빅뱅' 플랫폼 변경 작업에 실패한 만큼 이는 합리적인 우려입니다.

시스템을 클라우드 기반으로 재설계하여 팀이 새로운 패러다임에서 효과적으로 작업하는 방법을 학습하는 동시에 새로운 기능을 계속 배포할 수 있도록 지원하는 점진적, 반복적, 진화적 접근 방식으로 이러한 우려를 해결할 수 있습니다. 이 접근 방식을 '이전 및 개선'이라고 부릅니다.

혁신적인 아키텍처의 주요 패턴은strangler fig 애플리케이션으로 알려져 있습니다.4 시스템을 처음부터 완전히 다시 작성하는 대신 현대적인 클라우드 기반 방식으로 새로운 기능을 작성하되 기존 기능을 위해 원래의 모놀리식 애플리케이션과 통신하도록 만듭니다. 그림 2와 같이 새 서비스의 개념적 무결성을 위해 시간이 지나면서 필요에 따라 점진적으로 기존 기능을 전환합니다.

4 https://martinfowler.com/bliki/StranglerFigApplication.html 페이지에 설명되어 있습니다.

스트랭글러 피그(strangler fig) 애플리케이션을 보여주는 다이어그램 최상위 수준의 고객과 디스패처를 나타내는 회색 정사각형이 모놀리식 애플리케이션과 새로운 모듈을 나타내는 파란색 정사각형으로 이어지고 둘 다 녹색 컨테이너로 이어집니다.
그림 2: 스트랭글러 피그(strangler fig) 패턴을 사용해 모놀리식 애플리케이션을 점진적으로 재설계

성공적인 재설계를 위한 중요한 가이드라인에는 3가지가 있습니다.

첫 번째, 기존 기능을 재현하지 말고 새 기능을 먼저 빠르게 배포하세요. 새 서비스를 사용하여 새로운 기능을 얼마나 빨리 제공할 수 있느냐가 주요 측정항목인 만큼 이 패러다임 내에서 실제로 작업하며 습득한 권장사항을 신속하게 학습하고 전달할 수 있습니다. 실제 사용자에게 몇 개월이 아닌 몇 주 내로 결과물을 배포한다는 목표를 갖고 범위를 적극적으로 축소하세요.

두 번째, 클라우드 기반을 고려해 설계하세요. DBMS, 메시징, CDN, 네트워킹, blob 스토리지 등에 클라우드 플랫폼의 기본 서비스를 사용하고 가능한 경우 플랫폼에서 제공하는 표준화된 애플리케이션 스택을 사용해야 합니다. 서비스를 컨테이너화하여 최대한 서버리스 패러다임을 활용하고 빌드, 테스트, 배포 프로세스를 완전 자동화해야 합니다. 모든 애플리케이션이 로깅, 모니터링, 알림에 플랫폼에서 제공하는 공유 서비스를 사용해야 합니다. (이러한 종류의 플랫폼 아키텍처는 베어메탈 온프레미스 환경을 비롯한 모든 멀티 테넌트 애플리케이션 플랫폼에 배포하면 유용할 수 있습니다.) 아래의 그림 3에는 클라우드 기반 플랫폼에 대한 대략적인 그림이 나와 있습니다.

클라우드 기반 플랫폼에 대한 대략적인 그림
그림 3: 클라우드 플랫폼의 대략적인 구성

마지막으로 자체 서비스를 테스트하고 배포할 수 있는 자율적이고 느슨하게 결합된 팀을 고려해 설계하세요. Google의 연구에 따르면 아키텍처로 달성해야 할 가장 중요한 결과는 다음 6가지에 대한 소프트웨어 배포 팀의 긍정적인 답을 얻는 것입니다.

  • 팀 외부인의 허가 없이 시스템 설계를 대대적으로 변경할 수 있습니다.
  • 다른 팀의 시스템을 변경하거나 다른 팀에 상당량의 작업을 할당하는 데 있어 해당 팀에 의존하지 않고도 시스템 설계를 대규모로 변경할 수 있습니다.
  • 팀 외부인과의 소통 및 조정 없이도 작업을 완료할 수 있습니다.
  • 제품 또는 서비스에서 사용하는 다른 서비스에 관계없이 제품이나 서비스를 온디맨드로 구현하고 출시할 수 있습니다.
  • 통합 테스트 환경 없이도 대부분의 테스트를 온디맨드로 수행할 수 있습니다.
  • 다운타임이 거의 없이 정상적인 업무시간 중에 배포할 수 있습니다.

팀에서 이러한 부분을 목표로 삼고 있는지 정기적으로 확인하고 목표 달성에 우선순위를 두세요. 그렇게 하려면 보통 조직적 아키텍처와 기업 아키텍처 모두를 재구성해야 하는 경우가 많습니다.

특히 제품 관리자를 포함해 소프트웨어를 빌드, 테스트, 배포하는 데 필요한 여러 모든 역할이 협력하도록 팀을 조직하고 최신 제품 관리 관행을 적용하여 작업 중인 서비스를 배포하고 발전시키도록 해야 합니다. 조직 구조를 바꿀 필요는 없습니다. 개발자, 테스터, 출시팀을 독립적으로 운영하는 대신 매일 한 팀으로서 협력하면 (가능한 경우 물리적 공간을 공유) 생산성이 크게 향상될 수 있습니다.

연구에 따르면 팀들이 이러한 내용에 얼마나 동의하느냐에 따라 소프트웨어 실적, 즉 안정적인 가용성이 높은 서비스를 하루에 여러 차례 배포할 수 있는지를 예측할 수 있습니다. 이를 통해 실적이 우수한 팀에서는 팀 규모가 커져도 개발자 생산성을 높일 수 있습니다(일일 개발자별 배포 수 측면에서 측정).

원칙 및 관행

마이크로서비스 아키텍처 원칙 및 관행

마이크로서비스 또는 서비스 지향 아키텍처를 채택할 때 따라야 할 몇 가지 중요한 원칙과 관행이 있습니다. 나중에 개조하려면 비용이 많이 들기 때문에 처음부터 이를 철저히 따르는 것이 좋습니다.

  • 모든 서비스에는 자체 데이터베이스 스키마가 있어야 합니다. 관계형 데이터베이스, NoSQL 솔루션 등 무엇을 사용하든 각 서비스에는 다른 서비스에서 액세스하지 않는 고유한 스키마가 있어야 합니다. 여러 서비스에서 동일한 스키마와 통신할 경우 시간이 지나면서 데이터베이스 레이어에서 서비스가 긴밀히 결합하게 됩니다. 이렇게 종속 항목이 생기면 서비스의 독립적인 테스트 및 배포를 막아 변경이 어렵고 배포 위험도 커집니다.
  • 서비스가 네트워크에서 공개 API를 통해서만 통신해야 합니다. 모든 서비스가 공개 API로 동작을 노출해야 하며 서비스가 이 API로만 상호 통신해야 합니다. '백도어' 액세스나 다른 서비스의 데이터베이스에 직접 통신하는 서비스가 있어서는 안 됩니다. 공개 API를 사용해야 서비스가 긴밀히 결합되지 않도록 할 수 있으며 서비스 간 통신에 문서화가 잘 되어 있고 지원되는 API가 사용됩니다.
  • 서비스에서 클라이언트의 하위 호환성을 책임집니다. 서비스를 빌드하고 운영하는 팀에는 서비스 업데이트로 인해 소비자와의 관계가 끊어지지 않도록 할 책임이 있습니다. 새 버전을 출시해도 기존 고객과의 관계가 끊어지지 않도록 하위 호환성을 고려해 API 버전 관리 및 테스트를 계획해야 한다는 뜻입니다. 팀에서는 카나리아 릴리스를 사용해 이를 검증할 수 있습니다. 블루-그린 배포 또는 단계적 출시 등의 기술을 사용해 배포로 인한 다운타임을 없애야 한다는 의미이기도 합니다.
  • 개발 워크스테이션에서 서비스를 실행하는 표준화된 방식을 만드세요. 개발자는 단일 명령어를 사용해 개발 워크스테이션에서 온디맨드로 프로덕션 서비스의 하위 집합을 구현할 수 있어야 합니다. 스텁 버전의 서비스를 온디맨드로 실행할 수도 있어야 합니다. 많은 클라우드 제공업체에서 지원하는 에뮬레이션된 버전의 클라우드 서비스를 사용하도록 하세요. 목표는 개발자가 로컬에서 서비스를 쉽게 테스트하고 디버깅할 수 있도록 하는 것입니다.
  • 프로덕션 모니터링 및 관측 가능성에 투자하세요. 성능 문제를 비롯한 프로덕션의 많은 문제가 기존에 없던 새로운 문제이며 여러 서비스 간 상호작용으로 인해 발생합니다. Google의 연구에 따르면 시스템의 전반적인 상태(예: 시스템이 작동 중인지, 시스템에서 사용 가능한 리소스가 충분한지)를 보고하고 팀이 서비스 간 상호작용을 비롯한 프로덕션 환경의 인프라 문제를 추적, 이해, 진단하는 데 도움이 되는 도구와 데이터를 이용할 수 있는 솔루션을 마련하는 것이 중요합니다.
  • 서비스의 서비스 수준 목표(SLO)를 정하고 정기적으로 재해 복구 테스트를 수행하세요. 서비스의 SLO를 정하면 서비스 수행에 대한 기대치가 설정되고 서비스가 중단될 경우의 시스템 동작을 계획하는 데 도움이 됩니다(예: 복원력이 우수한 분산 시스템 빌드 시 고려해야 할 주요 사항). 재해 복구 테스트 계획의 일부로 제어된 결함 주입과 같은 기술을 사용해 프로덕션 시스템이 실제로 어떻게 작동하는지 테스트합니다. DORA의 연구에 따르면 이 같은 방법을 사용해 재해 복구 테스트를 수행하는 조직은 서비스 가용성이 더 높은 것으로 나타났습니다. 이와 같은 필수 활동을 정규화할 수 있도록 이러한 방식을 빨리 도입하는 것이 좋습니다.

고려해야 할 부분이 많으므로 아이디어 구현을 실험할 수 있는 시간과 능력을 갖춘 팀에서 이런 종류의 작업을 파일럿 테스트해야 합니다. 성공적인 결과를 얻을 때도 있고 실패할 때도 있겠지만, 테스트를 진행한 팀에게 정보를 얻어 조직에 새로운 아키텍처 패러다임을 전파할 때 이를 활용하는 것이 중요합니다.

Google의 연구에 따르면 성공한 기업은 개념 증명을 사용하고 실무 커뮤니티를 만드는 등 팀에서 정보를 공유할 기회를 제공하는 것으로 나타났습니다. 여러 팀의 인력이 정기적으로 만나 아이디어를 교환할 수 있는 시간, 공간, 리소스를 제공하세요. 또한 모두가 새로운 기술을 배워야 합니다. 도서 구입, 교육 과정 수강, 컨퍼런스 참석 등의 예산을 할당해 인재 성장에 투자하세요. 회사 메일링 리스트, 기술 자료, 오프라인 모임을 통해 산업 지식과 권장사항을 전파할 수 있는 인프라와 시간을 인력에게 제공하세요. 

참조 아키텍처

이 섹션에서는 다음 가이드라인을 토대로 한 참조 아키텍처에 대해 설명합니다.

  • 조정을 위해 Cloud Run, Kubernetes 등의 프로덕션 서비스용 컨테이너 및 컨테이너 스케줄러 사용
  • 효과적인 CI/CD 파이프라인 만들기
  • 보안에 집중

제품 서비스 컨테이너화

컨테이너화된 클라우드 애플리케이션은 컨테이너 관리와 조정 서비스를 기반으로 합니다. 여러 서비스가 출시되었지만 현재 가장 많이 사용되는 서비스는 Kubernetes입니다. 이제 Kubernetes는 업계의 컨테이너 조정 표준을 설정하며, 활발한 커뮤니티를 지원하고 다양한 주요 상용 공급업체의 지원을 받습니다. 그림 4에는 Kubernetes 클러스터의 논리적 구조가 요약되어 있습니다.

Kubernetes에서는 포드라고 부르는 추상화를 정의합니다. 각 포드에는 그림 4의 포드 A, B와 같이 하나의 컨테이너만 포함된 경우가 많지만 포드 C와 같이 여러 컨테이너가 포함될 수도 있습니다. 각 Kubernetes 서비스는 일반적으로 가상 머신(VM)인 여러 개의 노드를 포함하는 클러스터를 실행합니다. 그림 4에는 4개의 VM만 표시되어 있지만 실제 클러스터에서는 백 개 이상도 쉽게 포함할 수 있습니다. 포드가 Kubernetes 클러스터에 배포되면 서비스는 포드의 컨테이너가 실행되어야 할 VM을 결정합니다. 컨테이너에서 필요한 리소스를 지정하므로 Kubernetes에서 각 VM에 할당되는 포드를 지능적으로 선택할 수 있습니다.

포드의 배포 정보 중 일부에서 실행해야 할 포드의 인스턴스, 즉 복제본 수를 표시합니다. 그러면 Kubernetes 서비스가 포드 컨테이너 인스턴스를 여러 개 만들어 VM에 할당합니다. 예를 들어 그림 4에서 보이는 바와 같이, 포드 A의 배포에서 포드 C의 배포처럼 3개의 복제본을 요청했습니다. 하지만 포드 B의 배포에서는 4개의 복제본을 요청했으므로 이 예시의 클러스터에는 컨테이너 2를 위해 실행되는 인스턴스 4개가 포함됩니다. 그림에서 알 수 있듯이 포드 C처럼 여러 컨테이너를 포함한 포드는 항상 컨테이너가 동일한 노드에 할당됩니다.

Kubernetes에서는 다음과 같은 다른 서비스도 제공합니다.

  • 실행 중인 포드 모니터링: 컨테이너가 실패할 경우 서비스에서 새 인스턴스를 시작합니다. 이를 통해 포드의 배포에서 요청된 모든 복제본을 계속 사용할 수 있게 합니다.
  • 트래픽 부하 분산: 컨테이너의 복제본에 각 포드의 요청을 지능적으로 분산합니다.
  • 새 컨테이너의 자동 제로 다운타임 출시: 신규 버전이 완전히 배포될 때까지 새 인스턴스가 기존 인스턴스를 점진적으로 대체합니다.
  • 자동 확장: 클러스터에서 자율적으로 수요에 따라 VM을 추가하거나 삭제합니다.
상단에 3개의 파란색, 빨간색, 초록색 포드가 있는 Kubernetes와 아래에는 여러 포드로 구성된 완전한 Kubernetes 클러스터가 있는 다이어그램.
그림 4: Kubernetes 클러스터가 워크로드를 실행하며, 각 포드는 하나 이상의 컨테이너를 포함합니다.

효과적인 CI/CD 파이프라인 만들기

Kubernetes에서 실행하면 비용 절감과 같은 모놀리식 애플리케이션 리팩터링의 이점 몇 가지를 누릴 수 있습니다. 하지만 가장 중요한 이점 중 하나인 애플리케이션 업데이트 빈도를 늘리는 기능은 소프트웨어 배포 및 출시 방법을 변경해야만 얻을 수 있습니다. 이러한 이점을 누리려면 조직에서 효과적인 CI/CD 파이프라인을 만들어야 합니다.

지속적 통합은 개발자에게 빠른 피드백을 제공하는 자동 빌드 및 테스트 워크플로를 사용합니다. 팀 구성원 모두가 동일한 코드(예: 단일 서비스의 코드)를 사용해 공유되는 기본 라인 또는 트렁크에 작업을 정기적으로 통합해야 합니다. 각 개발자가 적어도 매일 이러한 통합을 수행해야 하며 자동 테스트를 포함하는 빌드 프로세스를 통해 각 통합을 검증해야 합니다. 지속적 배포에서는 성능, 보안, 탐색 테스트 등의 활동을 지속적으로 수행할 수 있도록 주로 빌드, 테스트, 배포 프로세스를 자동화하여 이 통합 코드를 빠르게 낮은 위험도로 배포하는 것을 목표로 합니다. 간단히 말해 CI는 개발자가 통합 문제를 신속하게 감지하는 데 도움이 되고, CD는 안정적이고 일상적인 배포를 지원합니다.

이해를 돕기 위해 구체적인 예를 살펴보겠습니다. 그림 5에서는 Google Kubernetes Engine에서 실행되는 컨테이너에 Google 도구를 사용하는 CI/CD 파이프라인을 보여줍니다.

그림 6과 같이 이 프로세스를 두 부분으로 나누어 생각하면 쉽습니다.

로컬 개발 원격 개발
여기서 목표는 내부 개발 루프의 속도를 높이고 개발자에게 로컬 코드 변경이 미치는 영향에 대한 피드백을 빠르게 얻을 수 있는 도구를 제공하는 것입니다. 여기에는 린트 작업, YAML 자동 완성, 더 빠른 로컬 빌드가 포함됩니다. pull 요청(PR)이 제출되면 원격 개발 루프가 시작됩니다. 여기서 목표는 CI를 통해 PR을 검증 및 테스트하고 취약점 스캔 및 바이너리 서명과 같은 기타 활동을 수행하는 데 걸리는 시간을 크게 단축하는 동시에 출시 승인을 자동화하는 것입니다.

  

클라우드 코드부터 Google Kubernetes Engine 배포까지의 프로세스를 보여주는 선이 있는 CI/CD 파이프라인입니다.
그림 5: 코드 작성부터 새 컨테이너 배포에 이르는 여러 단계가 포함되는 CI/CD 파이프라인

로컬 및 원격 개발 루프를 보여주는 두 개의 주기
그림 6: 로컬 및 원격 개발 루프

이 프로세스가 진행되는 동안 Google Cloud 도구는 어떻게 도움이 될까요?

로컬 개발: 로컬 애플리케이션 개발을 통해 개발자 생산성을 높이는 것이 중요합니다. 이러한 로컬 개발에는 로컬 및 원격 클러스터에 배포할 수 있는 애플리케이션 빌드가 수반됩니다. GitHub와 같은 소스 제어 관리 시스템에 변경사항을 커밋하기 전에 빠른 로컬 개발 루프로 개발자가 변경사항을 테스트하고 로컬 클러스터에 배포하도록 지원할 수 있습니다.

Google Cloud에서 Cloud Code를 제공하는 이유입니다. Cloud Code에는 Visual Studio Code 및 Intellij 등의 IDE 확장 프로그램이 포함되어 있어 개발자가 Kubernetes에서 코드를 신속하게 반복하고 디버깅하여 실행할 수 있습니다. Cloud Code에서는 Skaffold, Jib, Kubectl 등 자주 사용되는 도구를 통해 개발자가 코드에 대한 꾸준한 피드백을 실시간으로 확보할 수 있습니다.

지속적 통합: 새로운 Cloud Build GitHub 앱을 사용하면 팀이 GitHub 내에서 발생하는 다양한 저장소 이벤트(pull 요청, 분기 또는 태그 이벤트)에 빌드를 트리거할 수 있습니다. Cloud Build는 완전 서버리스 플랫폼으로서 부하에 따라 확장 및 축소되며 서버를 사전에 프로비저닝하거나 추가 용량에 대한 비용을 미리 지불할 필요가 없습니다. GitHub 앱을 통해 트리거된 빌드에서 상태를 GitHub에 자동으로 다시 게시합니다. 피드백이 GitHub 개발자 워크플로에 직접 통합되어 환경 전환이 줄어듭니다.

아티팩트 관리: Container Registry는 팀이 Docker 이미지를 관리하고, 취약점 스캔을 수행하고, 세분화된 액세스 제어를 통해 누가 어디에 액세스할 수 있는지 결정할 수 있는 유일한 공간입니다. 취약점 스캔이 Cloud Build에 통합되어 Cloud Build에서 이미지를 만들어 Container Registry에 저장하는 즉시 개발자가 보안 위협을 식별할 수 있습니다.

지속적 배포: Cloud Build에서는 빌드 단계를 사용하여 빌드, 테스트, 배포의 일부로 수행되는 특정 단계를 정의할 수 있습니다. 예를 들어 새 컨테이너를 만들어 Container Registry에 푸시해 놓고 이후의 빌드 단계에서 이 컨테이너를 관련 구성 및 정책과 함께 Google Kubernetes Engine(GKE) 또는 Cloud Run에 배포할 수 있습니다. 멀티 클라우드 전략을 추구한다면 다른 클라우드 제공업체에 배포하는 것도 가능합니다. 마지막으로 GitOps 스타일의 지속적 배포를 원하는 경우 Cloud Build에서 Git 저장소에 저장된 파일(예: Kubernetes 매니페스트)을 사용해 배포를 선언적으로 기술할 수 있습니다.

하지만 코드를 배포한다고 작업이 끝나는 것은 아닙니다. 조직은 코드를 실행하는 동안 코드를 관리하기도 해야 합니다. 이를 위해 Google Cloud는 운영 팀에 Cloud Monitoring, Cloud Logging과 같은 도구를 제공합니다.

GKE에서는 Google의 CI/CD 도구 사용이 필수가 아닙니다. 원한다면 다른 도구 모음을 마음대로 사용해도 됩니다. 예를 들어 CI/CD를 위해 Jenkins를 활용하거나 아티팩트 관리에 Artifactory를 활용할 수 있습니다.

현재 VM 기반 클라우드 애플리케이션을 사용하는 조직 중에서 능률적인 CI/CD 시스템을 갖추고 있는 조직은 거의 없습니다. 재설계된 애플리케이션의 이점을 얻으려면 이러한 시스템을 필수적으로 마련해야 하며 이에 따른 작업도 필요합니다. 파이프라인을 만드는 데 필요한 기술은 Kubernetes의 성숙도에 따라 일부 제공되기도 합니다. 하지만 인력의 변화가 중요합니다. 배포팀 인력이 개발, 테스트, 운영 등 다방면으로 기술을 갖추고 있어야 합니다. 기업 문화의 변화에는 많은 시간이 소요되므로 CI/CD 환경으로 이전할 때 인력의 지식과 행동을 변화시키는 데 노력을 기울여야 합니다.

보안에 집중

모놀리식 애플리케이션을 클라우드 기반 패러다임으로 재설계하는 것은 큰 변화입니다. 이로 인해 해결해야 할 새로운 보안 과제가 제기되는 것은 당연한 일입니다. 가장 중요한 과제 두 가지는 다음과 같습니다.

  • 컨테이너 간 액세스 보안
  • 안전한 소프트웨어 공급망 보장

첫 번째 과제는 애플리케이션을 컨테이너화된 서비스(또는 마이크로서비스)로 분할하려면 서비스끼리 통신할 수 있는 방법이 필요하다는 사실에서 기인합니다. 모든 서비스를 동일한 Kubernetes 클러스터에서 실행하더라도 여전히 서비스 간 액세스 제어를 신경 써야 합니다. 결국에는 Kubernetes 클러스터를 다른 애플리케이션과 공유하게 될 수 있으며 이 경우 다른 앱에 컨테이너를 개방해 두면 안 됩니다.

컨테이너에 대한 액세스를 제어하려면 호출자를 인증한 후 이러한 다른 컨테이너에서 어떤 17개의 요청이 승인되었는지 확인해야 합니다. 요즘은 일반적으로 서비스 메시를 사용해 이와 같은 문제를 해결합니다. Google, IBM 등에서 만든 오픈소스 프로젝트인 Istio가 그 대표적인 예입니다. 그림 7에서는 Kubernetes 클러스터에서 Istio가 사용되는 경우를 보여줍니다.

그림과 같이 Istio 프록시는 애플리케이션 컨테이너 사이의 모든 트래픽을 가로챕니다. 이를 통해 애플리케이션 코드를 변경하지 않고도 서비스 메시가 여러 유용한 서비스를 제공할 수 있습니다. 다음과 같은 서비스가 포함됩니다.

  • 보안: TLS 및 최종 사용자 인증을 사용한 서비스 간 인증을 활용합니다.
  • 트래픽 관리: 애플리케이션에서 컨테이너 간에 요청이 라우팅되는 방식을 제어할 수 있습니다.
  • 관측 가능성: 컨테이너 간 통신의 로그 및 측정항목을 캡처합니다.
액세스 보안에서 서비스 메시의 기능을 보여주는 다이어그램
그림 7: Istio를 사용한 Kubernetes 클러스터에서는 컨테이너 간의 모든 트래픽이 이 서비스 메시를 거칩니다.

Google Cloud에서는 Istio를 GKE 클러스터에 추가할 수 있습니다. 서비스 메시를 사용할 필요가 없더라도 클라우드 애플리케이션 고객이 보안을 Istio급으로 강화할 수 있는지 문의할 수 있습니다. 고객들은 보안에 큰 관심을 갖고 있으며, 컨테이너 기반 환경에서 Istio는 보안 제공에서 중요한 부분을 차지합니다.

Google Cloud에서는 오픈소스 Istio 지원 외에 Traffic Director도 제공합니다. 이 완전 Google Cloud 관리형 서비스 메시 제어 영역은 여러 리전의 클러스터와 VM 인스턴스에 글로벌 부하 분산을 제공하고, 서비스 프록시에서 상태 점검을 오프로드하며, 정교한 트래픽 관리 및 위에서 설명한 기타 기능을 제공합니다.

Traffic Director의 특별한 기능 중 하나는 (그림 8에 나온) 메시의 마이크로서비스에 대한 리전 간 자동 장애 조치 및 오버플로입니다.

Traffic Director를 보여주는 다이어그램
그림 8: Traffic Director는 리전 간 자동 장애 조치 및 오버플로 지원 제공

이 기능을 사용해 서비스 메시의 서비스에 대한 글로벌 복원력과 보안을 결합할 수 있습니다.

Traffic Director는 서비스 메시의 보안 수준을 개선하는 데 유용한 여러 트래픽 관리 기능을 제공합니다. 예를 들어 그림 9의 트래픽 미러링 기능은 섀도 애플리케이션이 기본 버전의 애비 처리 중인 실제 트래픽의 사본을 수신할 수 있도록 정책으로 쉽게 설정할 수 있습니다. 섀도 서비스에서 수신한 사본 응답은 처리 후에 삭제됩니다. 트래픽 미러링은 프로덕션 트래픽에 영향을 주지 않으면서 프로덕션 트래픽의 보안 이상을 테스트하고 오류를 디버깅할 수 있는 효과적인 도구가 될 수 있습니다.

하지만 리팩터링된 애플리케이션이 가져온 새로운 보안 과제는 컨테이너 간 상호작용 보호뿐만이 아닙니다. 실행하는 컨테이너 이미지를 신뢰할 수 있도록 보장하는 것도 문제입니다. 이를 위해서는 소프트웨어 공급망에 보안과 규정 준수를 기본 제공해야 합니다.

상단의 파란색 정사각형에 Traffic Director 텍스트가 있고 선이 Service A와 프록시라고 쓰여 있는 1개의 빈 정사각형에 안에 있는 회색 정사각형 2개로 연결되고 선이 분기로 연결되는 다이어그램. 한 쪽 분기에는 트래픽을 나타내는 빈 정사각형이 있고 반대쪽에는 트래픽 사본을 나타내는 빈 정사각형이 있습니다.
그림 9: Traffic Director의 트래픽 미러링

(그림 10과 같은) 두 가지 기본 작업이 필요합니다.

취약점 스캔: Container Registry 취약점 스캔을 통해 잠재적 위협에 대한 빠른 피드백을 얻고 컨테이너를 Cloud Build에서 빌드하여 Container Registry에 저장하는 즉시 문제를 식별할 수 있습니다. 애플리케이션 개발 프로세스 중에 바로 Ubuntu, Debian, Alpine에 대한 패키지 취약점을 식별하며 이 과정에서 CentOS 및 RHEL도 지원됩니다. 많은 비용이 드는 비효율성을 없애고 알려진 취약점을 해결하는 데 필요한 시간을 단축할 수 있습니다.

Binary Authorization: Binary Authorization 및 Container Registry 취약점 스캔을 통합하면 전체 배포 정책의 일부로 취약점 스캔 발견 항목에 따라 배포를 통제할 수 있습니다. Binary Authorization은 배포 시점의 보안 제어를 제공하여 수동 개입 없이 GKE에 신뢰할 수 있는 컨테이너 이미지만 배포되도록 합니다.

서비스 메시를 사용한 컨테이너 간 액세스 보호 및 안전한 소프트웨어 공급망 보장은 안전한 컨테이너 기반 애플리케이션을 만드는 데 있어 중요합니다. 배포하는 클라우드 플랫폼 인프라의 보안 검증을 비롯한 다양한 기능이 있습니다. 하지만 가장 중요한 점은 모놀리식 애플리케이션에서 현대적인 클라우드 기반 패러다임으로 이전할 경우 새로운 보안 과제도 발생한다는 사실입니다. 성공적인 전환을 위해서는 과제를 이해하고 각 문제를 해결하기 위한 구체적인 계획을 수립해야 합니다.

코드가 Kubernetes Engine에 배포되기 전에 Cloud Build, 취약점 스캔, Binary Authorization, 신뢰할 수 있는 이미지를 거치는 과정을 보여주는 다이어그램. 취약점 또는 신뢰할 수 없는 이미지가 발견되면 감사 로그를 트리거하는 방법을 보여줍니다.
그림 10: 취약점 스캔 및 Binary Authorization의 워크플로

시작하기

클라우드 기반 아키텍처로의 이전을 다년간의 빅뱅 프로젝트처럼 다루지 말고

개념 증명을 시작할 수 있는 역량과 전문성을 갖춘 팀 또는 이미 이를 마친 팀부터 찾으세요. 그런 다음 획득한 정보를 조직 전체에 전파하세요. 팀에서 스트랭글러 피그(strangler fig) 패턴을 채택하여 새 기능을 계속 배포하면서 서비스를 점진적, 반복적으로 클라우드 기반 아키텍처로 이전하도록 하세요.

성공을 위해서는 일상 업무의 일부로 시스템 아키텍처를 진화시킬 수 있는 역량, 리소스, 권한이 팀에 있어야 합니다. 앞에 나온 6가지 아키텍처 결과에 따라 새로운 작업에 대한 명확한 아키텍처 목표를 설정하되, 이를 달성할 방법을 결정할 수 있는 자유를 팀에 부여하세요.

무엇보다도 주저하지 말고 시작하세요. 팀의 생산성, 민첩성을 향상하고 서비스의 보안과 안정성을 개선하는 것이 조직의 성공에 더욱 중요해질 것입니다. 체계적인 실험과 개선이 일상 업무가 된 팀이 우수한 실적을 거둘 수 있습니다.

Google은 수년 동안 내부에서 사용해 온 소프트웨어를 기반으로 Kubernetes를 발명한 만큼 클라우드 기반 기술에 대한 풍부한 경험을 갖고 있습니다.

Google Cloud는 CI/CD 및 보안 제품에서 알 수 있듯이 컨테이너화된 애플리케이션에 초점을 맞추고 있습니다. 사실은 분명합니다. Google Cloud는 오늘날 컨테이너화된 애플리케이션 지원에 있어 선두적인 업체라는 것입니다.

cloud.google.com/devops에서 빠른 점검을 이용해 귀사의 현황을 파악하고 느슨하게 결합된 아키텍처 등 이 백서에서 설명한 패턴 구현 등 진행 방법에 대한 조언을 확인하세요.

많은 Google Cloud 파트너가 이미 기업들의 전환을 돕고 있습니다. 숙련된 가이드를 이용할 수 있는데 굳이 재설계 방법을 직접 개척할 이유가 있을까요?

시작하려면 문의를 통해 Google 솔루션 설계자 상담 일정을 잡으세요. 변화를 이해하도록 도와드리고 이를 실현하는 방법을 함께 찾아드립니다.

추가 자료

다음 단계로 나아갈 준비가 되셨나요?

Google Cloud가 기존 아키텍처에서 벗어나는 데 어떤 도움을 주는지 알아보려면 문의하세요.
전문가와 상담하기
Google Cloud Next '21: Google Kubernetes Engine에서 Autopilot 소개
웹 세미나 보기

양식을 작성하시면 연락드리겠습니다. 영업팀에 문의