Skip to content

사이드카 패턴

사이드카 패턴이란 쿠버네티스와 같이 컨테이너 오케스트레이션 툴에서 구성할 수 있는 컨테이너 배치 패턴으로, 마치 오토바이 옆에 붙어 있는 사이드카와 비슷한 형태이다.

장점

1. 기존 로직의 변경 없이 기능 추가

사이드카 컨테이너를 통해 기존의 로직은 그대로 놔둔체 새로운 기능을 덧붙일 수 있다. 예를 들어 기존 http 프로토콜에 대해서만 서비스를 하는 웹서버에 tls layer를 추가하고 싶은 경우, 메인 컨테이너인 기존의 legacy 웹서버는 그대로 놔둔체 사이드카 컨테이너를 통해 https 서비스를 클라이언트에게 제공할 수 있다.

2. 컨테이너 재사용성

사이드카 컨테이너를 단일한 기능을 하게 모듈화하면 다른 곳에서 재사용하기 수월해진다. 대부분의 app에서는 로깅, 실행 프로세스 정보 확인 등의 작업들이 필요하다. 이때, 미리 인터페이스만 잘 맞춰 놓으면 매번 컴포넌트를 개발할 필요 없이, 하나의 사이드카 컨테이너로 해결할 수 있다.

예를 들어, 로그 수집 사이드카 컨테이너를 생각해 볼 수 있다. 메인 컨테이너에서 미리 지정된 디렉토리에 어플리케이션 로그를 쌓으면 동일한 사이드카 컨테이너로 해당 로그를 로그 저장소에 저장하여 따로 로그를 분석하거나 더 오랜 기간 로그를 확인을 할 수 있게 된다.

3. 간단한 PaaS 구현

사이드카 컨테이너를 비즈니스 로직을 제공 컨테이너로 활용하고, 메인 컨테이너에서는 단지 실행환경을 제공하는 역할만 담당하게 하는 PaaS 서비스를 구성할 수 있다. PaaS는 Platform을 제공해주고 그 안에 들어가는 application 로직은 사용자가 정의하는 서비스이다.

사이드카 패턴에서 PaaS를 구현한다면 메인 컨테이너가 비즈니스 로직의 실행 환경을 제공해 주는 plaltform으로써 존재하고 사이드카 컨테이너가 사용자가 입맛에 따라 로직을 정의하여 플랫폼에 올리는 역할을 하게 된다. 이를 통해 비즈니스 상황에 따라 바뀌게 되는 비즈니스 로직을 손쉽게 업데이트할 수 있고 비교적 자주 바뀌지 않는 런타임 환경은 안정적으로 서비스할 수 있게 만들어 준다.

Native 사이드카 컨테이너

Native 사이드카 컨테이너는, 기존 사이드카 패턴의 라이프사이클 관리 문제를 해결하기 위해 도입되었다. Kubernetes 1.29부터는 기본적으로 활성화되어 있으며, 1.33 버전에서 stable로 승격되었다.

  • 복잡한 readiness probe나 lifecycle hook 없이 간단하게 순서를 보장한다.
  • Job 리소스에도 지원하여서, Batch 작업에서도 사이드카 패턴을 자연스럽게 사용할 수 있다.

기존 사이드카 기능에서는 모든 컨테이너가 동시에 시작되고 종료되기 때문에 아래 문제들이 발생했다:

  • 시작 순서 보장 X: Service mesh proxy나 로깅 에이전트가 메인 애플리케이션보다 늦게 시작되면 초기 요청이나 로그가 누락될 수 있다.
  • 종료 순서 문제: 메인 컨테이너가 종료될 때 사이드카가 먼저 종료되면 종료 프로세스의 로그나 메트릭을 수집하지 못한다.
  • Job 완료 차단: Kubernetes Job에서 메인 작업이 완료되어도 사이드카 컨테이너가 계속 실행 중이면 Job이 완료되지 않는다.

restartPolicy: Always 옵션을 설정하면 다음과 같은 라이프사이클을 보장한다:

  • 메인 컨테이너보다 먼저 시작되어 필요한 인프라 서비스를 준비한다.
  • Init container이지만 Pod가 실행되는 동안 계속 실행된다.
  • 모든 메인 컨테이너가 종료된 후에 종료되어 마지막까지 지원 서비스를 제공한다.

yaml 예시

apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
initContainers:
- name: istio-proxy
image: istio/proxyv2:1.20.0
restartPolicy: Always # 이 설정이 Native 사이드카를 만든다
ports:
- containerPort: 15001
name: envoy-admin
- name: init-setup
image: busybox:1.36
command: ['sh', '-c', 'echo "Initial setup complete"']
# restartPolicy를 지정하지 않으면 일반 init container
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080

위 예제에서 실행 순서는 다음과 같다:

  1. istio-proxy (native sidecar) 시작 및 준비 완료
  2. init-setup (일반 init container) 실행 및 종료
  3. app (메인 컨테이너) 시작
  4. app 종료
  5. istio-proxy 종료

참고