0. 이 글을 쓰는 이유
MSA에 대해 잘 몰라서 개념이라도 알아가기 위해 정리하기 위함
이 글은 모두 아래 영상들에서 나온 내용으로 영상을 보는 것을 추천합니다.
https://www.youtube.com/watch?v=8d4h7K_Fq-0
https://youtu.be/UsdB03LgqAM?feature=shared
1. MSA란?
Micro Service Architecture의 약자로
서비스를 비즈니스 경계에 맞게 세분화하고 서비스 간 통신은 네트워크 호출을 통해 진행하여 확장 가능하고 회복적이며 유연한 어플리케이션을 구성하는 아키텍처
2. 기존 Monolithic 방법론에 어떠한 문제점이 있길래?
여러 기능이 뭉쳐 Coupling과 Dependency가 강해 아래와 같은 문제점들이 발생한다.
- 소프트웨어의 모든 구성요소가 한 프로젝트에 합쳐져 있어 큰 변화에 대응이 어렵다.
- 새로운 기능 추가 및 업데이트 어렵다.
- 특정 부분 문제시 시스템 전체에 장애가 발생 가능하다.
- 여러 역할을 하는 시스템이 하나의 서버에 올라가서 Scale-out시 필요 없는 자원도 함께 증가한다.
3. MSA의 장점에 대해 한마디로 요약해 본다면?
민첩하고 손쉬운 배포 및 업데이트가 가능해진다.
다만 마틴 파울러 아저씨의 명언이 있다.
"Moholith로 관리하기가 너무 복잡한 게 아니라면 MSA를 고려하지 말 것"
4. MSA를 구성하는 주요 Component
- Config Managament
- 서비스의 재빌드/재부팅 없이 설정사항을 반영한다.(Netflix Archaius, K8S ConfigMap)
- Service Discovery
- MSA기반 서비스 배포 시 서비스 검색 및 등록(Netflix Eureka, K8S Service, Istio)
- API Management
- 클라이언트 접근 요청을 일원화(Netflix zuul, K8S Ingress)
- 접근 요청에 대한 일원화란 클라이언트가 외부에서 여러 서비스에 접근하는 것에 대해 외부 접근을 관리하고 통합하는 방법을 의미한다.
- 클라이언트 접근 요청을 일원화(Netflix zuul, K8S Ingress)
- Cetralized Logging
- 서비스별 로그의 중앙집중화(ELK Stack)
- Distributed Tracing
- 마이크로서비스 간의 호출 추적(Spring Cloud Sleuth, Zipkin)
- Centralized Monitoring
- 서비스별 메트릭 정보의 중앙집중화(Netflix Spectator, Heapster)
- Resilience & Fault Tolerance
- MSA구조에서 하나의 실패한 서비스가 체인에 연결된 전체 서비스들에 파급 효과를 발생시키지 않도록 하기 위한 계단식 실패 방지 구조(Netflix Hystrix, K8S Health Check)
- Auto-Scaling & Self-Healing
- 자동 스케일링, 복구 자동화를 통한 서비스 관리 효율화
5. 그래서 MSA를 구현하기 위한 기반 기술들은?
마이크로 서비스 간 통신을 위해 각 서비스를 식별(Discovery)하고 경로를 파악(Routing)하며, 로드밸런싱(Load-Balancing)을 하고 전체 서비스의 장애 전파를 차단(Circuit Break)하며 Telemetry와 통합되어 로깅, 모니터링, 트레이싱 기능을 담당하는 Service Mesh에 대한 이해도가 필요하다.
6. Service Mesh의 3가지 기능
결국 Service Mesh란 애플리케이션의 다양한 부분들이 서로 데이터를 공유하는 방식을 제어하는 방법이다. 각 서비스 간 통신을 추상화하여 안전하고, 빠르고, 신뢰할 수 있게 만드는 것이 주요 기능이다.
- Connect
- Routing을 제어하여 서비스/엔드포인트 간의 트래픽과 API흐름을 제어한다.
- Secure
- 서비스 간의 안전한 통신 제공
- 커뮤니케이션을 허용하거나 거부하는 정책을 적용 가능
- Monitor
- K8S의 경우 Prometheus 및 Jaeger와 같이 시각화도구들과 즉시 통합되므로 서비스, 트래픽 흐름, API 지연 시간 및 추적 간의 종속성을 발견하고 시각화 가능
7. Service Mesh 적용 시 고려사항
- 복잡성
- 서비스 메쉬를 사용하면 런타임 인스턴스 수가 증가한다.
- 사이드카 컨테이너(컨테이너 독립적으로 붙이는 컨테이너) 수 증가
- 각 서비스는 서비스 메쉬의 사이드카 프록시를 통해 호출되므로 개별 프록시 수가 증가하게 된다. 이에 따른 부하로 서비스 운영에 문제가 발생할 가능성이 있는지에 대한 아키텍처 구조 측면에서 사전에 검토해야 한다.
- 기술력의 미성숙
- 빠르게 발전하고 있으나 아직은 새롭고 미성숙한 기술에 속한다. 또한 많은 기업이 서비스 메쉬에 대한 경험이 없는 실정이다.
8. 어째서 K8S를 많이 사용하는가
오픈소스로 되어있고 MSA구성에 필요한 컴포넌트들을 제공할 뿐만 아니라 많은 기업들이 K8S를 채택하며 많은 레퍼런스를 지니고 있어 사실상 MSA를 구현하는 표준이 되어가고 있다.
9. K8S의 Component
Pod
- K8S에서 생성하고 관리할 수 있는 배포가능한 가장 작은 단위
- 하나 이상의 실행 컨테이너를 포함하는 개념
- 일반적으로 밀접하게 연결된 Application이 올라간 컨테이너들을 Pod로 묶어서 배포
- Deployment 혹은 Job과 같은 워크로드를 이용하여 생성
- Application Container, Storage Resource, 고유 네트워크 ID 및 기타 구성을 캡슐화
- Pod생성 시 휘발성 성질을 가진 IP를 자동으로 할당
Object and Controller
- Object
- 쿠버네티스에서 말하는 기본 실행 단위이다.
- Controller
- 오브젝트를 생성하고 관리하는 객체이다.
- Replication Controller, ReplicaSet, Deployment등의 기능이 존재한다.
Service
크게 3가지 기능이 있다.
- ClusterIP
- Service의 ClusterIP를 통해 유동적으로 생성되고 사라지는 Pod에 접근하기 위한 방법으로 사용
- Cluster의 Service CIDR중 지정된 IP로 생성 가능
- CIDR이란?
- 쉽게 이해하려면 IP의 범위를 지정하는 것이다.
- CIDR이란?
- NodePort
- LB
일반적으로 Pod자체를 외부에 노출시키지 않는다. Pod는 어떠한 이유에 있어서 중지가 되고 생성되고 삭제되는 일이 빈번하게 발생할 수 있고 Pod은 한번 죽으면 해당 Pod에 부여된 IP도 변경되어 Pod간의 IP통신은 권장되지 않는다. 그래서 LB역할을 하는 Service객체를 Pod앞에 배치해서 외부에서 들어오는 Pod를 Routing하기도 하고(라고 했는데 자연스러운 표현은 외부에서 들어오는 Request를 Routing한다 가 더 자연스러운 표현이 아닐까 싶다.) 정상 운영 중인 Pod에 대한 Traffic Routing을 한다.
ConfigMap
컨테이너에 들어갈 Application의 설정 값을 외부에서 제어할 수 있도록 도와주는 Object다.
Key:Value 값으로 선언한다.
일반적인 정보는 ConfigMap으로 생성하지만 민감한 기밀 정보(인증키, 패스워드 등)는 Secret으로 생성한다.
컨테이너에서 두 Object(ConfigMap, Secret)값을 가져와 사용하면 컨테이너 내부 코드를 변경할 필요가 없다.
두 Object(ConfigMap, Secret)를 적절히 이용하면 개발/운영 환경에서 동일한 컨테이너 이미지 활용이 가능하다.
3가지 방식이 존재한다.
- Literal
- ConfigMap과 Secret에 직접 상수 값을 입력
- Secret Value값의 경우 Base64 인코딩이 되어있는 값을 넣어야 함
- File
- file을 만들어 그 값으로 ConfigMap과 Secret을 생성한다.
- file 이름이 key, file의 내용이 value가 된다.(file이름:file내용 = key:value)
- File 방식의 경우 Base64인코딩을 자동으로 지원해 주기 때문에 따로 인코딩 된 값을 넣을 필요가 없다.
- K8S노드에서 kubectl 명령어로 직접 생성해야한다.(https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/)
- Volume Mount
- Pod생성 시 Container에 mount경로를 지정하여 해당 위치에 ConfigMap과 Secret을 마운트 하여 사용
- ConfigMap과 Secret의 Value가 중간에 변경되면 변경된 값이 자동으로 반영된다.
Monitoring
Object에서 정의한 개수 대로 Pod를 복제/관리하는 Object다.
ReplicaSet을 단독으로 사용할 수 있으나 주로 Deployment의 spec으로 정의하는 것을 권장한다.
관리해야 하는 pod를 식별하기 위한 selector, 유지해야 하는 pod의 개수, pod template을 포함한다.
- Host
- 노드에 대한 지표 모니터링에 해당(노드의 CPU, Memory, Disk, Network usage등이 여기에 해당)
- Container
- Container의 CPU, Memory, Disk, Network Usage등을 관리
- Application
- Container에서 구동되는 개별 어플리케이션 지표를 모니터링
- K8S
- 컨테이너를 컨트롤하는 K8S자체에 대한 모니터링. 쿠버네티스의 자원인 서비스나 pod, 계정정보가 해당한다.