편집자 – 이 7부작 시리즈 기사는 이제 완료되었습니다.
NGINX Plus를 사용하여 마이크로서비스를 구현하는 것에 대한 정보와 더불어 전체 문서 세트를 전자책으로 다운로드할 수도 있습니다. – 마이크로서비스: 설계부터 배포까지 . 그리고 마이크로서비스 참조 아키텍처 와 마이크로서비스 솔루션 페이지 에 대한 시리즈를 확인하세요.
이 글은 마이크로서비스로 애플리케이션을 구축하는 것에 대한 시리즈의 여섯 번째 기사입니다. 첫 번째 기사 에서는 마이크로서비스 아키텍처 패턴을 소개하고 마이크로서비스를 사용하는 것의 이점과 단점에 대해 설명합니다. 다음 문서에서는 API 게이트웨이 사용 , 프로세스 간 통신 , 서비스 검색 , 이벤트 기반 데이터 관리 등 마이크로서비스 아키텍처의 다양한 측면에 대해 설명합니다. 이 글에서는 마이크로서비스를 배포하기 위한 전략을 살펴보겠습니다.
모노리식 애플리케이션을 배포한다는 것은 대개 규모가 큰 단일 애플리케이션의 여러 개의 동일한 사본을 실행하는 것을 의미합니다. 일반적으로 N개의 서버(물리적 또는 가상)를 프로비저닝하고 각 서버에서 M개의 애플리케이션 인스턴스를 실행합니다. 모놀리식 애플리케이션을 배포하는 것은 항상 간단한 일은 아니지만 마이크로서비스 애플리케이션을 배포하는 것보다는 훨씬 간단합니다.
마이크로서비스 애플리케이션은 수십 개, 심지어 수백 개의 서비스로 구성됩니다. 서비스는 다양한 언어와 프레임워크로 작성됩니다. 각각은 고유한 배포, 리소스, 확장 및 모니터링 요구 사항을 갖춘 미니 애플리케이션입니다. 예를 들어, 해당 서비스에 대한 수요에 따라 각 서비스의 특정 수의 인스턴스를 실행해야 합니다. 또한 각 서비스 인스턴스에는 적절한 CPU, 메모리, I/O 리소스가 제공되어야 합니다. 더욱 어려운 점은 이러한 복잡성에도 불구하고 서비스를 배포하는 것은 빠르고 안정적이며 비용 효율적이어야 한다는 것입니다.
마이크로서비스 배포 패턴에는 몇 가지가 있습니다. 먼저 호스트당 여러 서비스 인스턴스 패턴을 살펴보겠습니다.
마이크로서비스를 배포하는 한 가지 방법은 호스트당 여러 서비스 인스턴스 패턴을 사용하는 것입니다. 이 패턴을 사용하면 하나 이상의 물리적 호스트나 가상 호스트를 프로비저닝하고 각 호스트에서 여러 서비스 인스턴스를 실행합니다. 여러 면에서 이는 애플리케이션 배포에 대한 전통적인 접근 방식입니다. 각 서비스 인스턴스는 하나 이상의 호스트의 잘 알려진 포트에서 실행됩니다. 호스트 머신은 일반적으로 애완동물처럼 다루어집니다 .
다음 다이어그램은 이 패턴의 구조를 보여줍니다.
이 패턴에는 몇 가지 변형이 있습니다. 한 가지 변형은 각 서비스 인스턴스가 프로세스나 프로세스 그룹이 되는 것입니다. 예를 들어, Apache Tomcat 서버에 Java 서비스 인스턴스를 웹 애플리케이션으로 배포할 수 있습니다. Node.js 서비스 인스턴스는 부모 프로세스와 하나 이상의 자식 프로세스로 구성될 수 있습니다.
이 패턴의 또 다른 변형은 동일한 프로세스 또는 프로세스 그룹에서 여러 서비스 인스턴스를 실행하는 것입니다. 예를 들어, 동일한 Apache Tomcat 서버에 여러 Java 웹 애플리케이션을 배포하거나 동일한 OSGI 컨테이너에서 여러 OSGI 번들을 실행할 수 있습니다.
호스트당 여러 서비스 인스턴스 패턴에는 이점과 단점이 모두 있습니다. 가장 큰 장점 중 하나는 리소스 사용이 비교적 효율적이라는 것입니다. 여러 서비스 인스턴스가 서버와 운영 체제를 공유합니다. 프로세스나 프로세스 그룹이 여러 서비스 인스턴스(예: 동일한 Apache Tomcat 서버와 JVM을 공유하는 여러 웹 애플리케이션)를 실행하는 경우 더욱 효율적입니다.
이 패턴의 또 다른 장점은 서비스 인스턴스를 배포하는 것이 비교적 빠르다는 것입니다. 서비스를 호스트에 복사하고 시작하기만 하면 됩니다. 서비스가 Java로 작성된 경우 JAR 또는 WAR 파일을 복사합니다. Node.js나 Ruby 등 다른 언어의 경우 소스 코드를 복사합니다. 어느 경우든 네트워크를 통해 복사되는 바이트 수는 비교적 적습니다.
또한, 오버헤드가 없기 때문에 서비스를 시작하는 속도가 보통 매우 빠릅니다. 서비스가 별도의 프로세스인 경우, 그냥 시작하면 됩니다. 그렇지 않고, 서비스가 동일한 컨테이너 프로세스나 프로세스 그룹에서 실행되는 여러 인스턴스 중 하나인 경우, 서비스를 컨테이너에 동적으로 배포하거나 컨테이너를 다시 시작합니다.
그 매력에도 불구하고 호스트당 여러 서비스 인스턴스 패턴에는 몇 가지 심각한 단점이 있습니다. 가장 큰 단점은 각 서비스 인스턴스가 별도의 프로세스가 아닌 한 서비스 인스턴스의 격리가 거의 없거나 전혀 없다는 것입니다. 각 서비스 인스턴스의 리소스 사용률을 정확하게 모니터링할 수 있지만 각 인스턴스가 사용하는 리소스를 제한할 수는 없습니다. 잘못 작동하는 서비스 인스턴스가 호스트의 모든 메모리나 CPU를 소모할 수 있습니다.
동일한 프로세스에서 여러 서비스 인스턴스가 실행되는 경우에는 격리가 전혀 이루어지지 않습니다. 예를 들어 모든 인스턴스가 동일한 JVM 힙을 공유할 수 있습니다. 서비스 인스턴스가 제대로 작동하지 않으면 동일한 프로세스에서 실행되는 다른 서비스가 쉽게 중단될 수 있습니다. 더욱이 각 서비스 인스턴스에서 사용되는 리소스를 모니터링할 방법이 없습니다.
이 접근 방식의 또 다른 심각한 문제는 서비스를 배포하는 운영 팀이 해당 서비스를 수행하는 방법에 대한 구체적인 세부 사항을 알아야 한다는 것입니다. 서비스는 다양한 언어와 프레임워크로 작성될 수 있으므로 개발팀이 운영팀과 공유해야 할 세부 정보가 많습니다. 이러한 복잡성으로 인해 배포 중에 오류가 발생할 위험이 커집니다.
보시다시피, 익숙한 패턴임에도 불구하고 호스트당 여러 서비스 인스턴스 패턴에는 몇 가지 심각한 단점이 있습니다. 이제 이러한 문제를 피하면서 마이크로서비스를 배포하는 다른 방법을 살펴보겠습니다.
마이크로서비스를 배포하는 또 다른 방법은 호스트당 서비스 인스턴스 패턴입니다. 이 패턴을 사용하면 각 서비스 인스턴스를 별도의 호스트에서 격리하여 실행합니다. 이 패턴에는 두 가지 다른 전문 분야가 있습니다. 가상 머신당 서비스 인스턴스 및 컨테이너당 서비스 인스턴스.
가상 머신당 서비스 인스턴스 패턴을 사용하면 각 서비스를 Amazon EC2 AMI 와 같은 가상 머신(VM) 이미지로 패키징합니다. 각 서비스 인스턴스는 해당 VM 이미지를 사용하여 시작되는 VM(예: EC2 인스턴스)입니다. 다음 다이어그램은 이 패턴의 구조를 보여줍니다.
이는 Netflix가 비디오 스트리밍 서비스를 배포하는 데 사용하는 기본 접근 방식입니다. Netflix는 Aminator를 사용하여 각 서비스를 EC2 AMI로 패키징합니다. 실행 중인 각 서비스 인스턴스는 EC2 인스턴스입니다.
다양한 도구를 사용하여 자체 VM을 빌드할 수 있습니다. CI(Continuous Integration) 서버(예: Jenkins )를 구성하여 Aminator를 호출하여 서비스를 EC2 AMI로 패키징할 수 있습니다. Packer.io는 자동화된 VM 이미지 생성을 위한 또 다른 옵션입니다. Aminator와 달리 EC2, DigitalOcean, VirtualBox, VMware 등 다양한 가상화 기술을 지원합니다.
Boxfuse라는 회사는 아래에서 설명할 VM의 단점을 극복하는 VM 이미지를 구축하는 매력적인 방법을 보유하고 있습니다. Boxfuse는 Java 애플리케이션을 최소한의 VM 이미지로 패키징합니다. 이러한 이미지는 빠르게 구축되고 부팅이 빠르며, 노출되는 공격 영역이 제한되어 있어 보안성이 더 뛰어납니다.
CloudNative라는 회사는 EC2 AMI를 만드는 SaaS 제품인 Bakery를 보유하고 있습니다. 마이크로서비스에 대한 테스트를 통과한 후 CI 서버가 Bakery를 호출하도록 구성할 수 있습니다. 그런 다음 The Bakery는 귀하의 서비스를 AMI로 패키징합니다. The Bakery와 같은 SaaS 오퍼링을 사용하면 AMI 생성 인프라를 설정하는 데 귀중한 시간을 낭비할 필요가 없습니다.
가상 머신당 서비스 인스턴스 패턴에는 여러 가지 이점이 있습니다. VM의 가장 큰 이점은 각 서비스 인스턴스가 완전히 격리되어 실행된다는 것입니다. 고정된 양의 CPU와 메모리를 갖고 있어 다른 서비스에서 리소스를 훔칠 수 없습니다.
마이크로서비스를 VM으로 배포하는 또 다른 이점은 성숙한 클라우드 인프라를 활용할 수 있다는 것입니다. AWS와 같은 클라우드는 부하 분산 및 자동 크기 조정과 같은 유용한 기능을 제공합니다.
서비스를 VM으로 배포하는 또 다른 큰 이점은 서비스 구현 기술을 캡슐화한다는 것입니다. 서비스가 VM으로 패키징되면 블랙박스가 됩니다. VM 관리 API는 서비스를 배포하기 위한 API가 됩니다. 배포가 훨씬 간단해지고 안정성이 높아집니다.
그러나 가상 머신 패턴당 서비스 인스턴스에는 몇 가지 단점이 있습니다. 한 가지 단점은 자원 활용의 효율성이 떨어진다는 것이다. 각 서비스 인스턴스에는 운영 체제를 포함한 전체 VM의 오버헤드가 있습니다. 게다가 일반적인 퍼블릭 IaaS에서 VM은 고정된 크기로 제공되고 VM이 활용도가 낮을 가능성이 있습니다.
Moveover의 경우, 공용 IaaS는 일반적으로 VM이 바쁘든 유휴 상태든 관계없이 요금을 청구합니다. AWS와 같은 IaaS는 자동 확장 기능을 제공하지만 수요 변화에 신속하게 대응하기 어렵 습니다. 그 결과, VM을 과도하게 프로비저닝해야 하는 경우가 많아 배포 비용이 증가합니다.
이러한 접근 방식의 또 다른 단점은 서비스의 새로운 버전을 배포하는 것이 일반적으로 느리다는 것입니다. VM 이미지는 일반적으로 크기가 커서 빌드 속도가 느립니다. 또한 VM은 그 크기로 인해 인스턴스화 속도가 일반적으로 느립니다. 또한, 운영 체제를 시작하는 데는 일반적으로 어느 정도 시간이 걸립니다. 하지만 Boxfuse가 구축한 것과 같은 가벼운 VM도 존재하기 때문에 이것이 보편적으로 사실은 아니라는 점에 유의하세요.
가상 머신 패턴당 서비스 인스턴스의 또 다른 단점은 일반적으로 귀하(또는 조직 내의 다른 사람)가 차별화되지 않은 많은 힘든 작업을 담당한다는 것입니다. Boxfuse와 같이 VM을 빌드하고 관리하는 오버헤드를 처리하는 도구를 사용하지 않는 한, 이는 사용자의 책임입니다. 필요하지만 시간이 많이 걸리는 이 활동은 핵심 사업에 집중력을 빼앗아갑니다.
이제 더 가볍지만 VM의 많은 이점을 여전히 제공하는 마이크로서비스를 배포하는 대체 방법을 살펴보겠습니다.
컨테이너당 서비스 인스턴스 패턴을 사용하면 각 서비스 인스턴스가 자체 컨테이너에서 실행됩니다. 컨테이너는 운영 체제 수준에서 가상화되는 메커니즘 입니다. 컨테이너는 샌드박스에서 실행되는 하나 이상의 프로세스로 구성됩니다. 프로세스 관점에서 보면, 각 프로세스는 자신만의 포트 네임스페이스와 루트 파일 시스템을 갖습니다. 컨테이너의 메모리와 CPU 리소스를 제한할 수 있습니다. 일부 컨테이너 구현에는 I/O 속도 제한도 있습니다. 컨테이너 기술의 예로는 Docker 와 Solaris Zones가 있습니다.
다음 다이어그램은 이 패턴의 구조를 보여줍니다.
이 패턴을 사용하려면 서비스를 컨테이너 이미지로 패키징해야 합니다. 컨테이너 이미지는 서비스를 실행하는 데 필요한 애플리케이션과 라이브러리로 구성된 파일 시스템 이미지입니다. 일부 컨테이너 이미지는 완전한 Linux 루트 파일 시스템으로 구성됩니다. 더 가벼운 것도 있습니다. 예를 들어 Java 서비스를 배포하려면 Java 런타임, Apache Tomcat 서버 및 컴파일된 Java 애플리케이션이 포함된 컨테이너 이미지를 빌드합니다.
서비스를 컨테이너 이미지로 패키징한 후 하나 이상의 컨테이너를 실행합니다. 일반적으로 각 물리적 호스트나 가상 호스트에서 여러 개의 컨테이너를 실행합니다. Kubernetes 나 Marathon 과 같은 클러스터 관리자를 사용하여 컨테이너를 관리할 수 있습니다. 클러스터 관리자는 호스트를 리소스 풀로 처리합니다. 컨테이너에 필요한 리소스와 각 호스트에서 사용 가능한 리소스를 토대로 각 컨테이너를 어디에 배치할지 결정합니다.
컨테이너당 서비스 인스턴스 패턴에는 이점과 단점이 모두 있습니다. 컨테이너의 이점은 VM의 이점과 유사합니다. 컨테이너는 서비스 인스턴스를 서로 분리합니다. 각 컨테이너에서 소비되는 리소스를 쉽게 모니터링할 수 있습니다. 또한 VM과 마찬가지로 컨테이너는 서비스를 구현하는 데 사용되는 기술을 캡슐화합니다. 컨테이너 관리 API는 서비스를 관리하는 API 역할도 합니다.
그러나 VM과 달리 컨테이너는 가벼운 기술입니다. 컨테이너 이미지는 일반적으로 매우 빠르게 구축됩니다. 예를 들어, 내 노트북에서는 Spring Boot 애플리케이션을 Docker 컨테이너로 패키징하는 데 불과 5초가 걸립니다. 또한 컨테이너는 OS 부팅 메커니즘이 길지 않기 때문에 매우 빠르게 시작됩니다. 컨테이너가 시작되면 서비스가 실행됩니다.
컨테이너를 사용하는 데는 몇 가지 단점이 있습니다. 컨테이너 인프라는 빠르게 성숙하고 있지만 VM 인프라만큼 성숙하지는 않습니다. 또한 컨테이너는 호스트 OS의 커널을 서로 공유하기 때문에 VM만큼 안전하지 않습니다.
컨테이너의 또 다른 단점은 컨테이너 이미지를 관리하는 차별화되지 않은 힘든 작업을 직접 해야 한다는 것입니다. 또한 Google Container Engine 이나 Amazon EC2 Container Service (ECS)와 같은 호스팅 컨테이너 솔루션을 사용하지 않는 한, 컨테이너 인프라와 컨테이너가 실행되는 VM 인프라를 직접 관리해야 합니다.
또한 컨테이너는 종종 VM당 가격이 책정되는 인프라에 배포됩니다. 따라서 앞서 설명한 대로 부하 급증을 처리하기 위해 VM을 과도하게 프로비저닝하는 데 추가 비용이 발생할 가능성이 높습니다.
흥미로운 점은 컨테이너와 VM의 구분이 모호해질 가능성이 높다는 것입니다. 앞서 언급했듯이 Boxfuse VM은 빠르게 빌드하고 시작할 수 있습니다. Clear Containers 프로젝트는 가벼운 VM을 만드는 것을 목표로 합니다. [편집자 - 2017년 12월에 발표된 대로 Clear Containers 개발은 현재 오픈 소스 Kata Containers 프로젝트에서 계속되고 있습니다.] unikernels 에 대한 관심도 커지고 있습니다. Docker, Inc.는 최근 Unikernel Systems를 인수했습니다.
또한 컨테이너 또는 VM에서 서비스를 배포하는 것 중에서 선택해야 하는 문제를 회피하는 접근 방식인 서버리스 배포라는 새롭고 점점 더 인기 있는 개념도 있습니다. 다음에 살펴보겠습니다.
AWS Lambda 는 서버리스 배포 기술의 한 예입니다. Java, Node.js, Python 서비스를 지원합니다. 마이크로서비스를 배포하려면 ZIP 파일로 패키징하여 AWS Lambda에 업로드합니다. 또한, 요청(이벤트라고도 함)을 처리하기 위해 호출되는 함수의 이름을 지정하는 메타데이터도 제공합니다. AWS Lambda는 요청을 처리하기에 충분한 마이크로서비스 인스턴스를 자동으로 실행합니다. 각 요청에 대해 소요된 시간과 사용된 메모리 양에 따라 요금이 청구됩니다. 물론, 중요한 것은 세부 사항에 있으며 AWS Lambda에도 한계가 있다는 사실을 곧 알게 될 것입니다. 하지만 개발자나 조직의 어느 누구도 서버, 가상 머신 또는 컨테이너의 어떤 측면에 대해서도 걱정할 필요가 없다는 개념은 매우 매력적입니다.
람다 함수 는 상태 비저장 서비스입니다. 일반적으로 AWS 서비스를 호출하여 요청을 처리합니다. 예를 들어, S3 버킷에 이미지가 업로드될 때 호출되는 Lambda 함수는 DynamoDB 이미지 테이블에 항목을 삽입하고 Kinesis 스트림에 메시지를 게시하여 이미지 처리를 트리거할 수 있습니다. Lambda 함수는 타사 웹 서비스를 호출할 수도 있습니다.
Lambda 함수를 호출하는 방법은 네 가지가 있습니다.
cron
과 같은 일정에 따라보시다시피 AWS Lambda는 마이크로서비스를 배포하는 편리한 방법입니다. 요청 기반 가격 책정은 귀하의 서비스가 실제로 수행하는 작업에 대해서만 비용을 지불한다는 것을 의미합니다. 또한, IT 인프라에 대한 책임을 지지 않으므로 애플리케이션 개발에 집중할 수 있습니다.
그러나 몇 가지 중요한 한계도 있습니다. 타사 메시지 브로커에서 메시지를 사용하는 서비스 등 장기 실행 서비스를 배포하는 데 사용하도록 의도된 것이 아닙니다. 요청은 300초 이내에 완료되어야 합니다. 이론적으로 AWS Lambda는 각 요청에 대해 별도의 인스턴스를 실행할 수 있으므로 서비스는 상태 비저장이어야 합니다. 지원되는 언어 중 하나로 작성해야 합니다. 서비스는 신속하게 시작되어야 합니다. 그렇지 않으면 시간 초과되어 종료될 수 있습니다.
마이크로서비스 애플리케이션을 배포하는 것은 어려운 일입니다. 다양한 언어와 프레임워크로 작성된 수십, 심지어 수백 개의 서비스가 있습니다. 각각은 고유한 배포, 리소스, 확장 및 모니터링 요구 사항을 갖춘 미니 애플리케이션입니다. 가상 머신당 서비스 인스턴스, 컨테이너당 서비스 인스턴스 등을 포함하여 여러 가지 마이크로서비스 배포 패턴이 있습니다. 마이크로서비스를 배포하는 데 있어 또 다른 흥미로운 옵션은 서버리스 방식인 AWS Lambda입니다. 이 시리즈의 다음이자 마지막 부분에서는 모놀리식 애플리케이션을 마이크로서비스 아키텍처로 마이그레이션하는 방법을 살펴보겠습니다.
편집자 – 이 7부작 시리즈 기사는 이제 완료되었습니다.
NGINX Plus를 사용하여 마이크로서비스를 구현하는 것에 대한 정보와 더불어 전체 문서 세트를 전자책으로 다운로드할 수도 있습니다. – 마이크로서비스: 설계부터 배포까지 . 그리고 마이크로서비스 참조 아키텍처 와 마이크로서비스 솔루션 페이지 에 대한 시리즈를 확인하세요.
게스트 블로거 크리스 리처드슨은 Amazon EC2를 위한 초기 Java PaaS(서비스형 플랫폼)인 CloudFoundry.com 의 창립자입니다. 그는 현재 기업들과 협의해 애플리케이션을 개발하고 배포하는 방식을 개선하기 위해 노력하고 있습니다. 그는 또한 https://microservices.io 에서 마이크로서비스에 관해 정기적으로 블로그를 운영하고 있습니다.
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."