마이크로서비스 아키텍처의 진화
아키텍처 패턴으로서 마이크로서비스는 복잡한 시스템을 수십에서 수백 개의 작은 서비스로 분할하며, 각 서비스는 독립적인 비즈니스 로직을 구현합니다. 이러한 작은 서비스는 소규모 소프트웨어 엔지니어링 팀이 이해하고 수정하기 쉽고, 언어 및 프레임워크 선택의 유연성을 제공하며, 애플리케이션 개발 및 출시 시간을 단축하고, 다양한 워크로드 및 리소스 요구 사항에 따라 서비스를 독립적으로 확장/축소할 수 있는 이점을 제공합니다.
반면에 애플리케이션이 여러 마이크로서비스 프로세스로 분할되면 프로세스 내 메서드 호출이 프로세스 간 원격 호출로 변경됩니다. 이는 수많은 서비스의 연결, 관리 및 모니터링의 복잡성을 야기합니다.
이러한 변화는 분산 시스템의 일련의 문제를 야기합니다. 예를 들어:
- 서비스 제공자를 어떻게 찾을 것인가?
- 원격 메서드 호출의 신뢰성을 어떻게 보장할 것인가?
- 서비스 호출의 보안을 어떻게 보장할 것인가?
- 서비스 호출의 지연 시간을 어떻게 줄일 것인가?
- 엔드 투 엔드 디버깅을 어떻게 수행할 것인가?
또한, 프로덕션 배포에서 마이크로서비스 인스턴스는 운영의 어려움을 증가시킵니다. 예를 들어:
- 수많은 마이크로서비스의 성능 지표를 수집하여 분석하는 방법은?
- 온라인 비즈니스에 영향을 주지 않고 마이크로서비스를 업그레이드하는 방법은?
- 마이크로서비스 클러스터 배포의 내결함성 및 안정성을 테스트하는 방법은?
이러한 문제는 수백, 수천 개의 서비스 통신, 관리, 배포, 버전, 보안, 장애 조치, 정책 실행, 원격 측정 및 모니터링과 관련되어 있으며, 마이크로서비스 아키텍처가 도입한 이러한 문제를 해결하는 것은 쉽지 않습니다.
마이크로서비스 아키텍처의 발전 과정을 되짚어 봅시다. 서비스 메시가 등장하기 전에는 서비스 검색, 회로 차단, 재시도, 타임아웃, 암호화, 속도 제한 등 서비스 간 통신 로직을 마이크로서비스 애플리케이션 내에서 처리했습니다.
분산 시스템에서 이 부분의 로직은 비교적 복잡합니다. 마이크로서비스 애플리케이션에 안정적이고 신뢰할 수 있는 인프라 계층을 제공하고, 중복 작업을 피하며, 오류 발생 가능성을 줄이기 위해 일반적으로 서비스 통신을 담당하는 이 부분의 로직을 추상화하고 일반화하여 각 마이크로서비스 애플리케이션에서 사용할 수 있는 코드 라이브러리를 형성합니다. 아래 그림과 같습니다.
공통 코드 라이브러리는 애플리케이션 개발 및 유지 관리 작업을 줄이고, 애플리케이션 개발자가 마이크로서비스 통신 로직을 개별적으로 구현할 때 발생하는 오류 가능성을 줄이지만, 다음과 같은 문제가 여전히 존재합니다.
- 마이크로서비스 통신 로직은 애플리케이션 개발자에게 투명하지 않으며, 애플리케이션 개발자는 코드 라이브러리를 이해하고 올바르게 사용해야 하므로 비즈니스 로직에만 집중할 수 없습니다.
- 다른 언어/프레임워크에 대해 다른 코드 라이브러리를 개발해야 하므로, 마이크로서비스 애플리케이션 개발 언어 및 프레임워크 선택에 영향을 미치고 기술 선택의 유연성에 영향을 미칩니다.
- 시간이 지남에 따라 코드 라이브러리는 다른 버전을 가질 수 있으며, 다른 버전의 코드 라이브러리 호환성 및 대규모 실행 환경에서 마이크로서비스 업그레이드는 어려운 문제가 될 것입니다.
마이크로서비스 간의 통신 인프라 계층을 TCP/IP 프로토콜 스택과 비교할 수 있습니다. TCP/IP 프로토콜 스택은 운영 체제의 모든 애플리케이션에 기본 통신 서비스를 제공하지만, TCP/IP 프로토콜 스택과 애플리케이션 간에는 긴밀한 결합 관계가 없습니다. 애플리케이션은 TCP/IP 프로토콜이 제공하는 하위 통신 기능만 사용하면 되며, IP가 어떻게 라우팅되는지, TCP가 어떻게 연결을 생성하는지 등 TCP/IP 프로토콜의 구현에는 관심이 없습니다.
마찬가지로 마이크로서비스 애플리케이션도 서비스 검색, 로드 밸런싱, 재시도, 회로 차단기 등 마이크로서비스 간 통신의 하위 세부 사항에 관심을 가질 필요가 없습니다. 마이크로서비스에 통신 서비스를 제공하는 이 부분의 로직을 애플리케이션 프로세스에서 추출하여 별도의 프로세스로 배포하고, 이를 서비스 간 통신 프록시로 사용하면 아래 그림과 같은 아키텍처를 얻을 수 있습니다.
통신 프록시 프로세스가 애플리케이션 프로세스와 함께 배포되므로, 이러한 배포 방식을 “사이드카”(즉, 삼륜 오토바이의 사이드카)라고 부릅니다.
애플리케이션 간의 모든 트래픽은 프록시를 거쳐야 합니다. 프록시가 사이드카 방식으로 애플리케이션과 동일한 호스트에 배포되므로, 애플리케이션과 프록시 간의 통신은 신뢰할 수 있다고 간주할 수 있습니다. 프록시는 대상 서비스를 찾고 통신의 신뢰성 및 보안 문제를 담당합니다.
서비스가 대규모로 배포될 때, 서비스와 함께 배포된 사이드카 프록시 간의 연결은 아래 그림과 같은 메시를 형성하며, 이 메시는 마이크로서비스 통신 인프라 계층이 되어 마이크로서비스 간의 모든 트래픽을 전달하며, 이를 서비스 메시(Service Mesh)라고 부릅니다.

서비스 메시는 서비스 간 통신을 처리하는 인프라 계층입니다. 클라우드 네이티브 애플리케이션은 복잡한 서비스 토폴로지를 가지며, 서비스 메시는 이러한 토폴로지에서 요청이 안정적으로 이동할 수 있도록 보장합니다. 실제 애플리케이션에서 서비스 메시는 일반적으로 일련의 경량 네트워크 프록시로 구성되며, 이들은 애플리케이션과 함께 배포되지만 애플리케이션은 이들의 존재를 알 필요가 없습니다.
_William Morgan WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?
서비스 메시에는 수많은 사이드카 프록시가 있으며, 각 프록시를 개별적으로 설정하면 작업량이 매우 커집니다. 서비스 메시의 프록시를 보다 편리하게 통합하여 중앙에서 제어하기 위해 서비스 메시 위에 제어 평면 구성 요소가 추가되었습니다.

여기서 우리는 SDN의 개념을 유추할 수 있습니다. 제어 평면은 SDN 네트워크 관리의 컨트롤러와 유사하며, 라우팅 정책 지정 및 라우팅 규칙 배포를 담당합니다. 데이터 평면은 SDN 네트워크의 스위치와 유사하며, 데이터 패킷 전달을 담당합니다.
마이크로서비스의 모든 통신은 서비스 메시 인프라 계층에서 제공되므로, 제어 평면과 데이터 평면의 협력을 통해 이러한 통신을 모니터링, 관리 및 제어하여 마이크로서비스 카나리 배포, 분산 추적 호출, 장애 주입 시뮬레이션 테스트, 동적 라우팅 규칙, 마이크로서비스 폐쇄 루프 제어 등과 같은 관리 기능을 구현할 수 있습니다.
Istio 서비스 메시
Istio는 서비스 메시 오픈 소스 프로젝트로, Google이 Kubernetes에 이어 또 다른 역작으로, 주요 참여 기업은 Google, IBM, Lyft입니다.
Kubernetes의 훌륭한 아키텍처 설계와 강력한 확장성을 바탕으로 Google은 Kubernetes를 중심으로 생태계를 구축했습니다. Kubernetes는 마이크로서비스 오케스트레이션에 사용됩니다(오케스트레이션은 영어 Orchestration의 직역으로, 쉽게 말해 일련의 마이크로서비스 간의 연관 관계를 설명하고 마이크로서비스의 배포, 종료, 업그레이드, 확장/축소 등을 담당합니다). 아래로는 CNI(컨테이너 네트워크 인터페이스), CRI(컨테이너 런타임 인터페이스) 표준 인터페이스를 통해 다양한 네트워크 및 컨테이너 런타임 구현과 연결되어 마이크로서비스 실행을 위한 인프라를 제공합니다. 위로는 Istio를 통해 마이크로서비스 거버넌스 기능을 제공합니다.
아래 그림에서 볼 수 있듯이, Istio는 Kubernetes 생태계의 중요한 부분을 보완하며, Google의 마이크로서비스 영역에서 이정표적인 확장입니다.
Google은 Istio의 힘을 빌려 마이크로서비스 거버넌스의 사실상 표준을 추진하고 있으며, 이는 Google 자체 제품인 Google Cloud에 매우 중요한 의미를 가집니다. Redhat, Pivotal, Nginx, Buoyant 등 다른 클라우드 서비스 공급업체들도 이러한 추세를 보고 자사 제품과 Istio를 통합하여 뒤처지지 않고 시장 기회를 놓치지 않기 위해 적극적으로 참여하고 있습니다.
가까운 미래에 클라우드 네이티브 애플리케이션의 경우, 서비스 배포 및 클러스터 관리에 Kubernetes를 사용하고, 서비스 통신 및 거버넌스에 Istio를 사용하는 것이 마이크로서비스 애플리케이션의 표준 구성이 될 것으로 예상됩니다.
Istio 서비스는 데이터 평면과 제어 평면의 두 부분으로 구성됩니다.
- 데이터 평면은 지능형 프록시(Envoy) 세트로 구성되며, 프록시는 사이드카로 배포되어 마이크로서비스 간의 모든 네트워크 통신을 중재하고 제어합니다.
- 제어 평면은 트래픽 라우팅을 위해 프록시를 관리하고 구성하며, 런타임에 정책을 실행합니다.

Istio 제어 평면
Istio 제어 평면은 Pilot, Mixer, Istio-Auth의 세 가지 구성 요소로 이루어져 있습니다.
Pilot
Pilot은 메시 내 서비스의 표준 모델을 유지 관리하며, 이 표준 모델은 다양한 하위 플랫폼과 독립적입니다. Pilot은 어댑터를 통해 각 하위 플랫폼과 연결하여 이 표준 모델을 채웁니다.
예를 들어, Pilot의 Kubernetes 어댑터는 Kubernetes API 서버를 통해 Kubernetes의 Pod 등록 정보 변경, Ingress 리소스 및 트래픽 관리 규칙 저장 등의 정보를 얻은 다음, 이 데이터를 표준 모델로 변환하여 Pilot이 사용하도록 제공합니다. 어댑터 패턴을 통해 Pilot은 Mesos, Cloud Foundry, Consul에서도 서비스 정보를 가져올 수 있으며, 다른 서비스 검색 구성 요소를 Pilot에 통합하기 위한 어댑터를 개발할 수도 있습니다.
이 외에도 Pilot은 데이터 평면과 통신하기 위한 표준 API 세트를 정의했습니다. 이 API가 제공하는 인터페이스 내용은 서비스 검색, 로드 밸런싱 풀 및 라우팅 테이블의 동적 업데이트를 포함합니다. 이 표준 API를 통해 제어 평면과 데이터 평면이 분리되어 설계가 단순화되고 플랫폼 간 이식성이 향상되었습니다. 이 표준 API를 기반으로 이미 여러 사이드카 프록시와 Istio의 통합이 구현되었으며, Istio가 현재 통합한 Envoy 외에도 Linkerd, Nginmesh 등 타사 통신 프록시와 통합할 수 있으며, 이 API를 기반으로 자체 사이드카 구현을 작성할 수도 있습니다.
Pilot은 또한 DSL(Domain Specific Language) 언어 세트를 정의했습니다. DSL 언어는 운영자가 이해하고 사용할 수 있는 비즈니스 지향적인 고수준 추상화를 제공합니다. 운영자는 이 DSL을 사용하여 트래픽 규칙을 정의하고 Pilot에 배포하며, 이 규칙은 Pilot에 의해 데이터 평면 구성으로 변환된 다음 표준 API를 통해 Envoy 인스턴스에 배포되어 런타임에 마이크로서비스 트래픽을 제어하고 조정할 수 있습니다.

Mixer
마이크로서비스 애플리케이션에서는 일반적으로 비즈니스 기능을 지원하기 위해 일부 기본 백엔드 공통 서비스를 배포해야 합니다. 이러한 인프라에는 액세스 제어, 할당량 관리와 같은 정책 유형과 APM, 로그와 같은 원격 측정 보고서가 포함됩니다. 마이크로서비스 애플리케이션과 이러한 백엔드 지원 시스템은 일반적으로 직접 통합되어 있어 애플리케이션과 인프라 간의 긴밀한 결합을 초래합니다. 운영상의 이유로 인프라를 업그레이드하거나 변경해야 하는 경우, 각 마이크로서비스의 애플리케이션 코드를 수정해야 하며, 그 반대도 마찬가지입니다.
이 문제를 해결하기 위해 Mixer는 애플리케이션 코드와 인프라 백엔드 사이에 일반적인 중간 계층을 도입했습니다. 이 중간 계층은 애플리케이션과 백엔드 인프라를 분리하여, 애플리케이션 코드가 특정 백엔드와 통합되는 대신 Mixer와 비교적 간단하게 통합되도록 하고, Mixer가 백엔드 시스템과의 연결을 담당합니다.
Mixer는 주로 세 가지 핵심 기능을 제공합니다.
- 사전 조건 확인. 서비스 소비자의 들어오는 요청에 응답하기 전에 일부 사전 조건을 확인할 수 있도록 합니다. 사전 조건에는 서비스 소비자가 올바르게 인증되었는지, 서비스의 화이트리스트에 있는지, ACL 검사를 통과했는지 등이 포함될 수 있습니다.
- 할당량 관리. 서비스가 여러 차원에서 할당량을 할당하고 해제할 수 있도록 합니다. 할당량이라는 간단한 리소스 관리 도구는 서비스 소비자가 제한된 리소스에 대해 경쟁할 때 상대적으로 공정한 (경쟁 수단)을 제공할 수 있습니다. 속도 제한(Rate Limiting)은 할당량의 한 예입니다.
- 원격 측정 보고. 서비스가 로그 및 모니터링을 보고할 수 있도록 합니다. 미래에는 서비스 운영자 및 서비스 소비자를 위한 추적 및 청구 흐름도 활성화될 것입니다.
Mixer의 아키텍처는 다음과 같습니다.

먼저, 사이드카는 요청 경로, 시간, 원본 IP, 대상 서비스, 트레이싱 헤더, 로그 등 각 요청에서 관련 정보를 수집하고 이러한 속성을 Mixer에 보고합니다. Mixer와 백엔드 서비스는 어댑터를 통해 연결되며, Mixer는 사이드카가 보고한 내용을 어댑터를 통해 백엔드 서비스로 전송합니다.
사이드카는 Mixer와만 연결되고 백엔드 서비스와는 결합되지 않으므로, Mixer 어댑터 메커니즘을 사용하여 애플리케이션 코드를 수정할 필요 없이 다양한 백엔드 서비스를 연결할 수 있습니다. 예를 들어, 다른 Mixer 어댑터를 통해 메트릭을 Prometheus 또는 InfluxDB로 수집할 수 있으며, 애플리케이션 서비스를 중단하지 않고도 백엔드 서비스를 동적으로 전환할 수도 있습니다.
둘째, 사이드카는 각 요청을 처리할 때 Mixer를 통해 정책 판단을 수행하고, Mixer가 반환하는 결과에 따라 해당 호출을 계속 처리할지 여부를 결정합니다. 이러한 방식으로 Mixer는 정책 결정을 애플리케이션 계층에서 제거하여 운영자가 런타임에 정책을 구성하고 애플리케이션의 동작을 동적으로 제어할 수 있도록 하여 정책 제어의 유연성을 높입니다. 예를 들어, 각 마이크로서비스 애플리케이션의 액세스 화이트리스트, 다른 클라이언트의 속도 제한 등을 구성할 수 있습니다.
논리적으로 마이크로서비스 간의 모든 요청 호출은 두 번의 Mixer 처리를 거칩니다. 호출 전에 정책 판단을 수행하고, 호출 후에 원격 측정 데이터를 수집합니다. Istio는 Mixer 처리가 Envoy의 전달 효율성에 영향을 미치지 않도록 일부 메커니즘을 사용합니다.
위 그림에서 볼 수 있듯이, Istio는 Envoy에 Mixer 필터를 추가했습니다. 이 필터는 제어 평면의 Mixer 구성 요소와 통신하여 정책 제어 및 원격 측정 데이터 수집 기능을 수행합니다. Mixer 필터에는 정책 판단에 필요한 데이터 캐시가 저장되어 있으므로, 대부분의 정책 판단은 Envoy에서 처리되며 Mixer로 요청을 보낼 필요가 없습니다. 또한, Envoy가 수집한 원격 측정 데이터는 먼저 Envoy의 캐시에 저장된 다음, 일정 시간마다 일괄 방식으로 Mixer에 보고됩니다.
Auth
Istio는 엔드 투 엔드 보안 솔루션을 제공하기 위해 양방향 SSL 인증(Mutual SSL Authentication)과 역할 기반 접근 제어(RBAC)를 지원합니다.
인증
Istio는 내부 CA(인증 기관)를 제공하며, 이 CA는 각 서비스에 인증서를 발급하여 서비스 간 양방향 SSL 인증을 제공하고 통신 암호화를 수행합니다. 그 아키텍처는 아래 그림과 같습니다.

작동 메커니즘은 다음과 같습니다. 배포 시:
- CA는 Kubernetes API 서버를 감시하고, 클러스터의 각 서비스 계정에 대해 한 쌍의 키와 인증서를 생성하여 Kubernetes API 서버로 전송합니다. 여기서 각 서비스에 대해 하나의 인증서를 생성하는 것이 아니라, 각 서비스 계정에 대해 하나의 인증서를 생성한다는 점에 유의하십시오. 서비스 계정과 Kubernetes에 배포된 서비스는 일대다 관계일 수 있습니다. 서비스 계정은 인증서의 SAN(Subject Alternative Name) 필드에 저장됩니다.
- Pod가 생성될 때, Kubernetes는 해당 Pod와 연결된 서비스 계정에 따라 키와 인증서를 Kubernetes Secrets 리소스 형태로 Pod의 Volume으로 로드하여 Envoy가 사용할 수 있도록 합니다.
- Pilot은 Envoy가 사용할 키 및 인증서 정보와 어떤 서비스 계정이 어떤 서비스를 실행할 수 있는지 등 데이터 평면 구성을 생성하여 Envoy에 배포합니다.
참고: 가상 머신 환경의 경우, Node Agent가 키를 생성하고 Istio CA에 인증서를 요청한 다음, 인증서를 Envoy에 전달합니다.
런타임 시:
- 서비스 클라이언트의 아웃바운드 요청은 Envoy에 의해 가로채집니다.
- 클라이언트의 Envoy와 서버의 Envoy는 양방향 SSL 핸드셰이크를 시작합니다. 핸드셰이크 단계에서 클라이언트 Envoy는 서버 Envoy 인증서의 서비스 계정이 해당 요청 서비스를 실행할 권한이 있는지 확인합니다. 권한이 없으면 서버를 신뢰할 수 없다고 판단하여 연결을 생성할 수 없습니다.
- 암호화된 TSL 연결이 생성되면 요청 데이터는 서버의 Envoy로 전송된 다음, Envoy를 통해 로컬 TCP 연결을 통해 서비스로 전송됩니다.
권한 부여
Istio의 “역할 기반 접근 제어”(RBAC)는 네임스페이스, 서비스, 메서드의 세 가지 다른 세분화된 서비스 접근 권한 제어를 제공합니다. 그 아키텍처는 아래 그림과 같습니다.

관리자는 접근 제어 보안 정책을 사용자 정의할 수 있으며, 이러한 보안 정책은 Istio Config Store에 저장됩니다. Istio RBAC Engine은 Config Store에서 보안 정책을 가져와 보안 정책에 따라 클라이언트가 시작한 요청을 판단하고 권한 부여 결과(허용 또는 금지)를 반환합니다.
Istio RBAC Engine은 현재 Mixer Adapter로 구현되어 있으므로, Mixer를 통해 전달된 컨텍스트에서 접근 요청자의 신원(Subject)과 작업 요청(Action)을 가져올 수 있으며, Mixer를 통해 접근 요청에 대한 정책 제어를 수행하여 특정 요청을 허용하거나 금지할 수 있습니다.
Istio Policy에는 두 가지 기본 개념이 포함됩니다.
ServiceRole: 역할을 정의하고, 해당 역할에 메시 내 서비스에 대한 접근 권한을 지정합니다. 역할 접근 권한을 지정할 때 네임스페이스, 서비스, 메서드의 다른 세분화된 수준에서 설정할 수 있습니다.
ServiceRoleBinding: 역할을 Subject에 바인딩합니다. Subject는 사용자, 사용자 그룹 또는 서비스일 수 있습니다.
Istio 데이터 평면
Istio 데이터 평면은 “사이드카” 방식으로 마이크로서비스와 함께 배포되어 마이크로서비스에 안전하고 빠르며 신뢰할 수 있는 서비스 간 통신을 제공합니다. Istio의 제어 평면과 데이터 평면은 표준 인터페이스를 통해 상호 작용하므로 데이터는 다양한 구현을 가질 수 있으며, Istio는 기본적으로 Envoy 프록시의 확장 버전을 사용합니다.
Envoy는 C++로 개발된 고성능 프록시로, 서비스 메시 내의 모든 서비스의 모든 인바운드 및 아웃바운드 트래픽을 중재합니다. Envoy의 많은 내장 기능은 Istio에 의해 확장되었으며, 예를 들어 동적 서비스 검색, 로드 밸런싱, TLS 암호화, HTTP/2 & gRPC 프록시, 회로 차단기, 라우팅 규칙, 장애 주입 및 원격 측정 등이 있습니다.
Istio 데이터 평면이 지원하는 기능은 다음과 같습니다.
| 아웃바운드 기능 | 인바운드 기능 |
|---|---|
| 서비스 인증 | 서비스 인증 |
| 로드 밸런싱 | 권한 부여 |
| 재시도 및 회로 차단기 | 속도 제한 |
| 세분화된 라우팅 | 로드 쉐딩 |
| 원격 측정 | 원격 측정 |
| 요청 추적 | 요청 추적 |
| 장애 주입 | 장애 주입 |
참고: 아웃바운드 기능은 서비스 요청 측의 사이드카가 제공하는 기능을 의미하며, 인바운드 기능은 서비스 제공 측 사이드카가 제공하는 기능을 의미합니다. 원격 측정 및 분산 추적과 같은 일부 기능은 양쪽 사이드카 모두에서 지원해야 합니다. 반면, 권한 부여는 서비스 제공 측에서만 제공하면 되고, 재시도는 요청 측에서만 제공하면 되는 등 일부 기능은 한쪽에서만 제공하면 됩니다.
일반적인 적용 시나리오
Istio 서비스 관리는 다음과 같은 일반적인 적용 시나리오를 포함합니다.
분산 호출 추적
마이크로서비스 아키텍처에서 비즈니스 호출 체인은 매우 복잡하며, 사용자로부터의 하나의 요청이 수십 개의 서비스의 협업 처리를 포함할 수 있습니다. 따라서 추적 시스템은 전체 호출 체인에서 동일한 요청과 관련된 이벤트를 기록하고 분석하여 개발 및 운영 담당자가 시스템 병목 현상을 분석하고, 예외를 신속하게 찾아내며, 호출 체인을 최적화하는 데 도움을 줍니다.
Istio는 Envoy 프록시에서 호출 관련 데이터를 수집하여 애플리케이션에 침투하지 않는 분산 호출 추적 분석을 구현합니다. Istio가 분산 호출 추적을 구현하는 원리는 아래 그림과 같습니다.
Envoy는 엔드 투 엔드 호출의 각 세그먼트 데이터를 수집하고, 이러한 호출 추적 정보를 Mixer로 전송합니다. Mixer Adapter는 추적 정보를 해당 서비스 백엔드로 전송하여 처리합니다. 전체 호출 추적 정보 생성 프로세스는 애플리케이션 개입이 필요 없으므로, 분산 추적 관련 코드를 애플리케이션에 주입할 필요가 없습니다.
참고: 애플리케이션은 여전히 아웃바운드 호출을 수행할 때 수신된 인바운드 요청의 추적 관련 헤더를 전달하여 호출 체인의 다음 사이드카가 처리할 수 있도록 해야 합니다.
측정 항목 수집
Istio가 측정 항목을 수집하는 원리는 아래 그림과 같습니다.

Envoy는 요청 서비스, HTTP 상태 코드, 호출 지연 시간 등 지표 관련 원시 데이터를 수집하며, 이렇게 수집된 지표 데이터는 Mixer로 전송되어 Mixer Adapters를 통해 변환된 후 백엔드 모니터링 시스템으로 전송됩니다. Mixer는 플러그인 메커니즘을 사용하므로, 백엔드 모니터링 시스템은 필요에 따라 런타임에 동적으로 전환될 수 있습니다.
카나리 배포
애플리케이션이 출시된 후, 운영팀이 직면하는 큰 과제 중 하나는 이미 출시된 서비스에 영향을 주지 않고 업그레이드를 수행하는 방법입니다. 아무리 완벽한 테스트를 거쳤더라도 오프라인 테스트에서 모든 잠재적 오류를 발견할 수는 없습니다. 버전 업그레이드 오류를 100% 피할 수 없는 상황에서는 제어 가능한 버전 배포 방식을 통해 오류의 영향을 허용 가능한 범위 내로 제어하고 빠르게 롤백할 수 있어야 합니다.
카나리 배포(또는 카나리 릴리스)를 통해 기존 버전에서 새 버전으로 비즈니스를 원활하게 전환하고, 업그레이드 과정에서 발생할 수 있는 문제가 사용자에게 미치는 영향을 방지할 수 있습니다.
Istio는 높은 추상화와 훌륭한 설계를 통해 일관된 방식으로 카나리 배포를 구현했습니다. 새 버전이 출시된 후, 운영자는 라우팅 규칙을 사용자 정의하여 특정 트래픽(예: 지정된 특성을 가진 테스트 사용자)을 새 버전 서비스로 유입시켜 테스트할 수 있습니다. 새 버전으로 점진적으로 제어된 방식으로 프로덕션 트래픽을 유입함으로써, 업그레이드 중 발생하는 오류가 사용자에게 미치는 영향을 최소화할 수 있습니다.
Istio를 사용한 카나리 배포 프로세스는 아래 그림과 같습니다.
먼저, 새 버전의 서비스를 배포하고 라우팅 규칙을 통해 카나리 사용자의 트래픽을 새 버전 서비스로 유입시킵니다.

테스트가 안정화되면 라우팅 규칙을 사용하여 프로덕션 트래픽을 새 버전 시스템으로 점진적으로 유입시킵니다(예: 5%, 10%, 50%, 80% 순으로 점진적 유입).

새 버전이 정상적으로 작동하면 마지막으로 모든 트래픽을 새 버전 서비스로 유입시키고 이전 버전 서비스를 중단합니다. 만약 중간에 문제가 발생하면 트래픽을 이전 버전으로 다시 유입시키고, 새 버전에서 오류를 수정한 후 이 프로세스를 사용하여 다시 배포할 수 있습니다.

회로 차단기
마이크로서비스 아키텍처에는 수많은 서비스 단위가 존재하며, 하나의 서비스에 장애가 발생하면 의존성으로 인해 장애가 확산되어 결국 전체 시스템이 마비될 수 있습니다. 이러한 아키텍처는 기존 아키텍처보다 불안정합니다. 이러한 문제를 해결하기 위해 회로 차단기 패턴이 등장했습니다.
회로 차단기 패턴은 특정 서비스에 장애가 발생했을 때, 회로 차단기의 장애 모니터링이 호출자에게 오랜 시간 기다리게 하는 대신 즉각적인 오류 응답을 반환하는 것을 의미합니다. 이렇게 하면 호출 스레드가 장애 호출로 인해 오랫동안 점유되지 않아 전체 시스템으로 장애가 확산되는 것을 방지할 수 있습니다.
Istio가 회로 차단기를 구현하는 원리는 아래 그림과 같습니다.
관리자는 대상 정책을 통해 회로 차단 트리거 조건, 회로 차단 시간 등의 매개변수를 설정합니다. 예를 들어, 서비스 B에서 10번의 5XX 오류가 발생하면 15분 동안 회로 차단되도록 설정할 수 있습니다. 그러면 서비스 B의 특정 인스턴스가 회로 차단 조건을 충족하면 15분 동안 LB 풀에서 제거됩니다. 이 기간 동안 Envoy는 더 이상 클라이언트 요청을 해당 서비스 인스턴스로 전달하지 않습니다.
Istio의 회로 차단기는 최대 연결 수, 최대 대기 요청 수, 최대 요청 수, 연결당 최대 요청 수, 재시도 횟수 등과 같은 매개변수 구성도 지원합니다. 설정된 최대 요청 수에 도달하면 새로 시작된 요청은 Envoy에 의해 직접 거부됩니다.

장애 주입
대규모 마이크로서비스 애플리케이션의 경우 시스템의 견고성이 매우 중요합니다. 마이크로서비스 시스템에는 수많은 서비스 인스턴스가 존재하며, 일부 서비스 인스턴스에 문제가 발생하더라도 마이크로서비스 애플리케이션은 재시도, 회로 차단, 자가 치유 등의 수단을 통해 높은 내결함성을 가져야 하며, 시스템이 외부로 정상적인 서비스를 계속 제공할 수 있도록 보장해야 합니다. 따라서 애플리케이션을 프로덕션 시스템에 배포하기 전에 시스템에 대한 충분한 견고성 테스트를 수행해야 합니다.
마이크로서비스 애플리케이션에 대한 견고성 테스트의 가장 큰 어려움 중 하나는 시스템 장애를 시뮬레이션하는 방법입니다. 수백, 수천 개의 마이크로서비스가 배포된 테스트 환경에서 애플리케이션, 호스트 또는 스위치를 설정하여 마이크로서비스 간의 통신 장애를 시뮬레이션하는 것은 매우 어렵습니다.
Istio는 서비스 메시를 통해 마이크로서비스 간의 통신 트래픽을 전달하므로, 메시 내에서 규칙을 통해 장애를 주입하여 일부 마이크로서비스에 장애가 발생한 상황을 시뮬레이션하고 전체 애플리케이션의 견고성을 테스트할 수 있습니다.
장애 주입의 원리는 아래 그림과 같습니다.
테스터는 Pilot을 통해 Envoy에 규칙을 주입하여 서비스 MS-B로 향하는 요청에 지정된 시간 지연을 추가했습니다. 클라이언트 요청이 MSB-B로 전송될 때, Envoy는 이 규칙에 따라 해당 요청에 지연을 추가하여 클라이언트 요청 시간 초과를 유발합니다. 규칙을 설정하여 장애를 주입하는 방식으로 테스터는 마이크로서비스 간의 다양한 통신 장애를 쉽게 시뮬레이션하고 마이크로서비스 애플리케이션의 견고성을 비교적 완벽하게 시뮬레이션 테스트할 수 있습니다.
요약
서비스 메시는 마이크로서비스에 애플리케이션에 투명한 안전하고 신뢰할 수 있는 통신 인프라 계층을 제공합니다. 서비스 메시를 채택하면 마이크로서비스 애플리케이션 개발자는 비즈니스 영역 문제 해결에 집중하고, 일부 일반적인 문제는 서비스 메시가 처리하도록 맡길 수 있습니다. 서비스 메시를 채택하면 코드 라이브러리로 인한 의존성을 피할 수 있으며, 마이크로서비스의 이기종 이점을 최대한 활용하여 개발 팀이 비즈니스 요구 사항 및 개발자 역량에 따라 기술 스택을 자유롭게 선택할 수 있습니다.
Istio는 훌륭한 아키텍처 설계를 가지고 있으며, 강력한 2차 개발 확장성과 사용자 정의 기능을 제공합니다. Istio는 현재 베타 단계에 있지만, 이미 많은 유명 회사와 제품의 지원을 받고 있으며, 매우 유망한 오픈 소스 서비스 메시 프로젝트입니다.
