Theme:

마이크로서비스가 수십 개로 늘어나면 서비스 간 통신에서 재시도, 타임아웃, 인증, 관찰을 서비스마다 직접 구현해야 할까요?

마이크로서비스 아키텍처에서 서비스 간 통신이 복잡해지면, 각 서비스에 네트워크 관련 로직을 중복으로 구현하게 됩니다. Service Mesh는 이 네트워크 관련 기능을 인프라 계층으로 분리하여, 애플리케이션 코드 변경 없이 mTLS, 트래픽 관리, 분산 추적을 제공합니다.

Service Mesh란?

Service Mesh는 서비스 간 통신을 전담하는 인프라 계층입니다. 각 Pod에 사이드카 프록시를 주입하여, 모든 네트워크 트래픽이 이 프록시를 통해 흐르게 합니다.

PLAINTEXT
기존 방식:
  Service A ───────────────→ Service B

Service Mesh 방식:
  Service A → [Proxy A] ────→ [Proxy B] → Service B

구성 요소

계층역할예시
Data Plane각 Pod의 사이드카 프록시, 트래픽 처리Envoy, linkerd-proxy
Control Plane프록시 설정 관리, 인증서 발급istiod, linkerd-control-plane

사이드카 프록시 패턴

사이드카는 메인 컨테이너와 같은 Pod에서 실행되며, iptables 규칙으로 모든 인바운드/아웃바운드 트래픽을 가로챕니다.

PLAINTEXT
                       Pod
    ┌──────────────────────────────────┐
    │                                  │
    │  ┌─────────┐    ┌────────────┐  │
    │  │   App   │←──→│  Sidecar   │←──── 외부 트래픽
    │  │Container│    │  Proxy     │───→  외부 트래픽
    │  └─────────┘    └────────────┘  │
    │                                  │
    └──────────────────────────────────┘

Istio에서는 istio-init Init 컨테이너가 iptables 규칙을 설정하고, Envoy 사이드카가 모든 트래픽을 처리합니다.

핵심 기능

1. mTLS (Mutual TLS)

서비스 간 모든 통신을 자동으로 암호화하고, 양방향 인증을 수행합니다.

YAML
# Istio PeerAuthentication
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT  # 모든 통신에 mTLS 강제

Service Mesh 없이 mTLS를 구현하려면 각 서비스마다 인증서를 관리하고 갱신 로직을 작성해야 하는데, Service Mesh는 이를 자동으로 처리합니다.

2. 트래픽 관리

YAML
# Istio VirtualService — 트래픽 분할 (카나리 배포)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: my-service
spec:
  hosts:
    - my-service
  http:
    - route:
        - destination:
            host: my-service
            subset: v1
          weight: 90
        - destination:
            host: my-service
            subset: v2
          weight: 10  # 10% 트래픽을 v2로
    - timeout: 5s       # 타임아웃
      retries:
        attempts: 3     # 재시도 횟수
        perTryTimeout: 2s
---
# DestinationRule — 서브셋 정의
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: my-service
spec:
  host: my-service
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 100
    outlierDetection:          # Circuit Breaker
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s

3. 관찰 (Observability)

사이드카 프록시가 모든 요청을 처리하므로, 추가 코드 없이 다음을 제공합니다.

  • 분산 추적: 요청이 서비스를 거치는 전체 경로 추적 (Jaeger, Zipkin)
  • 메트릭: 요청 수, 지연 시간, 에러율 (Prometheus)
  • 서비스 그래프: 서비스 간 통신 시각화 (Kiali)

4. 접근 제어

YAML
# Istio AuthorizationPolicy
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: frontend-to-backend
spec:
  selector:
    matchLabels:
      app: backend
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/default/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/*"]

Istio vs Linkerd

Istio

  • 프록시: Envoy (C++)
  • 기능: 매우 풍부 (트래픽 관리, 보안, 관찰, 확장)
  • 복잡도: 높음
  • 리소스: 사이드카당 ~128MB 메모리
  • 적합: 대규모 클러스터, 세밀한 트래픽 제어 필요 시
SHELL
# Istio 설치
istioctl install --set profile=default

# 네임스페이스에 사이드카 자동 주입 활성화
kubectl label namespace production istio-injection=enabled

# 이후 이 네임스페이스에 배포되는 Pod에 Envoy 사이드카가 자동 주입됨

Linkerd

  • 프록시: linkerd2-proxy (Rust)
  • 기능: 핵심 기능에 집중 (mTLS, 관찰, 재시도)
  • 복잡도: 낮음
  • 리소스: 사이드카당 ~10MB 메모리
  • 적합: 가벼운 Service Mesh 필요 시, 빠른 도입
SHELL
# Linkerd 설치
linkerd install | kubectl apply -f -

# 기존 Deployment에 사이드카 주입
kubectl get deployment my-app -o yaml | linkerd inject - | kubectl apply -f -

비교 표

기준IstioLinkerd
리소스 사용량높음매우 낮음
학습 곡선높음낮음
기능 범위넓음핵심에 집중
커뮤니티매우 큼활발
mTLS지원기본 활성화
트래픽 분할정밀 제어기본 지원

도입 판단 기준

Service Mesh는 강력하지만, 모든 환경에 필요한 것은 아닙니다.

도입이 적합한 경우

  • 마이크로서비스가 10개 이상이고 서비스 간 통신이 복잡한 경우
  • 서비스 간 mTLS가 보안 요구사항인 경우
  • 카나리 배포, 트래픽 미러링 같은 고급 배포 전략이 필요한 경우
  • 분산 추적과 서비스 간 메트릭이 필요한 경우

도입이 불필요한 경우

  • 서비스가 소수이고 통신 패턴이 단순한 경우
  • 팀이 Service Mesh를 운영할 역량이 부족한 경우
  • 리소스 오버헤드를 감당할 수 없는 경우

도입 시 고려사항

  • 리소스 오버헤드: Pod마다 사이드카가 추가되므로 CPU/메모리 비용이 증가합니다
  • 지연 시간 증가: 사이드카를 거치므로 약간의 레이턴시가 추가됩니다 (~1-3ms)
  • 운영 복잡도: Control Plane 관리, 업그레이드, 트러블슈팅 난이도가 높아집니다
  • 디버깅 난이도: 네트워크 경로가 복잡해져서 문제 원인 파악이 어려울 수 있습니다

Ambient Mesh — 사이드카 없는 Service Mesh

Istio의 Ambient Mesh는 사이드카 대신 노드별 공유 프록시(ztunnel)를 사용하는 새로운 방식입니다. Pod마다 사이드카를 주입하지 않으므로 리소스 효율이 높고, 기존 워크로드 수정이 필요 없습니다.

PLAINTEXT
기존: Pod마다 사이드카
  [App + Envoy] [App + Envoy] [App + Envoy]

Ambient: 노드별 공유 프록시
  [App] [App] [App] ──→ [ztunnel (노드당 1개)]

아직 성숙 단계이지만, Service Mesh의 진입 장벽을 낮추는 방향으로 발전하고 있습니다.

정리

Service Mesh는 서비스 간 통신에 필요한 mTLS, 트래픽 관리, 관찰 기능을 인프라 계층에서 제공합니다. Istio는 기능이 풍부하지만 복잡하고, Linkerd는 가볍고 단순합니다. 도입 전에 실제로 해결해야 할 문제가 있는지, 운영 역량과 리소스를 감당할 수 있는지를 냉정하게 판단하는 것이 중요합니다.

댓글 로딩 중...