사이드카 패턴: 코드 수정 없이 마이크로서비스 확장

사이드카 패턴: 코드 수정 없이 마이크로서비스 확장

최신 클라우드 네이티브 시스템에서 마이크로서비스는 비즈니스 로직을 실행하는 것보다 훨씬 더 많은 일을 할 것으로 예상됩니다. 로깅을 처리하고, SSL/TLS 인증서를 관리하고, 측정항목을 수집하고, 재시도 메커니즘을 구현하고, 다른 서비스와의 보안 통신을 조정해야 합니다.

이러한 모든 크로스커팅 기능을 각 애플리케이션의 코드베이스에 직접 포함시키면 결국 코드가 팽창하고 긴밀한 결합 및 언어 잠금이 발생하게 됩니다.

이것이 바로 사이드카 패턴이 등장하는 곳입니다. 이 가이드에서는 사이드카 패턴이 무엇인지, 사이드카 패턴이 현대 마이크로서비스 아키텍처에 필수적인 이유, 간단한 비유와 Kubernetes 구성 예를 사용하여 사이드카 패턴이 어떻게 작동하는지 분석합니다.


실제 비유: 오토바이 사이드카

이 패턴을 이해하는 가장 쉬운 방법은 사이드카가 달린 오토바이를 생각하는 것입니다.

포드 내부의 애플리케이션 및 사이드카 컨테이너를 보여주는 사이드카 패턴 아키텍처 다이어그램

고성능 오토바이를 가지고 있다고 상상해 보십시오. 한 가지 일을 매우 효과적으로 수행하도록 설계되었습니다. 바로 한 명의 라이더를 빠르게 운송하는 것입니다. 이제 승객의 수하물을 운반하거나 추가 좌석을 추가해야 한다고 가정해 보겠습니다.

오토바이의 프레임, 엔진, 바퀴를 완전히 재설계하여 자동차로 바꿀 수도 있습니다. 그러나 이를 위해서는 엄청난 노력이 필요하고 자전거의 단순성이 손상되며 유지 관리가 어려워집니다.

대신 사이드카를 연결합니다.

사이드카는 모터사이클에 연결되는 별도의 독립형 장치입니다. 이는 오토바이의 여정을 공유하고, 자전거가 가는 곳이면 어디든 가며, 긴밀하게 협력하여 작동합니다. 그러나 오토바이의 핵심 엔진은 그대로 유지됩니다.

소프트웨어 아키텍처에서:

  • 오토바이는 기본 애플리케이션 컨테이너입니다(결제 또는 사용자 인증과 같은 핵심 비즈니스 로직 실행).
  • 사이드카는 별도의 도우미 컨테이너입니다(SSL 종료, 모니터링 또는 로그 전달과 같은 유틸리티 작업 실행).
  • 여정은 배포(예: Kubernetes Pod)의 수명 주기입니다.

문제: 교차 문제 및 코드 팽창

사이드카 이전에는 개발자가 애플리케이션 코드에 도우미 라이브러리를 직접 포함해야 했습니다. 예를 들어 로그를 중앙 서버로 보내려면 로깅 라이브러리를 가져왔습니다. 지표가 필요한 경우 지표 SDK를 추가했습니다.

이러한 라이브러리 기반 접근 방식은 다음과 같은 몇 가지 중요한 문제를 야기했습니다.

  • 언어 잠금: 모니터링 라이브러리가 Go로만 작성된 경우 Python 또는 Java 마이크로서비스에서 쉽게 사용할 수 없습니다. 스택의 모든 언어에 대한 라이브러리를 찾거나 구축해야 합니다.
  • 코드 오염: 재시도, 서비스 검색, 암호화 및 로깅을 위한 인프라별 코드로 비즈니스 로직이 복잡해집니다.
  • 복잡한 업그레이드: 통신 라이브러리에서 보안 취약점이 발견되면 모든 단일 마이크로서비스는 종속성을 업데이트하고 다시 컴파일하고 재배포해야 합니다.
  • 리소스 경합: 도우미 코드는 기본 애플리케이션과 동일한 런타임 프로세스에서 실행됩니다. 즉, 로거의 메모리 누수로 인해 전체 핵심 애플리케이션이 중단될 수 있습니다.

해결책: 사이드카 패턴

사이드카 패턴은 도우미 작업을 기본 애플리케이션 프로세스에서 이동하고 애플리케이션 바로 옆에서 실행되는 별도의 독립 프로세스에 배치하여 이러한 문제를 해결합니다.

Kubernetes와 같은 컨테이너화된 환경에서는 애플리케이션 컨테이너와 사이드카 컨테이너가 동일한 Pod 내에서 실행됩니다. 동일한 Pod를 공유하기 때문입니다.

  • 동일한 네트워크 네임스페이스: 동일한 IP 주소와 네트워크 포트를 공유합니다. 그들은 거의 대기 시간 없이 localhost을 통해 즉시 서로 대화할 수 있습니다.
  • 공유 스토리지 볼륨: 동일한 디스크 스토리지에 액세스할 수 있으므로 사이드카가 로그 파일을 읽거나 기본 애플리케이션에서 작성한 구성 파일을 로드할 수 있습니다.
  • 동일한 수명 주기: 사이드카는 기본 애플리케이션과 함께 배포, 시작, 중지 및 확장됩니다.

사이드카 패턴의 주요 사용 사례

사이드카는 믿을 수 없을 정도로 다재다능합니다. 가장 일반적인 응용 프로그램 중 일부는 다음과 같습니다.

1. 서비스 메시 프록싱(예: Envoy, Linkerd)

애플리케이션은 다른 서비스에 대해 직접 HTTP 호출을 수행하는 대신 로컬 사이드카 프록시에 요청을 보냅니다. 사이드카 프록시는 라우팅, 재시도, 로드 밸런싱, 회로 차단 및 상호 TLS(mTLS) 암호화를 처리한 다음 요청을 전달합니다. 애플리케이션은 이러한 네트워크 복잡성을 전혀 인식하지 못합니다.

2. 로그 수집 및 전달(예: Fluent Bit)

애플리케이션은 단순히 로그 문을 표준 출력이나 로컬 로그 파일에 기록합니다. 사이드카 컨테이너는 해당 파일을 모니터링하고 로그를 구문 분석한 후 Elasticsearch 또는 Datadog과 같은 중앙 분석 엔진으로 전달합니다.

3. 구성 및 비밀 다시 로드

사이드카는 구성 업데이트 또는 암호화 키 순환을 위해 원격 서버(예: Consul 또는 Vault)를 감시할 수 있습니다. 변경 사항이 감지되면 새 파일을 공유 볼륨에 다운로드하고 다시 시작할 필요 없이 기본 애플리케이션에 해당 파일을 다시 로드하라는 신호를 보냅니다.


쿠버네티스 구현 예시

Kubernetes에서는 사이드카 설정이 간단합니다. 다음은 공유 볼륨에 로그를 쓰는 애플리케이션 컨테이너와 해당 로그를 읽고 전달하는 Fluent Bit 사이드카 컨테이너를 보여주는 간단한 YAML 구성입니다.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-logging-sidecar
  labels:
    app: billing-service
spec:
  containers:
    # 1. Primary Application Container
    - name: web-app
      image: node:18-alpine
      command: ["/bin/sh", "-c"]
      args:
        - >
          while true; do
            echo "$(date) [INFO] Transaction processed successfully" >> /var/log/app/output.log;
            sleep 5;
          done
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app

    # 2. Sidecar Container (Log Shipper)
    - name: log-shipper
      image: fluent/fluent-bit:latest
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app
      # In a real setup, Fluent Bit config would read /var/log/app/output.log
      # and forward it to an external logging system.

  # Shared disk storage accessible by both containers
  volumes:
    - name: shared-logs
      emptyDir: {}

사이드카 패턴의 장점과 단점

다른 디자인 패턴과 마찬가지로 사이드카에도 장단점이 있습니다.

어드밴티지(프로) 단점(단점)
언어에 구애받지 않음: 사이드카는 자체 환경에서 실행됩니다. Go, Java, Python 또는 Ruby 앱 옆에 동일한 사이드카 도우미를 사용할 수 있습니다. 리소스 오버헤드: 포드당 여러 컨테이너를 실행하면 CPU 및 메모리 소비가 늘어납니다.
분리된 라이프사이클: 인프라 팀은 애플리케이션 코드를 건드리지 않고도 사이드카의 보안 패치를 업데이트할 수 있습니다. 복잡성 증가: 두 배 더 많은 컨테이너를 관리하면 배포 구성, 디버깅 및 예약이 복잡해집니다.
독립적 오류 격리: 사이드카 컨테이너가 충돌하는 경우 Kubernetes는 기본 애플리케이션을 중단하지 않고 자동으로 다시 시작할 수 있습니다. 약간의 네트워크 지연 시간: 로컬 프록시 사이드카를 통한 트래픽 라우팅은 일반적으로 무시할 수 있지만 약간의 홉을 추가합니다(< 1ms).

결론

사이드카 패턴은 최신 클라우드 네이티브 아키텍처의 기본 구성 요소입니다. 네트워크 프록시, 보안, 로깅 및 구성 관리와 같은 교차 문제를 별도의 동반 프로세스로 분리함으로써 개발자는 비즈니스 가치 구축에만 집중할 수 있습니다.

추가 리소스 오버헤드가 발생하고 효율적으로 관리하려면 Kubernetes와 같은 컨테이너 오케스트레이션 플랫폼이 필요하지만 더 깔끔한 코드베이스, 언어 유연성 및 독립적인 확장의 이점으로 인해 엔터프라이즈 마이크로서비스에 없어서는 안 될 패턴입니다.


Ghaznix 블로그에서 더 많은 소프트웨어 개발 및 백엔드 엔지니어링 통찰력을 살펴보세요 →