목차
- 1. Cloud 도입배경
- 2. Cloud Native Application 이란?
- 3. Microservice Architecture(MSA)는 어떻게 설계하는가?
- 4. Cloud Native Application은 어떻게 구현해야 하는가?
- 5. Cloud Native Application에는 무엇이 필요한가?
Cloud 도입 배경
- 기업에서 비용절감과 비즈니스 민첩성이 요구
- 서비스로서의 인프라(Infrastructure as a Service, IaaS)와 서비스로서의 플랫폼(Platform as a Service, Paas) 을 도입
(참고 : Pivotal)
Cloud Native Application 이란?
- IaaS와 PaaS 서비스를 도입하고 사용하려면 Application의 설계와 구성방식의 변경이 필요.
- Cloud Native Application : 클라우드 환경에서 지원하는 IaaS 및 PaaS 서비스의 장점을 활용 할 수 있도록 잘 설계된 Application. 즉, Cloud 환경에 최적화된 Application을 말함 (Software as a Service, SasS)
- 서비스지향 아키텍처(Service-Orientrd Architecture, SOA) 의 모든 전제를 검토하여 자율적(Autonomous) 서비스 설계 원칙을 세우게 되고, 이 원칙을 어떻게 적용할지 조사한 결과, Cloud 서비스 모델에 적합한Microservice 모델이 등장
< CLOUD-NATIVE 구성요소 : 참고 Pivotal https://pivotal.io/kr/cloud-native >
Microservice
“Service-oriented architecture composed of loosely coupled elements that have bouned-contexts“
마이크로서비스(Microservice)는 소프트웨어가 잘 정의된 API를 통해 통신하는 소규모의 독립적인 서비스로 구성되어 있는 소프트웨어 개발을 위한 아키텍처 및 조직적 접근 방식입니다.
— AWS
- 작고, 한 가지 일을 잘하는 데 주력 : 단일 책임 원칙(Single-responsibility principle)의 접근 방법으로 경계 도메인 컨텍스트에서 하나의 업무만 담당하여 서비스로 구현. ==> “bounded-contexts”
- 자율성 : 다른 서비스의 기능에 영향을 주지 않으면서 개발, 배포, 운영하고 확장할 수 있음. ==> “loosely coupled elements”
(참고 : Cloud-Naitive Applications in Java)
DevOps
- 소프트웨어 전달과 인프라스트럭처 변경 프로세스 자동화를 목표로 소프트웨어 개발자와 IT 운영자가 협업한 결과물
- 좀더 신뢰성 있는 소프트웨어 생성, 테스트, 릴리즈를 신속하게 자주 진행할 수 있는 문화와 환경을 구성
- 이점 : 빠른 작업 속도, 신속한 릴리즈, 안정성, 효율성, 협업 강화
Contiuous Delivery
- Application을 변경하면 다른 변경 사항, 의존성을 고려하지 않고 준비되는 즉시 릴리즈 할 수 있는 것을 말함.
Containers
Application을 실제 구동 환경으로부터 추상화할 수 있는 논리 패키징 메커니즘으로, Application과 그 실행에 필요한 라이브러리, 바이너리, 구성 파일 등을 패키지로 묶어 배포하는 것을 말함.
개발, 테스트, 운영 환경이 변경이 되더라도 실행에 필요한 파일이 함께 움직여, 오류의 최소화가 가능
Microservice Architecture(MSA)는 어떻게 설계하는가?
- MSA : 하나의 큰 Application을 여러개의 작은 Application으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처
- Microservice Pattern : https://microservices.io/
Domain Driven Design (도메인 주도 설계)
- 정의 : 개발을 함에 있어 도메인이 중심이 되는 개발 방식을 말하며, 그 목적은 소프트웨어의 연관된 부분들을 연결하여 계속 해서 진화하는 새로운 모델을 만들어 나가 복잡한 어플리케이션을 만드는 것을 쉽게 해 주는 것.
- Microservice 설계 및 정의시 경계를 정의하는 것이 핵심. ==> bounded context
참고 : https://connect.pivotal.io/rs/625-IUJ-009/images/3_Philip_MSA1_How-to-design-MSA.pdf
Event‑Driven Architecture(이벤트 주도 아키텍처)
- 분산된 시스템 간에 이벤트를 생성, 발행하고 발행된 이벤트를 필요로하는 수신자에게 전송, 필요에 따라 처리하는 시스템 아키텍쳐
- Event Sourcing : 서비스에서 발생하는 모든 상태 변화를 순서대로 이벤트로 보관하여 처리하는 것.
- 각 서비스는 자신이 필요한 이벤트만 보고 있다가 처리하면 됨.
CQRS (Command Query Responsibility Separation)
- Command와 Query의 책임을 분리.
- Command 는 Create, Update, Delete.. Query 는 Read라 볼수 있음.
- 이벤트는 Commad(상태변경) 인 경우에만 발생 시킴.
- Event Sourcing에 의해서 생성된 최신 데이터를 Query의 개념으로 접근하여 조회 처리를 하기 때문에 로직을 간략화 하고, Cache를 통해 조회 속도를 개선 할 수 있음.
Transaction
- Microservice에서는 서비스마다 다른 데이타베이스를 사용하는 것이 일반적이고, 이를 하나의 데이터 베이스 Transaction으로 처리하는 것은 기술적으로 어려움이 있고, 긴 Transction으로 이 발생하기 때문에 효용도가 낮음.
- Compensating Operations(보상 트랜잭션)
- 예) 상품 1개 추가 서비스가 있다면 반대로 상품 1개 삭제 서비스가 있어야 한다는 것
- SAGA
- 분산 Transation 패턴 중에 가장 널리 알려진 패턴
- 각 Transaction이 단일 서비스 내의 데이터를 갱신하는 일련의 로컬 트랜잭션이다. 첫번째 Transaction이 완료되고 난 후 두번째 Transaction은 이전의 작업 완료에 의해 트리거 되는 방식
- TCC (Try-Confirm/Cancel)
- https://dzone.com/articles/transactions-for-the-rest-of-us
- 예) 여행 예매 서비스 수행시 항공권 예매 서비스와 자동차 렌트서비스를 순서대로 실행하는데, 자동차 렌트 서비스가 실패할 경우 항공권 예매를 취소하는 서비스를 수행하는 전략
Cloud Native Application은 어떻게 구현해야 하는가?
The Twelve-Factor App
- Cloud Native Application이 구현해야 하는 12가지 요소 (https://12factor.net/ko/)
코드베이스(CodeBase) | 종속성(Dependencies) | 설정(Config) |
---|---|---|
백엔드 서비스(Backing services) | 빌드, 릴리즈, 실행(Build, release, run) | 프로세스(Processes) |
포트 바인딩(Port binding) | 동시성(Concurrency) | 폐기 가능(Disposability) |
개발/프로덕션환경 일치(Dev/prod Parity) | 로그(Logs) | Admin 프로세스(Admin processes) |
코드베이스(CodeBase) 버전 관리되는 하나의 코드베이스와 다양한 배포
Application은 하나의 코드베이스가 있어야 하며, 여러 번 배포할 필요가 있는 모든 Appication은 리비전(revision)을 관리해서 추적할 수 있어야 함.
각각의 Application은 같은 코드베이스를 공유하지 않음.
Application의 다른 부분에 영향을 주지 않고도 Application을 변경하고 배포할 수 있는 유연성을 제공되어야 함.
git, subversion …..
종속성(Dependencies) 명시적으로 선언되고 분리된 종속성
- 명시적으로 코드 종속성(의존성)을 선언 해야 함
- 종속성은 jar/war 파일의 일부로 패키징됨.
- Application간의 의존성을 없애고, 동일한 jar/war 파일의 버전이 여러 개일 경우에 발생하는 부작용을 줄일 수 있음.
- Application 개발에 새로 참가하게 된 개발자가 설치를 간단하게 할 수 있다는 장점이 있음.
- 시스템 도구에 의존하지 않아야 함. 예) curl …
Spring Boot, Docker …
dependencies { ... compile group: 'commons-logging', name: 'commons-logging', version: '1.2' compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.1.1' ... }
설정(Config) 환경(environment)에 저장된 설정
- Application 설정은 배포(개발, 테스트, 운영) 마다 달라질 수 있는 모든 것들을 말함.
- Application 설정 데이터는 설정관리 도구를 이용해서 Application의 외부로 옮겨야 함.
- Application은 환경변수를 이용하여 처리를 함. (OS에 의존하지 않은 표준)
Application은 실행 중인 환경에 따라 구성 정보를 선택하므로 같은 배포 단위로 모든 환경에 전파 할 수 있음.
... env: - name: JAVA_OPTS_XMS value: "128m" - name: JAVA_OPTS_XMX value: "512m" - name: "DB_URL" valueFrom: configMapKeyRef: name: repository key: database.url ...
백엔드 서비스(Backing services) 백엔드 서비스를 연결된 리소스로 취급
- 백앤드 서비스 : 데이타베이스, 메시지 큐잉 시스템, SMTP 서비스 등…
- 모든 외부 자원과 접속접은 주소 지정이 가능한 URL 이어야 함.
- 리소스는 자유롭게 배포에 연결되거나 분리될 수 있음. (예 : 환경변수 로 주입)
빌드, 릴리즈, 실행(build, release, run) 철저하게 분리된 빌드와 실행 단계
- 빌드 단계에서 Application은 불변 개체로 빌드되고, 이 불변 개체는 환경(개발, 테스트, 스테이징, 운영)에 알맞은 구성을 선택해 프로세스를 시작함.
- Build Pipeline. (git commit to master => build => deploy)
프로세스(Processes) Application을 하나 혹은 여러개의 무상태(stateless) 프로세스로 실행
- 실행 환경에서 프로세스는 하나 이상의 프로세스로 실행이 됨.
- Application은 비공유 모델을 기반으로 구축해야함. (공유가 될 데이터는 안정된 백엔드(DB) 서비스에 저장되어야 함.)
- 즉, Application은 상태가 없고, 상태는 캐시나 데이터 저장소로 외부화해야 함.
- 완벽한 확장성을 갖추게 되고, Load Balancer나 Proxy를 사용해 Application의 어떤 인스턴스로도 요청을 보낼 수 있음.
포트 바인딩(Port binding) 포트 바인딩을 사용해서 서비스를 공개함
- 서비스는 컨테이너 안에 구축됨.
- 서비스는 완전히 독립적이며, 포트 바인딩하여 HTTP서비스로 공개되며 그 포트로 들어오는 요청을 기다림.
- 포트 바인딩을 한다는 것은 하나의 서비스가 다른 서비스를 위한 백엔드 서비스가 될 수 있다는 것.
동시성(Concurrency) 프로세스 모델을 사용한 확장
Microservice 프로세스는 Scale out을 할 수 있음.
트래픽이 증가하면 이를 처리하기 위해 더 많은 Microservice 프로세스를 환경에 추가하는 것을 의미
폐기 가능(Disposability) 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화
- Microservice를 하나의 책임만 지는 불변 개체로 구축하면 시동 시간이 빨라지고, 견고성을 극대화 할 수 있음.
- 불변성은 서비스의 폐기 가능성을 높임.
개발/프로덕션환경 일치(Dev/prod Parity) 개발, 스테이징, 프로덕션 환경을 최대한 비슷하게 유지
- Application 생명주기 전반의 환경(개발, 테스트, 스테이징, 운영)은 이후의 의도치 않은 상황을 피할 수 있게 최대한 비슷하게 유지되어야 함.
- 지속적인 배포가 가능하도록 함.
전통적인 Application Twelve-Factor App 배포 간의 간격 몇 주 몇 시간 코드 작성자와 코드 배포자 다른 사람 같은 시간 개발 환경과 production 환경 불일치함 최대한 유사함 로그(Logs) 로그를 이벤트 스트림으로 취급
- 불변성을 가진 Microservice 내부에서 서비스 처리 중에 생성된 로그는 Application 상태에 대한 단서가 됨.
- 이런 로그는 이벤트 스트림으로 처리해서 로그 수집 인프라로 보냄. (Console Log)
- 로그 파일을 작성하거나, 관리하려고 해서는 안됨.(휘발성 Processor)
Admin 프로세스(Admin processes) admin/maintenance 작업을 일회성 프로세스로 실행
- 일반적으로 Microservice 인스턴스는 종료하거나 새 버전으로 대체하지 않는 한 계속해서 실행 되는 장기 실행 프로세스임.
- 다른 모든 관리 및 운영 작업은 일회성 프로세스로 처리해야 함.
12요소의 핵심 사상
- 선언적 형식으로 설정을 자동화해서 프로젝트에 새로 참여하는 동료가 적응하는 데 필요한 시간과 비용을 최소화 한다.
- 운영체제에 구애받지 않는 투명한 구성을 통해 다양한 실행 환경에서 작동할 수 있도록 이식성을 극대화 환다.
- 현대적인 클라우드 플랫폼 기반 개발을 통해 서버와 시스템 관리에 대한 부담을 줄인다.
- 개발과 운영의 간극을 최소화해서 지속적 배포(continuous delivery) 를 가능하게 하고 Agile성을 최대화 한다.
- 도구, 아키텍처, 개발 관행을 크게 바꾸지 않아도 서비스 규모 수직적 확장이 가능하다.
Cloud Native Application에는 무엇이 필요한가?
API Gateway
- API의 접근 제어 및 트래픽 모니터링, 보안 기능 등을 제공하여 Microservice를 보호하는 유입점을 담당
- 트래픽 관리, 권한 부여 및 액세스 제어, 모니터링 및 API 버전 관리 등 최대 수십만 개의 동시 API 호출을 수신 및 처리하는 데 관계된 모든 작업을 처리
- Solution : AWS API Gateway, Azure API Management, Kong, Apigee, 3scale, Netflix Zuul, Tyk Gateway 등..
Service Discovery (Service Registry)
- Application이 Microservice 모델로 분해가 될 경우 수십, 수백, 수천개의 Microservice로 구성 될 수 있음.
- Micrcoservice의 Endpoint를 탐색하려면 질의해서 찾을 수 있는 Service Discovery가 필요.
- 동적으로 생성, 변경, 삭제되는 Service의 인스턴스 접속정보를 자동으로 등록하고 삭제하고 관리하는 기능을 담당
- Solution : Consul, Zookeeper, Neflix Eureka, Etcd 등..
Service Mesh
서비스 간 통신을 추상화하여 안전하고, 빠르고, 신뢰할 수 있게 만드는 전용 InfraStructure Layer.
추상화를 통해 복잡한 내부 네트워크를 제어하고, 추적하고, 내부 네트워크 관련 로직을 추가함으로써 안정성, 신뢰성, 탄력성, 표준화, 가시성, 보안성 등을 확보.
Service Mesh 의 구현체인 경량화 Proxy를 통해 다양한 Routing Rules, Circuit Breaker 등 공통기능을 설정할 수 있음.
Solution : Istio, Linkerd, Netflix Hystrix 등..
Config Server
- 모든 Application은 설정이 필요. (예 : DB주소, 접속정보, 연동할 Server 정보 등)
- 동일한 Application이 다양한 환경에 배포를 해야할 필요성이 있음.
- 그래서 application.properties, application.yaml 등 설정 파일 등을 통해 관리가 되었으나, 설정이 바뀔 경우 배포가 필요.
- 이러한 문제로 환경 별로 중앙에서 관리가 필요하고, API요청을 통하여 Application이 필요한 설정 정보를 Load할 수 있는 기능 제공이 필요.
- Solution : Spring Cloud Config Server, Netflix Archaius, consul 등..
Container Orchestration(Container Management)
- Microservice는 보통 컨테이너에 담겨 PasS 환경에 배포가 됨.
- 그러나 배포가능한 컨테이너 수가 증가하면서, 시스템을 원할하게, 구성, 관리, 유지하는 것이 점점 어려워짐.
- Container Orchestration은 여러 컨테이너의 배포 프로세스를 최적화 및 자동화를 하는 것을 의미함. (자동화 오케스트레이션)
- Solution : Kubernetes, Cloud Foundry Diego, Docker Swarm, Apache Mesos 등..
Monitoring
- Microservice에서는 하나의 요청에 서로 다른 시스템에서 Application이 실행되어야 하는 경우가 많음.
- 특정 이벤트 또는 어떠한 작업에 대한 오류가 발생하였을때, 어떠한 Application이 문제가 발생하였는지 파악하는 것이 중요하고, 해당 이벤트에 대한 로그 추적이 중요.
- 오류 분석을 위해서는 실행 되는 각 서비스를 추적ID로 연결해야 하고, 이 추적ID를 중앙에서 수집하여 분석하는 시스템이 필요
- Solution : Zipkin, Spring Cloud Sleuth, Netflix Atlas, Naver Pinpoint 등..
CI/CD (Continuous Integration/Continuous Delivery)
- Application의 통합 및 테스트 단계에서부터 제공 및 배포에 이르는 Application의 라이프사이클 전체에 걸쳐 지속적인 자동화와 지속적인 모니터링을 제공.
- CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포.
- CI/CD 파이프라인 : 빌드, 테스트, 데이터 마이그레이션, Application 배포, 서비스 호출 및 기타 스크립트화된 절차에 따라 대상 환경에서 코드 변경을 실행 등을 자동화 하는 것을 말함. 이러한 자동화를 통해 빈번하게 Application을 통합, 테스트, 배포 등을 제공할 수 있음.
- Solution : Gitlab CI/CD, Spinnaker. (Source 관리, Build Tool, Test, Artifact, Deploy, Monitor 등 관련 Solution 등을 통합/자동화)