클라우드 네이티브란?

이 콘텐츠는 Azure용 클라우드 네이티브 .NET 애플리케이션 설계 eBook 에서 발췌한 것으로, .NET 문서에서 제공되거나 오프라인 상태에서도 읽을 수 있는 PDF(무료 다운로드 가능)로 제공됩니다.

Azure용 클라우드 기본 .NET 앱 eBook 표지 썸네일.

수행 중인 작업을 중지하고 동료에게 "클라우드 네이티브"라는 용어를 정의하도록 요청합니다. 몇 가지 다른 답변을 얻을 수 있는 좋은 기회가 될 것입니다.

간단한 정의로 시작해 보겠습니다.

‘클라우드 네이티브 아키텍처 및 기술은 클라우드에서 빌드된 워크로드를 디자인, 생성 및 운영하는 접근 방식으로, 클라우드 컴퓨팅 모델을 최대한 활용합니다.’

Cloud Native Computing Foundation은 다음과 같은 공식 정의를 제공합니다.

클라우드 네이티브 기술을 통해 조직은 퍼블릭, 프라이빗 및 하이브리드 클라우드와 같은 최신 동적 환경에서 스케일링 가능한 애플리케이션을 빌드하고 실행할 수 있습니다. 이 방법의 예로 컨테이너, 서비스 메시, 마이크로 서비스, 변경할 수 없는 인프라 및 선언적 API를 들 수 있습니다.

이러한 기술을 통해 복원력 있고 관리 가능하며 관찰 가능한 느슨하게 결합된 시스템을 사용할 수 있습니다. 강력한 자동화와 결합되므로 엔지니어는 최소한의 수고로 자주 발생하며 예측 가능한 방식으로 높은 영향을 미치는 변경을 수행할 수 있습니다.

클라우드 네이티브는 ‘속도’ 및 ‘민첩성’에 관한 것입니다. 비즈니스 시스템은 비즈니스 역량을 활성화하는 측면에서 비즈니스 속도와 성장을 가속화하는 전략적 혁신 무기로 진화하고 있습니다. 새로운 아이디어를 즉시 출시하는 것이 필수적입니다.

동시에, 비즈니스 시스템은 더 많은 사용자 요구로 인해 점점 더 복잡해지고 있습니다. 빠른 응답성, 혁신적인 기능 및 제로 가동 중지 시간을 기대합니다. 성능 문제, 반복적인 오류 및 빠른 전환 능력 부족은 더 이상 허용되지 않습니다. 사용자들은 경쟁업체를 찾게 될 것입니다. 클라우드 네이티브 시스템은 빠른 변화, 더 큰 규모 및 복원력을 수용하도록 설계되었습니다.

다음은 클라우드 네이티브 기술을 구현한 일부 기업들입니다. 이러한 기업들이 달성한 속도, 민첩성 및 스케일링 기능에 대해 생각해 보세요.

회사 환경
Netflix 프로덕션 환경에 600개 이상의 서비스가 있습니다. 매일 100번 배포합니다.
Uber 프로덕션에 1,000개 이상의 서비스가 있습니다. 매주 수천 번 배포합니다.
WeChat 프로덕션에 3,000개 이상의 서비스가 있습니다. 매일 1,000번 배포합니다.

여기서 볼 수 있듯이 Netflix, Uber 및 WeChat은 많은 독립 서비스로 구성된 클라우드 네이티브 시스템을 노출합니다. 이 아키텍처 스타일을 사용하면 시장 상황에 신속하게 대응할 수 있습니다. 전체 재배포 없이 복잡한 라이브 애플리케이션의 소규모 영역을 즉시 업데이트합니다. 필요에 따라 개별적으로 서비스를 스케일링합니다.

클라우드 네이티브의 핵심 요소

클라우드 네이티브의 속도와 민첩성은 여러 요인에서 파생됩니다. 가장 중요한 것은 ‘클라우드 인프라’입니다. 하지만 이것이 다가 아닙니다. 그림 1-3에 나와 있는 5개의 다른 기본 핵심 요소가 클라우드 네이티브 시스템의 기반이 됩니다.

클라우드 네이티브 기본 핵심 요소

그림 1-3. 클라우드 네이티브 기본 핵심 요소

각 핵심 요소의 중요성을 좀 더 잘 이해하는 시간을 좀 더 가져보겠습니다.

클라우드

클라우드 네이티브 시스템은 클라우드 서비스 모델을 최대한 활용합니다.

가상화된 동적 클라우드 환경에서 성장하도록 설계된 이러한 시스템은 PaaS(Platform as a Service) 컴퓨팅 인프라 및 관리형 서비스를 광범위하게 사용합니다. 자동화를 통해 기본 인프라를 몇 분 안에 프로비저닝하고 주문형으로 크기 조정, 스케일링 또는 소멸시키는 ’삭제 가능’ 인프라로 처리합니다.

애완동물을 대하는 방식과 상품을 다루는 방식의 차이점을 생각해 보세요. 전통적인 데이터 센터에서는 서버가 애완동물(즉 의미 있는 이름이 부여되고 관리되는 실제 컴퓨터)로 취급됩니다. 동일한 머신에 더 많은 리소스를 추가하여 스케일링합니다(스케일 업). 서버가 아프면 건강해지도록 간호합니다. 서버를 사용할 수 없게 되면 모든 사용자가 알 수 있습니다.

상품 서비스 모델은 다릅니다. 각 인스턴스를 가상 머신 또는 컨테이너로 프로비저닝합니다. 각 인스턴스는 동일하며 Service-01, Service-02 등과 같은 시스템 식별자가 할당됩니다. 더 많은 인스턴스를 만들어 크기를 조정합니다(스케일 아웃). 인스턴스를 사용할 수 없게 되면 아무도 알아차리지 못합니다.

상품 모델은 변경이 불가능한 인프라를 수용합니다. 서버는 복구되거나 수정되지 않습니다. 한 서버에서 발생하거나 업데이트가 필요한 경우 삭제되고 새 서버가 프로비저닝되며 이러한 모든 작업은 자동화를 통해 수행됩니다.

클라우드 네이티브 시스템은 상품 서비스 모델을 수용합니다. 실행 중인 머신과 관계없이 인프라가 스케일 인되거나 스케일 아웃될 때도 계속 실행됩니다.

Azure 클라우드 플랫폼은 자동 스케일링, 자체 복구 및 모니터링 기능을 사용하여 이러한 유형의 고도로 탄력적인 인프라를 지원합니다.

최신 디자인

클라우드 네이티브 앱을 디자인하려면 어떻게 해야 할까요? 아키텍처는 어떤 모습일까요? 어떤 원칙, 패턴 및 모범 사례를 준수할 것인가요? 어떤 인프라 및 운영 문제가 중요할까요?

12단계 응용

클라우드 기반 애플리케이션을 생성하기 위한 널리 허용되는 방법은 12단계 응용입니다. 이 방식은 개발자가 최신 클라우드 환경에 최적화된 애플리케이션을 생성하기 위해 따르는 일련의 원칙과 사례를 설명합니다. 환경 전반의 이식성과 선언적 자동화에 특히 유의합니다.

모든 웹 기반 애플리케이션에 적용할 수 있지만 많은 실무자는 12단계를 클라우드 네이티브 앱 빌드를 위한 견고한 토대로 간주합니다. 이러한 원칙을 기준으로 하는 시스템은 신속하게 배포 및 확장할 수 있으며, 시장 변화에 신속하게 대응할 수 있는 기능을 추가할 수 있습니다.

다음 표에서는 12단계 방법론을 중점적으로 보여 줍니다.

요인 설명
1 - 코드베이스 자체 리포지토리에 저장된 각 마이크로 서비스에 대한 단일 코드베이스입니다. 버전 제어를 사용하여 추적되며 여러 환경(QA, 스테이징, 프로덕션)에 배포할 수 있습니다.
2 - 종속성 각 마이크로 서비스는 자체 종속성을 격리하고 패키징하여 전체 시스템에 영향을 주지 않으면서 변경 내용을 수용합니다.
3 - 구성 구성 정보는 마이크로 서비스 외부로 이동하며 코드 외부의 구성 관리 도구를 통해 외부화됩니다. 동일한 배포가 올바른 구성이 적용된 환경 간에 전파될 수 있습니다.
4 - 지원 서비스 보조 리소스(데이터 저장소, 캐시, 메시지 브로커)를 주소 지정 가능 URL을 통해 노출합니다. 이렇게 하여 리소스를 애플리케이션에서 분리하면 바꿔서 사용할 수 있습니다.
5 - 빌드, 릴리스, 실행 각 릴리스는 빌드, 릴리스, 실행 스테이지마다 엄격히 구분되어야 합니다. 각각에는 고유한 ID가 태그로 지정되고 롤백 기능을 지원해야 합니다. 최신 CI/CD 시스템은 이 원칙을 충족하는 데 도움이 될 수 있습니다.
6 - 프로세스 각 마이크로 서비스는 실행 중인 다른 서비스와 격리되어 자체 프로세스에서 실행되어야 합니다. 필요한 상태를 분산 캐시 또는 데이터 저장소와 같은 지원 서비스에 외부화합니다.
7 - 포트 바인딩 각 마이크로 서비스는 자체 포트에 노출되는 인터페이스 및 기능을 갖춘 자체 포함 서비스여야 합니다. 이러한 방식으로 다른 마이크로 서비스에서 격리합니다.
8 - 동시성 용량을 늘려야 하는 경우 사용 가능한 가장 강력한 머신에서 대규모 단일 인스턴스를 스케일 업하는 것이 아니라, 여러 동일한 프로세스(복사본)에서 수평으로 서비스를 스케일 아웃합니다. 애플리케이션을 동시 상태로 개발하여 클라우드 환경에서 원활하게 스케일 아웃할 수 있도록 합니다.
9 - 삭제 가능성 서비스 인스턴스는 삭제할 수 있어야 합니다. 속도 우선 시작을 적용하여 스케일링 기회와 정상적인 종료를 늘림으로써 시스템을 올바른 상태로 유지합니다. 오케스트레이터와 함께 Docker 컨테이너는 기본적으로 이 요구 사항을 충족합니다.
10 - 개발/프로덕션 패리티 애플리케이션 수명 주기 동안 환경을 가능한 한 비슷하게 유지하여 비용이 많이 드는 단축 작업 경로를 방지합니다. 여기서 컨테이너를 채택하면 동일한 실행 환경이 개선되므로 유용할 수 있습니다.
11 - 로깅 마이크로 서비스에서 생성된 로그를 이벤트 스트림으로 처리합니다. 이벤트 집계를 사용하여 처리합니다. 로그 데이터를 Azure Monitor 또는 Splunk와 같은 데이터 마이닝/로그 관리 도구로 전파하고 결국에는 장기 보관 상태로 유지합니다.
12 - 관리 프로세스 데이터 정리 또는 컴퓨팅 분석과 같은 운영/관리 작업을 일회성 프로세스로 실행합니다. 독립 도구를 사용하여 프로덕션 환경에서 이러한 작업을 호출하지만 애플리케이션과는 별도로 호출합니다.

Beyond the Twelve-Factor App(12단계 앱 그 이상) 책에서 저자인 Kevin Hoffman은 원래의 12가지 단계 각각에 대해 자세히 설명합니다(2011년 제작). 또한 오늘날의 최신 클라우드 애플리케이션 디자인을 반영하는 세 가지 추가 단계에 대해서도 설명합니다.

새 단계 설명
13 - API 우선 모든 항목을 서비스로 만듭니다. 코드가 프런트 엔드 클라이언트, 게이트웨이 또는 다른 서비스에서 사용된다고 가정합니다.
14 - 원격 분석 워크스테이션에서 애플리케이션 및 해당 동작을 심층적으로 파악할 수 있습니다. 클라우드에서는 그렇지 않습니다. 디자인에 모니터링, 도메인별 및 상태/시스템 데이터 컬렉션이 포함되어 있는지 확인합니다.
15 - 인증/권한 부여 처음부터 ID를 구현합니다. 퍼블릭 클라우드에서 사용할 수 있는 RBAC(역할 기반 액세스 제어) 기능을 고려합니다.

이 장과 책 전반에서 12개 이상의 요인에 대한 다양한 측면을 살펴보겠습니다.

Azure Well-Architected 프레임워크

특히 클라우드 네이티브 아키텍처를 구현할 때 클라우드 기반 워크로드를 디자인하고 배포하는 것은 어려울 수 있습니다. Microsoft는 사용자와 팀이 강력한 클라우드 솔루션을 제공하는 데 도움이 되는 업계 표준 모범 사례를 제공합니다.

Microsoft Well-Architected Framework는 클라우드 네이티브 워크로드의 품질을 개선하는 데 사용할 수 있는 일련의 안내 테넌트를 제공합니다. 프레임워크는 아키텍처 우수성의 5가지 핵심 요소로 구성됩니다.

원리 설명
원가 관리 지속적으로 증가하는 가치를 초기에 창출하는 데 중점을 둡니다. 빌드-측정-학습 원칙을 적용하여 자본 집약적인 솔루션을 피하면서 출시 시간을 단축합니다. 종량제 전략을 사용하여 대규모 투자를 선불로 제공하는 대신 스케일 아웃할 때 투자합니다.
운영 우수성 환경 및 작업을 자동화하여 속도를 높이고 인간의 오류를 줄입니다. 문제 업데이트를 신속하게 롤백하거나 롤포워드합니다. 처음부터 모니터링 및 진단을 구현합니다.
성능 효율성 워크로드에 대한 요구를 효율적으로 충족합니다. 수평 스케일링(스케일 아웃)을 우선적으로 적용하고 시스템으로 설계합니다. 성능 및 부하 테스트를 지속적으로 수행하여 잠재적인 병목 상태를 식별합니다.
신뢰성 복원 가능하고 사용 가능한 워크로드를 빌드합니다. 복원력을 통해 워크로드를 오류로부터 복구하고 계속 작동할 수 있습니다. 가용성을 통해 사용자는 항상 워크로드에 액세스할 수 있습니다. 오류를 예상하고 복구하도록 애플리케이션을 디자인합니다.
보안 디자인 및 구현에서 배포 및 운영에 이르는 애플리케이션의 전체 수명 주기에서 보안을 구현합니다. ID 관리, 인프라 액세스, 애플리케이션 보안, 데이터 주권 및 암호화에 보다 세심한 주의를 기울입니다.

시작하기 위해 Microsoft는 현재 클라우드 워크로드에서 잘 설계된 다섯 가지 핵심 요소를 평가하는 데 도움이 되는 일련의 온라인 평가를 제공합니다.

마이크로 서비스

클라우드 네이티브 시스템은 최신 애플리케이션을 생성하기 위한 인기 있는 아키텍처 스타일인 마이크로 서비스를 수용합니다.

공유 패브릭을 통해 상호 작용하는 소규모 독립 서비스의 분산 집합으로 빌드된 마이크로 서비스는 다음과 같은 특성을 공유합니다.

  • 각각은 더 큰 도메인 컨텍스트 내에서 특정 비즈니스 기능을 구현합니다.

  • 각각은 자율적으로 개발되며 독립적으로 배포할 수 있습니다.

  • 각각은 자체 데이터 스토리지 기술, 종속성 및 프로그래밍 플랫폼을 캡슐화하는 자체 포함형입니다.

  • 각각은 자체 프로세스에서 실행되며 HTTP/HTTPS, gRPC, WebSockets 또는 AMQP와 같은 표준 통신 프로토콜을 사용하여 서로 통신합니다.

  • 함께 애플리케이션을 구성합니다.

그림 1-4는 모놀리식 애플리케이션 접근 방식과 마이크로 서비스 접근 방식을 대조해서 보여 줍니다. 모놀리스가 단일 프로세스에서 실행되는 계층화된 아키텍처로 구성되는 방법을 확인합니다. 일반적으로 관계형 데이터베이스를 사용합니다. 그러나 마이크로 서비스 접근 방식은 기능을 각각 자체 논리, 상태 및 데이터를 갖는 독립적인 서비스로 분리합니다. 각 마이크로 서비스는 자체 데이터 저장소를 호스팅합니다.

모놀리식 배포 대 마이크로 서비스

그림 1-4. 모놀리식 대 마이크로 서비스 아키텍처

마이크로 서비스가 앞에서 설명한 12단계 응용에서 프로세스 원칙을 승격하는 방법을 확인합니다.

6단계는 “각 마이크로 서비스가 실행 중인 다른 서비스와 격리되어 자체 프로세스에서 실행되어야 함”을 지정합니다.

왜 마이크로 서비스인가?

마이크로 서비스는 민첩성을 제공합니다.

이 장 앞부분에서는 모놀리식으로 빌드된 전자 상거래 애플리케이션을 마이크로 서비스와 비교했습니다. 이 예제에서는 몇 가지 명확한 이점을 확인했습니다.

  • 각 마이크로 서비스에는 자율 수명 주기가 있으며 독립적으로 발전하고 자주 배포할 수 있습니다. 새 기능 또는 업데이트를 배포하기 위해 분기별 릴리스를 기다릴 필요가 없습니다. 라이브 애플리케이션의 작은 영역을 업데이트하여 전체 시스템을 중단할 위험을 줄일 수 있습니다. 애플리케이션을 완전히 다시 배포하지 않고도 업데이트를 수행할 수 있습니다.

  • 각 마이크로 서비스는 독립적으로 스케일링할 수 있습니다. 전체 애플리케이션을 단일 단위로 스케일링하는 대신, 원하는 성능 수준 및 서비스 수준 계약을 충족하기 위해 더 많은 처리 능력이 필요한 서비스만 스케일 아웃합니다. 세분화된 스케일링은 시스템을 보다 효율적으로 제어할 수 있도록 하며, 전체가 아니라 시스템의 일부를 스케일링함으로써 전반적인 비용을 줄이는 데 도움이 됩니다.

마이크로 서비스를 이해하기 위한 유용한 참조 가이드는 .NET 마이크로 서비스: 컨테이너화된 .NET 애플리케이션을 위한 아키텍처입니다. 이 책은 마이크로 서비스 디자인 및 아키텍처에 대해 자세히 설명합니다. Microsoft에서 무료로 다운로드할 수 있는 전체 스택 마이크로 서비스 참조 아키텍처의 부록에 해당합니다.

마이크로 서비스 개발

마이크로 서비스는 모든 최신 개발 플랫폼에서 만들 수 있습니다.

Microsoft .NET 플랫폼은 탁월한 선택입니다. 무료 및 오픈 소스로 제공되는 이 플랫폼에는 마이크로 서비스 개발을 간소화하는 많은 기본 제공 기능이 있습니다. .NET은 플랫폼에 관계없이 사용 가능합니다. 애플리케이션은 Windows, macOS 및 대부분의 Linux 버전에서 빌드하고 실행할 수 있습니다.

.NET은 성능이 뛰어나고 Node.js 및 기타 경쟁 플랫폼에 비해 높은 평가를 받았습니다. 흥미롭게도 TechEmpower는 많은 웹 애플리케이션 플랫폼 및 프레임워크에서 광범위한 성능 벤치마크 집합을 수행했습니다. .NET은 Node.js 및 기타 경쟁 플랫폼보다 훨씬 높은 상위 10위 이내에 있습니다.

.NET은 Microsoft 및 GitHub의 .NET 커뮤니티에서 유지 관리됩니다.

마이크로 서비스 문제

분산 클라우드 네이티브 마이크로 서비스는 엄청난 민첩성과 속도를 제공할 수 있지만 다음과 같은 많은 과제를 제시합니다.

통신

프런트 엔드 클라이언트 애플리케이션은 백 엔드 코어 마이크로 서비스와 어떻게 통신합니까? 직접 통신을 허용할까요? 또는 유연성, 제어 및 보안을 제공하는 게이트웨이 외관을 사용하여 백 엔드 마이크로 서비스를 추상화할 수 있나요?

백 엔드 코어 마이크로 서비스는 서로 어떻게 통신하나요? 결합을 높이고 성능과 민첩성에 영향을 줄 수 있는 직접 HTTP 호출을 허용할까요? 또는 큐 및 토픽 기술과 분리된 메시징을 고려할 수 있나요?

통신은 클라우드 네이티브 통신 패턴 장에서 다룹니다.

복원력

마이크로 서비스 아키텍처는 시스템을 In-Process에서 Out-of-process 네트워크 통신으로 이동합니다. 분산 아키텍처에서 서비스 B가 서비스 A의 네트워크 호출에 응답하지 않으면 어떻게 되나요? 또는 서비스 C를 일시적으로 사용할 수 없게 되고 서비스 C를 호출하는 다른 서비스가 차단되면 어떻게 되나요?

복원력은 클라우드 네이티브 복원력 장에서 다룹니다.

‘분산 데이터’

기본적으로 각 마이크로 서비스는 자체 데이터를 캡슐화하여 퍼블릭 인터페이스를 통해 작업을 노출합니다. 그렇다면 데이터를 쿼리하거나 여러 서비스에서 트랜잭션을 구현하려면 어떻게 해야 할까요?

분산 데이터는 클라우드 네이티브 데이터 패턴 장에서 다룹니다.

비밀

마이크로 서비스로 어떻게 비밀 및 중요한 구성 데이터를 안전하게 저장하고 관리할 수 있나요?

비밀은 클라우드 네이티브 보안에서 자세히 설명합니다.

Dapr을 사용하여 복잡성 관리

Dapr은 분산 오픈 소스 애플리케이션 런타임입니다. Dapr은 플러그형 구성 요소의 아키텍처를 통해 분산 애플리케이션의 내부 ‘배관’을 크게 간소화합니다. Dapr 런타임에서 미리 빌드된 인프라 기능 및 구성 요소와 애플리케이션을 바인딩하는 동적 글루를 제공합니다. 그림 1-5는 20,000피트 상공에서 바라본 Dapr을 보여 줍니다.

Dapr이 배포되어 있습니다.그림 1-5. 20,000피트 상공에서 바라본 Dapr

그림의 맨 위 행에서 Dapr이 인기 있는 개발 플랫폼에 언어별 SDK를 제공하는 방법을 확인합니다. Dapr v1에는 .NET, Go, Node.js, Python, PHP, Java 및 JavaScript에 대한 지원이 포함됩니다.

언어별 SDK는 개발자 환경을 향상시키지만 Dapr은 플랫폼에 구애받지 않습니다. 내부적으로 Dapr의 프로그래밍 모델은 표준 HTTP/gRPC 통신 프로토콜을 통해 기능을 노출합니다. 모든 프로그래밍 플랫폼은 네이티브 HTTP 및 gRPC API를 통해 Dapr을 호출할 수 있습니다.

그림의 가운데에 있는 파란색 상자는 Dapr 구성 요소를 나타냅니다. 각각은 애플리케이션에서 사용할 수 있는 분산 애플리케이션 기능에 대해 미리 빌드된 배관 코드를 노출합니다.

구성 요소 행은 애플리케이션에서 사용할 수 있는 미리 정의된 대규모 인프라 구성 요소 집합을 나타냅니다. 구성 요소를 작성할 필요가 없는 인프라 코드로 간주합니다.

아래쪽 행은 Dapr의 이식성과 실행할 수 있는 다양한 환경을 강조 표시합니다.

앞으로 Dapr은 클라우드 네이티브 애플리케이션 개발에 중대한 영향을 미칠 가능성이 있습니다.

컨테이너

모든 ‘클라우드 네이티브’ 대화에서 용어 ‘컨테이너’가 언급되는 것을 자주 듣게 될 것입니다. 클라우드 네이티브 패턴 책에서 저자인 Cornelia Davis는 “컨테이너가 클라우드 네이티브 소프트웨어의 뛰어난 활성화 요인”이라고 말합니다.” Cloud Native Computing Foundation은 클라우드 네이티브 여정을 시작하는 기업을 위한 지침인 클라우드 네이티브 트레일 맵의 첫 번째 단계로 마이크로 서비스 컨테이너화를 배치합니다.

마이크로 서비스를 컨테이너화하는 것은 간단합니다. 코드, 해당 종속성 및 런타임은 컨테이너 이미지라는 이진 파일로 패키지됩니다. 이미지는 이미지의 리포지토리 또는 라이브러리 역할을 하는 컨테이너 레지스트리에 저장됩니다. 레지스트리는 개발 컴퓨터, 데이터 센터 또는 퍼블릭 클라우드에 있을 수 있습니다. Docker 자체는 Docker Hub를 통해 퍼블릭 레지스트리를 유지 관리합니다. Azure 클라우드는 프라이빗 컨테이너 레지스트리를 사용하여 컨테이너 이미지를 실행할 클라우드 애플리케이션 가까이에 저장합니다.

애플리케이션이 시작되거나 스케일링되면 컨테이너 이미지를 실행 중인 컨테이너 인스턴스로 변환합니다. 인스턴스는 컨테이너 런타임 엔진이 설치된 모든 컴퓨터에서 실행됩니다. 필요한 수만큼 컨테이너화된 서비스의 인스턴스를 유지할 수 있습니다.

그림 1-6은 각각 자체 컨테이너에 있으며 모두 단일 호스트에서 실행되는 세 개의 서로 다른 마이크로 서비스를 보여 줍니다.

컨테이너 호스트에서 실행되는 여러 컨테이너

그림 1-6. 컨테이너 호스트에서 실행되는 여러 컨테이너

각 컨테이너가 서로 다를 수 있는 자체 종속성 및 런타임 집합을 유지 관리하는 방법에 유의하세요. 여기서는 동일한 호스트에서 실행되는 다양한 버전의 제품 마이크로 서비스를 볼 수 있습니다. 각 컨테이너는 기본 호스트 운영 체제, 메모리 및 프로세서의 조각을 공유하지만 서로 격리됩니다.

컨테이너 모델이 12단계 응용종속성 원칙을 얼마나 잘 수용하는지 확인합니다.

2단계는 “각 마이크로 서비스가 자체 종속성을 격리하고 패키징하여 전체 시스템에 영향을 주지 않으면서 변경 내용을 수용한다”고 지정합니다.

컨테이너는 Linux 및 Windows 워크로드를 모두 지원합니다. Azure 클라우드는 두 가지 모두를 공개적으로 수용합니다. 흥미롭게도 Windows Server가 아닌 Linux는 Azure에서 더 인기 있는 운영 체제가 되었습니다.

여러 컨테이너 공급업체가 있지만 Docker가 시장에서 가장 큰 지분을 차지했습니다. 이 회사는 소프트웨어 컨테이너 이동을 추진하고 있습니다. 또한 클라우드 네이티브 애플리케이션을 패키징, 배포 및 실행하기 위한 사실상 표준이 되었습니다.

왜 컨테이너일까요?

컨테이너는 환경 전반에서 이식성을 제공하고 일관성을 보장합니다. 모든 항목을 단일 패키지로 캡슐화하여 기본 인프라에서 마이크로 서비스 및 종속성을 ‘격리’합니다.

Docker 런타임 엔진을 호스트하는 모든 환경에서 컨테이너를 배포할 수 있습니다. 또한 컨테이너화된 워크로드는 프레임워크, 소프트웨어 라이브러리 및 런타임 엔진을 사용하여 각 환경을 미리 구성하는 비용을 제거합니다.

기본 운영 체제 및 호스트 리소스를 공유하면 컨테이너의 공간이 전체 가상 머신보다 훨씬 더 작습니다. 크기가 작을수록 지정된 호스트가 한 번에 실행할 수 있는 마이크로 서비스 수 또는 ‘밀도’가 증가합니다.

컨테이너 오케스트레이션

Docker와 같은 도구는 이미지를 만들고 컨테이너를 실행하는 동안 이미지를 관리하는 도구도 필요합니다. 컨테이너 관리는 컨테이너 오케스트레이터라는 특수 소프트웨어 프로그램으로 수행됩니다. 많은 독립 실행 컨테이너를 사용하여 대규모로 작동하는 경우 오케스트레이션이 필수적입니다.

그림 1-7은 컨테이너 오케스트레이터가 자동화하는 관리 작업을 보여 줍니다.

컨테이너 오케스트레이터가 수행하는 작업

그림 1-7. 컨테이너 오케스트레이터가 수행하는 작업

다음 표에서는 일반적인 오케스트레이션 작업에 대해 설명합니다.

작업 설명
일정 예약 컨테이너 인스턴스를 자동으로 프로비저닝합니다.
선호도/반선호도 컨테이너를 서로 가까이 또는 멀리 떨어진 위치에 프로비저닝하여 가용성과 성능을 지원합니다.
상태 모니터링 오류를 자동으로 검색하고 수정합니다.
장애 조치(Failover) 실패한 인스턴스를 정상 머신으로 자동으로 다시 프로비저닝합니다.
확장 수요를 충족하기 위해 컨테이너 인스턴스를 자동으로 추가하거나 제거합니다.
네트워킹 컨테이너 통신을 위한 네트워킹 오버레이를 관리합니다.
서비스 검색 컨테이너가 서로를 찾을 수 있도록 설정합니다.
롤링 업그레이드 제로 가동 중지 시간 배포로 증분 업그레이드를 조정합니다. 문제가 있는 변경 내용을 자동으로 롤백합니다.

컨테이너 오케스트레이터가 어떻게 12단계 응용삭제 가능성동시성 원칙을 수용하는지 확인합니다.

9단계는 “서비스 인스턴스를 삭제할 수 있어야 하며, 빠른 시작을 선호하여 확장성 기회를 높이고 시스템을 올바른 상태로 유지하도록 정상적인 종료를 허용해야 함”을 지정합니다. 오케스트레이터와 함께 Docker 컨테이너는 기본적으로 이 요구 사항을 충족합니다.

8단계는 “서비스가 사용 가능한 가장 강력한 머신에서 단일 대규모 인스턴스를 스케일 업하지 않고, 많은 수의 동일한 소규모 프로세스(복사본)에서 스케일 아웃됨”을 지정합니다.

여러 컨테이너 오케스트레이터가 있지만 Kubernetes는 사실상 클라우드 네이티브 세계의 표준이 되었습니다. 컨테이너화된 워크로드를 관리하기 위한 이식 가능하고 확장 가능한 오픈 소스 플랫폼입니다.

Kubernetes의 고유한 인스턴스를 호스트할 수 있지만 리소스를 프로비저닝하고 관리하는 작업은 사용자가 담당합니다. 이러한 작업은 복잡할 수 있습니다. Azure 클라우드는 Kubernetes를 관리형 서비스로 제공합니다. AKS(Azure Kubernetes Service)ARO(Azure Red Hat OpenShift)를 통해 Kubernetes를 설치하고 유지 관리할 필요 없이 해당 기능과 성능을 관리형 서비스로서 완전히 활용할 수 있습니다.

컨테이너 오케스트레이션은 클라우드 네이티브 애플리케이션 스케일링에 자세히 설명되어 있습니다.

지원 서비스

클라우드 네이티브 시스템은 데이터 저장소, 메시지 브로커, 모니터링 및 ID 서비스와 같은 다양한 보조 리소스에 의존합니다. 이러한 서비스를 지원 서비스라고 합니다.

그림 1-8에서는 클라우드 네이티브 시스템에서 사용하는 많은 일반적인 지원 서비스를 보여 줍니다.

공통 지원 서비스

그림 1-8. 공통 지원 서비스

사용자 고유의 지원 서비스를 호스트할 수 있지만 해당 리소스의 라이선스, 프로비저닝 및 관리를 담당하게 됩니다.

클라우드 공급자는 다양한 ‘관리형 백업 서비스’ 모음을 제공합니다. 서비스를 소유하는 대신 사용하면 됩니다. 클라우드 공급자는 대규모로 리소스를 운영하며 성능, 보안 및 유지 관리를 담당합니다. 모니터링, 중복성 및 가용성은 서비스에 기본 제공됩니다. 공급자는 서비스 수준 성능을 보장하고 관리형 서비스를 완벽하게 지원합니다. 즉, 티켓을 열고 문제를 해결합니다.

클라우드 네이티브 시스템은 클라우드 공급업체의 관리형 지원 서비스를 적용합니다. 시간과 작업량의 절감은 상당할 수 있습니다. 직접 호스팅하고 문제를 겪게 되는 운영 위험을 해결하는 데는 비용이 많이 들 수 있습니다.

지원 서비스를 외부 구성에 저장된 구성 정보(URL 및 자격 증명)를 사용하여 마이크로 서비스에 동적으로 바인딩된 연결된 리소스로 처리하는 것이 가장 좋습니다. 이 지침은 이 장 앞부분에서 설명한 12단계 응용에 설명되어 있습니다.

‘4단계’는 지원 서비스가 “주소 지정 가능한 URL을 통해 노출되어야 함을 지정합니다. 이렇게 하면 애플리케이션에서 리소스가 분리되며 바꿔서 사용할 수 있습니다.”

‘3단계’는 “구성 정보가 마이크로 서비스 외부로 이동하며 코드 외부의 구성 관리 도구를 통해 외부화됨”을 지정합니다.

이 패턴을 사용하면 코드 변경 없이 백업 서비스를 연결하고 분리할 수 있습니다. 마이크로 서비스를 QA에서 스테이징 환경으로 승격할 수 있습니다. 스테이징에서 지원 서비스를 가리키도록 마이크로 서비스 구성을 업데이트하고 환경 변수를 통해 설정을 컨테이너에 삽입합니다.

클라우드 공급업체는 고유한 지원 서비스와 통신하기 위한 API를 제공합니다. 이러한 라이브러리는 독점적인 배관 및 복잡성을 캡슐화합니다. 그러나 이러한 API와 직접 통신하면 코드를 해당 특정 지원 서비스와 긴밀하게 결합할 수 있습니다. 공급업체 API의 구현 세부 정보를 격리하는 것은 널리 허용되는 사례입니다. 서비스 코드에 제네릭 작업을 노출하고 내부 공급 업체 코드를 래핑하는 중간 계층 또는 중간 API를 도입합니다. 이 느슨한 결합을 사용하면 주요 서비스 코드를 변경하지 않고도 한 백업 서비스를 다른 백업 서비스와 교체하거나 코드를 다른 클라우드 환경으로 이동할 수 있습니다. 앞에서 설명한 Dapr은 미리 빌드된 빌딩 블록 집합을 사용하여 이 모델을 따릅니다.

최종적으로 지원 서비스는 이 장 앞부분에서 설명하는 12단계 응용상태 비저장 원칙도 승격합니다.

‘6단계’는 “각 마이크로 서비스가 실행 중인 다른 서비스와 격리되어 자체 프로세스에서 실행되어야 하며, 필요한 상태를 분산 캐시 또는 데이터 저장소와 같은 지원 서비스에 외부화함”을 지정합니다.

지원 서비스는 클라우드 네이티브 데이터 패턴클라우드 네이티브 통신 패턴에 설명되어 있습니다.

자동화

확인한 것처럼 클라우드 네이티브 시스템은 마이크로 서비스, 컨테이너 및 최신 시스템 디자인을 수용하여 속도와 민첩성을 달성합니다. 하지만 이는 일부에 불과합니다. 이러한 시스템이 실행되는 클라우드 환경을 어떻게 프로비저닝하나요? 앱 기능 및 업데이트를 신속하게 배포하려면 어떻게 해야 할까요? 전체적인 상황을 어떻게 설명할 수 있을까요?

Infrastructure as Code 또는 IaC의 널리 허용되는 사례를 입력합니다.

IaC를 사용하면 플랫폼 프로비저닝 및 애플리케이션 배포를 자동화할 수 있습니다. 기본적으로 DevOps 사례에 테스트 및 버전 관리와 같은 소프트웨어 엔지니어링 사례를 적용합니다. 인프라 및 배포는 자동화되고, 일관되며, 반복 가능합니다.

인프라 자동화

Azure Resource Manager, Azure Bicep, HashiCorp의 TerraformAzure CLI와 같은 도구를 사용하여 필요한 클라우드 인프라를 선언적으로 스크립팅할 수 있습니다. 리소스 이름, 위치, 용량 및 비밀은 매개 변수화되며 동적입니다. 스크립트의 버전이 지정되고 프로젝트의 아티팩트로서 소스 제어에 체크 인됩니다. 스크립트를 호출하여 QA, 스테이징 및 프로덕션과 같은 시스템 환경에서 일관되고 반복 가능한 인프라를 프로비저닝합니다.

내부적으로 IaC는 idempotent입니다. 즉, 부작용 없이 동일한 스크립트를 반복해서 실행할 수 있습니다. 팀은 변경을 수행해야 하는 경우 스크립트를 편집하고 다시 실행합니다. 업데이트된 리소스만 영향을 받습니다.

작성자 Sam Guckenheimer는 Infrastructure as Code란 무엇인가 문서에서 "IaC를 구현하는 팀이 안정적인 환경을 신속하고 대규모로 제공”할 수 있는 방법에 대해 설명합니다. 팀은 환경을 수동으로 구성하지 않고 코드를 통해 환경의 원하는 상태를 표시하여 일관성을 적용합니다. IaC를 사용한 인프라 배포는 반복 가능하며 구성 드리프트 또는 누락된 종속성으로 인한 런타임 문제를 방지합니다. DevOps 팀은 통합 사례 및 도구 집합을 함께 사용하여 애플리케이션과 지원 인프라를 신속하고 안정적으로 대규모로 제공할 수 있습니다.

배포 자동화

앞에서 설명한 12단계 응용은 완료된 코드를 실행 중인 애플리케이션으로 변환할 때 별도의 단계를 요구합니다.

5단계는 “각 릴리스는 빌드, 릴리스, 실행 스테이지마다 엄격히 구분되어야 합니다. 각각은 고유한 ID로 태그를 지정하고 롤백 기능을 지원해야 함”을 지정합니다.

최신 CI/CD 시스템은 이 원칙을 충족하는 데 도움이 될 수 있습니다. 사용자가 쉽게 사용할 수 있는 일관된 고품질 코드를 보장하는 데 도움이 되는 별도의 빌드 및 전송 단계를 제공합니다.

그림 1-9는 배포 프로세스 간의 분리를 보여 줍니다.

CI/CD 파이프라인의 배포 단계

그림 1-9. CI/CD 파이프라인의 배포 단계

이전 그림에 나오는 작업 분리에 특히 유의합니다.

  1. 개발자는 개발 환경에서 기능을 생성하여 코드, 실행 및 디버그로 이루어진 "내부 루프" 과정을 반복합니다.
  2. 완료되면 해당 코드는 GitHub, Azure DevOps 또는 BitBucket과 같은 코드 리포지토리에 ‘푸시’됩니다.
  3. 푸시는 코드를 이진 아티팩트로 변환하는 빌드 스테이지를 트리거합니다. 작업은 CI(연속 통합) 파이프라인으로 구현됩니다. 자동으로 애플리케이션을 빌드, 테스트 및 패키징합니다.
  4. 이후 릴리스 스테이지가 이진 아티팩트를 넘겨받아서 외부 애플리케이션 및 환경 구성 정보를 적용한 후 변경이 불가능한 릴리스를 생성합니다. 릴리스는 지정된 환경에 배포됩니다. 이 작업은 CD(지속적인 업데이트) 파이프라인으로 구현됩니다. 각 릴리스를 식별할 수 있어야 합니다. “이 배포는 애플리케이션의 릴리스 2.1.1을 실행하고 있습니다.”라고 말할 수 있습니다.
  5. 마지막으로, 릴리스된 기능이 대상 실행 환경에서 실행됩니다. 릴리스는 변경할 수 없습니다. 즉, 변경을 수행하면 새 릴리스가 만들어져야 합니다.

이러한 사례를 적용하여 조직은 소프트웨어를 전달하는 방법을 근본적으로 발전시켰습니다. 많은 조직들은 분기별 릴리스에서 주문형 업데이트로 전환했습니다. 목표는 개발 주기 초기에 문제를 찾아냄으로써 해결 비용을 줄이는 것입니다. 통합 간의 기간이 길어질수록 문제를 해결하는 데 더 많은 비용이 듭니다. 통합 프로세스의 일관성을 통해 팀은 코드 변경 내용을 좀 더 자주 커밋하여 협업 및 소프트웨어 품질을 높일 수 있습니다.

GitHub 및 Azure DevOps와 함께 Infrastructure as code 및 배포 자동화는 DevOps에 자세히 설명되어 있습니다.