본문으로 건너뛰기
김신건의 로그

[Kubernetes] Init Containers & Sidecar Containers

· 수정 · 📖 약 3분 · 1,080자/단어 #kubernetes #pod #init-container #sidecar
Init Containers, Sidecar Containers, k8s init container, k8s sidecar, native sidecar, restartPolicy Always init, k8s 1.29 sidecar, k8s 1.33 sidecar GA, 쿠버네티스 사이드카, 쿠버네티스 init 컨테이너

정의

Init Containers 는 Pod 의 메인 컨테이너보다 먼저 실행되어 초기화 작업을 완료하고 종료되는 컨테이너입니다.

Sidecar Containers 는 메인 컨테이너와 함께 실행되며 로깅/모니터링/프록시 등 부가 기능을 제공하는 컨테이너입니다. Kubernetes v1.33 (2025-04) 에서 native sidecar 지원이 GA 되어 (restartPolicy: AlwaysinitContainers 에 지정) 기존 pattern 이 표준화되었습니다.

Init Container

특징

  • 순차 실행: spec.initContainers 순서대로. 하나가 성공해야 다음 시작.
  • 완료 후 종료: exit code 0 이면 성공. 실패면 Pod 재시작 정책에 따라 처리.
  • 메인 컨테이너와 이미지 분리 가능: 초기화 도구는 초기화 이미지에.
  • 네트워크/볼륨 공유: 메인과 같은 network namespace, 같은 volume.

사용 사례

  1. DB migration: 앱 시작 전 alembic upgrade, rails db:migrate
  2. 설정 파일 생성: 원격 config service 에서 fetch 후 configMap/emptyDir 에 저장
  3. 의존 서비스 대기: wait-for-it db:5432 로 DB ready 확인
  4. secret 처리: KMS 에서 decrypt 후 emptyDir 에
  5. Git clone: 코드 저장소 clone

예시

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.36
      command: ['sh', '-c', 'until nc -z db 5432; do sleep 1; done']
    - name: migrate
      image: myapp:1.0
      command: ['python', 'manage.py', 'migrate']
      envFrom:
        - secretRef:
            name: db-secret
  containers:
    - name: web
      image: myapp:1.0
      ports: [{containerPort: 8000}]

wait-for-db -> migrate -> web 순.

리소스 계산

Pod 의 effective request/limit 은:

Init container 는 순차 실행이라 동시에 존재하지 않지만, 스케줄러는 가장 큰 init container 도 감안하여 예약.

Sidecar (native) 는 initContainers 에 있지만 동시 실행 이라 합산.

Native Sidecar (v1.29 beta -> v1.33 GA)

배경

전통적 sidecar 는 containers[] 에 넣었지만 여러 문제:

  1. 시작 순서 불안정: Pod 시작 시 sidecar 와 main 이 동시 시작. Main 이 sidecar 필요 (예: log shipper) 하면 race.
  2. 종료 순서 불안정: Pod 종료 시 sidecar 가 main 보다 먼저 죽을 수 있음. Log 유실.
  3. Job 문제: Sidecar 가 계속 돌면 Job 이 완료되지 않음. Workaround 로 self-kill 신호 등 복잡.

해결

Native sidecarinitContainers 에 넣되 restartPolicy: Always:

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  initContainers:
    - name: log-agent           # native sidecar
      image: fluent/fluent-bit:3
      restartPolicy: Always      # 이것이 핵심
      volumeMounts:
        - name: logs
          mountPath: /var/log
    - name: db-migrator          # 전통 init container
      image: myapp:1.0
      command: ['python', 'manage.py', 'migrate']
  containers:
    - name: web
      image: myapp:1.0
      volumeMounts:
        - name: logs
          mountPath: /var/log
  volumes:
    - name: logs
      emptyDir: {}

Native sidecar 이점

  1. 명확한 시작 순서: sidecar 가 started 상태되면 다음 init container 시작. Sidecar 준비 후 main 이 시작.
  2. 명확한 종료 순서: main 이 완전히 종료된 후 sidecar 에 SIGTERM. 로그/메트릭 유실 없음.
  3. Job 호환: restartPolicy: Never/OnFailure Job 에서 sidecar 가 완료를 막지 않음.
  4. Probe 지원: liveness/readiness/startup probe 를 sidecar 에도.

언제 어느 것을?

유형containers[]initContainers[] restartPolicy 없음initContainers[] restartPolicy: Always
메인 앱
초기화 (완료 지향)
Sidecar (병렬 실행)예전✓ (권장)

주요 sidecar 패턴

1. Log agent

Fluent Bit 이 앱 로그를 수집해 원격 저장소로.

initContainers:
  - name: fluent-bit
    image: fluent/fluent-bit:3
    restartPolicy: Always
    volumeMounts:
      - name: logs
        mountPath: /logs
      - name: config
        mountPath: /fluent-bit/etc

2. Metrics exporter

Prometheus exporter 를 sidecar 로.

initContainers:
  - name: postgres-exporter
    image: prometheuscommunity/postgres-exporter:v0.15
    restartPolicy: Always
    env:
      - name: DATA_SOURCE_NAME
        value: "postgres://user:pass@localhost:5432/postgres?sslmode=disable"
    ports:
      - containerPort: 9187

3. Service mesh proxy (Envoy)

Istio, Linkerd 는 Envoy/linkerd-proxy 를 sidecar 로 auto-inject. Native sidecar 로 이관 진행 중.

4. Config reload

Config file 변경 감지 -> 앱에 SIGHUP.

5. Secret rotation

Vault agent injector, secrets-store-csi-driver.

Probe 통합

Init container (native sidecar) 도 probe 지원 (v1.28+):

initContainers:
  - name: log-agent
    image: fluent/fluent-bit:3
    restartPolicy: Always
    startupProbe:
      httpGet:
        path: /api/v1/health
        port: 2020
      failureThreshold: 30
      periodSeconds: 2
    livenessProbe:
      httpGet:
        path: /api/v1/health
        port: 2020

Sidecar 가 started 상태 되면 다음 init 또는 main 시작.

Migration Guide

기존 containers[] sidecar 를 native 로 옮기려면:

Before:

containers:
  - name: web
    image: myapp:1.0
  - name: log-agent
    image: fluent/fluent-bit:3

After:

initContainers:
  - name: log-agent
    image: fluent/fluent-bit:3
    restartPolicy: Always
containers:
  - name: web
    image: myapp:1.0

주의:

  • 클러스터 버전이 v1.29+ (feature gate) 또는 v1.33+ (GA) 이어야 함.
  • 자동 injector (Istio, Fluent Bit operator) 가 이미 native sidecar 지원하는지 확인.

Init container Anti-pattern

앱을 init 로 (X)

initContainers:
  - name: web         # 앱 자체
    image: myapp:1.0
    command: ['python', 'app.py']   # 계속 실행

Init 는 완료 지향. Long-running 을 넣으면 Pod 이 절대 Ready 안 됨.

초기화를 앱 안에서 (△)

containers:
  - name: web
    image: myapp:1.0
    command: ['sh', '-c', 'migrate && python app.py']   # 하나로

작동은 하지만:

  • 앱 이미지에 migration 도구 포함 필요
  • Migration 실패 시 앱 재시작 loop
  • 로그 구분 어려움

Init container 로 분리하는 편이 관용.

함정

WARNING

Native sidecar 는 클러스터 v1.29+ 필수. 오래된 클러스터에서는 restartPolicy: Always 가 조용히 무시되어 Pod 시작 실패.

CAUTION

Init container 실패는 Pod 실패로 카운트. restartPolicy: OnFailure/Always 라도 backoff 후 재시작. Init 가 무한 실패하면 CrashLoopBackoff.

WARNING

Init container 도 리소스 요청 필요. 안 걸면 BestEffort QoS -> 노드 압박 시 evict.

IMPORTANT

Sidecar 이미지 크기. Main + sidecar 합쳐 이미지 pull 시간 증가. 이미지 최적화.

CAUTION

Init 에서 network 접근 시 CNI 준비 여부. CNI 가 준비되기 전에 init 실행 가능성. 짧은 backoff + retry.

관련 위키

이 글의 용어 (9개)
[K8s] ConfigMap & Secret: 설정과 비밀의 분리kubernetes
정의 ConfigMap 과 Secret 은 컨테이너 이미지에서 설정/비밀 값을 분리하기 위한 Kubernetes 리소스. | 항목 | ConfigMap | Secret | |:-…
[K8s] Deployment: ReplicaSet, rolling update, rollbackkubernetes
정의 Deployment = stateless 워크로드를 위한 컨트롤러. 내부적으로 ReplicaSet 관리 + rolling update / rollback. 사용 시나리오 |…
[K8s] Job / CronJob: 일회성 + 스케줄 작업kubernetes
정의 | 컨트롤러 | 의미 | |---|---| | Job | 완료까지 실행하는 일회성 작업 | | CronJob | 스케줄 (cron) 에 따라 Job 생성 | Deployme…
[K8s] Pod: 컨테이너의 최소 단위, sidecar, lifecyclekubernetes
정의 Pod = K8s 의 가장 작은 배포 단위. 1개 이상의 컨테이너 + 공유 네트워크 + 공유 스토리지. [!IMPORTANT] Pod 는 컨테이너의 wrapping 이 아니…
[Kubernetes] Resource Management (Requests, Limits, QoS)kubernetes
정의 Kubernetes Resource Management 는 CPU, 메모리, ephemeral storage, hugepages 등의 리소스를 파드에 할당하고 제한하는 시스…
[Kubernetes] Service Mesh (Istio, Linkerd, Cilium)kubernetes
정의 Service Mesh 는 마이크로서비스 간 통신에 L7 정책, mTLS 암호화, 트래픽 관리, 관측성 을 제공하는 인프라 계층입니다. 앱 코드를 바꾸지 않고 프록시 (si…
[Observability] OpenTelemetry: 표준화된 trace/metric/logdevops
정의 OpenTelemetry (OTel) = observability 의 vendor-neutral 표준. CNCF. trace + metric + log 의 SDK + pro…
[Observability] Prometheus: pull 기반 메트릭, PromQLdevops
정의 Prometheus = pull 기반 시계열 metric 시스템. PromQL 로 쿼리. CNCF graduated. 2026 클라우드 네이티브 메트릭 표준. 아키텍처 Pu…
Kuberneteskubernetes
정의 Kubernetes (k8s) 는 컨테이너화된 애플리케이션의 배포, 스케일링, 관리 를 자동화하는 오픈소스 오케스트레이터입니다. Google 이 2014년 발표하고 2015…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기