클라우드 네이티브
서비스 메시란 무엇인가: 현대 플랫폼이 필요로 하는 이유
서비스 메시가 실제로 무엇을 하는지, 개발 팀에서 어떤 부담을 덜어주는지, 그리고 프록시 아키텍처가 어떻게 이를 구현하는지에 대한 실무자의 가이드.
Todea Engineering
클라우드 네이티브 실무
Kubernetes에서 마이크로서비스를 몇 개 이상 돌리고 있다면, 여러분의 개발자들은 이미 서비스 메시의 절반쯤을 다시 발명했을 가능성이 큽니다. 모든 HTTP 클라이언트에 박혀 있는 재시도·타임아웃 로직. CronJob과 스크립트로 간신히 묶어 놓은 인증서 로테이션. 베어러 토큰으로 임기응변으로 만든 서비스 간 인증. 리포지토리마다 흩어져 있는 라이브러리 버전, 언어별 관용구, 그리고 "나중에 고치자" 상태로 남아 있는 설정들.
모든 팀이 같은 문제를 조금씩 다른 방식으로 풀고 있습니다. 서비스 메시는 이런 관심사를 애플리케이션 코드에서 들어내어 플랫폼 팀이 소유하는 인프라로 옮깁니다.
개발자가 떠맡지 않아야 할 책임
모놀리스를 마이크로서비스로 쪼개면, 이전에 프로세스 안에서 일어나던 모든 것 — 오류 처리, 재시도, 타임아웃, 인증, 메트릭 — 도 함께 쪼개집니다. 메시가 없으면, 모든 팀이 같은 패턴을 각자의 언어 관용구로, 대개 잘못 설정된 채로, 일관성 없이 다시 만들게 됩니다:
- 재시도와 타임아웃 로직이 모든 HTTP 클라이언트에, 흔히 잘못 설정된 채로
- TLS 인증서 관리가 헤더로 공유 비밀을 돌리는 형태로
- 서비스 간 인증이 API 토큰으로 임시방편으로
- 분산 트레이싱 계측이 엔드포인트마다 수작업으로 추가된 형태로
- 서킷 브레이커가 미묘한 차이를 둔 채 서비스 간에 복사되는 형태로
- 로드 밸런싱과 재시도 예산이 애플리케이션 코드 전반에 흩어져 있는 형태로
- 네트워크 정책이 아무도 건드리려 하지 않는 IP 허용 목록으로 표현된 채로
이것을 모든 서비스, 출시하는 모든 언어, 그리고 그것을 유지하는 모든 팀에 곱해 보세요. 비용은 막대하고, 일관성은 낮으며, 신뢰성도 그만큼 떨어집니다.
서비스 메시는 이러한 관심사를 개발자에게서 덜어냅니다:
개발자는 비즈니스 로직을 씁니다. 메시가 횡단적 배관을 담당합니다.
작동 방식: 프록시 아키텍처
모든 서비스 메시는 같은 두 가지 컴포넌트 위에 세워져 있습니다:
- 데이터 플레인: 서비스 간 트래픽의 모든 바이트를 가로채고, mTLS를 처리하고, 정책을 적용하는 네트워크 프록시.
- 컨트롤 플레인: 이 프록시들을 구성하고, 워크로드 ID를 발급하며, 텔레메트리를 집계하는 컨트롤러.
메시마다 다른 지점은 바로 프록시가 어디서 실행되는가입니다. 주류는 두 가지 모델입니다.
사이드카 프록시
사이드카 모델에서는 프록시가 모든 애플리케이션 Pod 안에 추가 컨테이너로 실행됩니다. Linkerd는 기본적으로 이렇게 동작하며, 고전적인 Istio도 마찬가지입니다. Pod 시작 시, init 컨테이너 또는 CNI 플러그인이 iptables 규칙을 설치하여 Pod의 인바운드와 아웃바운드 TCP 트래픽을 투명하게 사이드카로 리다이렉트합니다.
서비스 A가 b.default.svc.cluster.local을 호출하면, A의 애플리케이션 컨테이너는 그저 Kubernetes Service로 평범한 HTTP 호출을 보낼 뿐입니다. iptables 리다이렉트가 그 호출을 A의 사이드카로 흘려보내고, 사이드카가 mTLS, 재시도, 타임아웃, 라우팅을 처리한 다음 요청을 B의 사이드카로 전달합니다. B의 사이드카는 인가 정책을 적용하고, 메트릭을 기록하며, 루프백으로 B에 전달합니다.
사이드카 없는 아키텍처
주요 진영은 다음과 같습니다:
-
Istio ambient 모드는 L4 터널(
ztunnel)을 노드당 하나씩 DaemonSet으로 띄워, 해당 노드의 모든 로컬 Pod에 대한 mTLS를 처리합니다. L7 기능(HTTP 라우팅, 경로 기반 인가 등)은 선택적 waypoint 프록시를 네임스페이스별로 배포하는 방식으로 얹어 제공됩니다. L7 비용은 실제로 필요한 자리에만 치르게 됩니다. -
Cilium Service Mesh는 L4 mTLS와 정책을 Linux 커널 내부의 eBPF로 밀어 넣고, L7 관심사는 노드당 Envoy를 돌려 처리합니다.
트레이드오프가 뒤집힙니다: Pod당 오버헤드가 없고, Pod 시작이 빠르며, 워크로드당 움직이는 부품도 적습니다 — 그러나 공유 프록시라는 말은 곧 같은 노드 위 워크로드들 사이로 테넌시 관심사가 새어 나온다는 뜻이며, 특정 서비스의 트래픽을 디버깅하려면 노드 단위 컴포넌트를 따라가며 추론해야 한다는 뜻이기도 합니다.
애플리케이션 관점에서는 두 모델이 동일해 보입니다: Kubernetes Service로 평범한 HTTP 호출을 보내는 것뿐입니다. 운영자 관점에서는 애플리케이션 코드를 한 줄도 바꾸지 않고, 트래픽의 모든 바이트가 인증되고, 암호화되고, 관찰 가능해지며, 정책으로 통제 가능해집니다.
플랫폼 수준에서 얻는 것
제대로 배포된 서비스 메시는 애플리케이션 변경 없이 다음을 제공합니다:
- 모든 서비스 간 상호 TLS: 인증서 발급, 로테이션, 폐기는 메시가 처리합니다. 앱 팀의 리포지토리에 PKI 코드가 들어가지 않습니다.
- 워크로드 ID: IP 주소나 공유 비밀이 아니라 암호 인증서에 기반합니다. 제로 트러스트 네트워킹의 토대입니다.
- 트래픽 관리: 재시도, 타임아웃, 서킷 브레이킹, 카나리 릴리스 — 모두 설정으로 선언됩니다.
- 분산 트레이싱: 모든 요청에 트레이스 ID가 자동으로 전파됩니다.
- 일관된 메트릭: 요청률, 오류율, p50/p95/p99 지연 — 계측 작업 없이 모든 서비스에 대해.
- 멀티 클러스터 서비스 디스커버리: 클러스터 A의 서비스가 클러스터 B의 서비스를 이웃처럼 호출할 수 있습니다.
흔한 함정
서비스 메시 도입은 예측 가능한 방식으로 실패합니다:
- 스위치처럼 다루기. 설치를 결승선으로 여기는 것. 메시를 돌리는 것까지는 쉬운 부분입니다. 진짜 투자가 필요한 지점은 그다음입니다 — 운영하고, 트러스트 앵커를 로테이션하고, 요청 경로상의 프록시 이슈를 디버깅하고, 업그레이드에 발맞추고, 클러스터가 커짐에 따라 리소스 제한을 조정하는 일. 처음부터 예산을 잡아두지 않으면 메시는 선반용 소프트웨어가 됩니다.
- 적합성 대신 기능으로 선택하기. Istio, Linkerd, Consul, Cilium Service Mesh는 운영 프로파일이 서로 크게 다릅니다. 팀이 세 명이라면 기능 목록이 가장 긴 메시가 정답이 아닙니다 — 실제로 운영 표면을 감당할 수 있는 메시를 고르세요.
- 관찰성 작업 건너뛰기. 서비스 메시는 엄청난 텔레메트리를 만들어냅니다. 대시보드와 SLO가 없으면 그 데이터는 쓸모가 없습니다.