Sidecar Pattern #

Sidecar pattern adalah salah satu pola desain paling berpengaruh di ekosistem cloud native. Idenya sederhana: tambahkan container pendamping di dalam Pod yang memperluas atau melengkapi kemampuan container utama, tanpa mengubah container utama sama sekali. Hasilnya adalah separation of concerns yang bersih — tim yang membangun aplikasi tidak perlu peduli dengan cross-cutting concerns seperti logging, keamanan jaringan, atau observability.

Konsep Dasar #

Nama “sidecar” mengacu pada kursi samping sepeda motor — ia tidak bisa berjalan sendiri, tapi ia memperluas kemampuan kendaraan utama tanpa mengubah kendaraan itu sendiri.

Tanpa sidecar:

  [App Container]
  │ kode aplikasi
  │ + logging logic
  │ + metrics collection
  │ + mTLS handling
  │ + tracing code
  └── semua concern jadi satu, image besar dan kompleks

Dengan sidecar:

  Pod
  ├── [App Container]          hanya kode bisnis
  │
  └── [Sidecar Container]      semua cross-cutting concern
        │ logging
        │ metrics
        │ mTLS
        └── tracing

Keuntungan utama pola ini: kamu bisa memperbarui sidecar (misalnya upgrade versi Envoy atau Fluentd) secara independen dari aplikasi, dan sebaliknya.


Use Case 1: Log Shipping #

Aplikasi menulis log ke file di filesystem. Sidecar mengambil log tersebut dan mengirimkannya ke sistem logging terpusat (Elasticsearch, Loki, CloudWatch, dll).

spec:
  volumes:
  - name: log-volume
    emptyDir: {}

  containers:
  # Container utama — hanya fokus pada logika bisnis
  - name: api
    image: my-api:v2
    volumeMounts:
    - name: log-volume
      mountPath: /var/log/app      # tulis log ke sini

  # Sidecar — fokus pada pengiriman log
  - name: log-shipper
    image: fluent/fluentd:v1.16
    volumeMounts:
    - name: log-volume
      mountPath: /var/log/app      # baca dari volume yang sama
      readOnly: true
    env:
    - name: FLUENT_ELASTICSEARCH_HOST
      value: "elasticsearch-service"
    - name: FLUENT_ELASTICSEARCH_PORT
      value: "9200"
    resources:
      requests:
        cpu: "50m"
        memory: "64Mi"
      limits:
        cpu: "100m"
        memory: "128Mi"

Dengan pola ini, bahasa atau framework apapun yang digunakan aplikasi tidak relevan — selama ia menulis log ke file, sidecar bisa mengambil dan mengirimkannya.


Use Case 2: Service Mesh Proxy #

Ini adalah penggunaan sidecar yang paling luas di industri. Service mesh seperti Istio menyuntikkan container Envoy sebagai sidecar ke setiap Pod secara otomatis (via admission webhook). Semua traffic masuk dan keluar dari Pod diintercept oleh proxy ini.

Tanpa service mesh:

  Pod A                            Pod B
  [App A] ─────────────────────── [App B]
           HTTP, tanpa enkripsi

Dengan Istio (sidecar otomatis):

  Pod A                                    Pod B
  [App A] → [Envoy] ── mTLS ──── [Envoy] → [App B]
             │                    │
             └── collect metrics  └── collect metrics
             └── distributed trace
             └── circuit breaking

App A dan App B tidak perlu tahu tentang mTLS, metrics, atau tracing — semua ditangani Envoy sidecar. Kode aplikasi tetap sederhana.

# Dengan Istio, annotasi ini cukup untuk mengaktifkan sidecar injection
metadata:
  annotations:
    sidecar.istio.io/inject: "true"

# Istio secara otomatis menambahkan container ini ke setiap Pod:
# - istio-proxy (Envoy)
# - istio-init (init container untuk setup iptables rules)

Use Case 3: Metrics Exporter #

Banyak aplikasi tidak mengekspos metric dalam format yang bisa dibaca Prometheus. Sidecar exporter bisa mengambil metric dari aplikasi (dalam format apapun) dan mengeksposnya dalam format Prometheus.

  containers:
  - name: app
    image: legacy-app:v1      # aplikasi lama, tidak punya /metrics endpoint
    ports:
    - containerPort: 8080

  - name: metrics-exporter
    image: prometheus/jmx_exporter:0.19.0   # exporter untuk aplikasi Java/JMX
    ports:
    - containerPort: 9404                    # Prometheus scrape dari sini
    args:
    - "9404"
    - /etc/jmx-config/config.yaml
    volumeMounts:
    - name: jmx-config
      mountPath: /etc/jmx-config

Use Case 4: Config Watcher #

Sidecar yang memantau perubahan konfigurasi dan memicu reload aplikasi tanpa restart Pod:

  volumes:
  - name: config-vol
    configMap:
      name: app-config

  containers:
  - name: app
    image: nginx:1.25
    volumeMounts:
    - name: config-vol
      mountPath: /etc/nginx/conf.d

  - name: config-reloader
    image: jimmidyson/configmap-reload:v0.9
    args:
    - --volume-dir=/etc/config
    - --webhook-url=http://localhost:8080/-/reload   # kirim sinyal reload ke app
    volumeMounts:
    - name: config-vol
      mountPath: /etc/config
      readOnly: true

Sidecar Container di Kubernetes 1.29+ #

Sebelum Kubernetes 1.29, sidecar dan container utama dimulai bersamaan, menyebabkan race condition jika container utama bergantung pada sidecar. Kubernetes 1.29 memperkenalkan native sidecar support yang menyelesaikan masalah ini.

spec:
  initContainers:
  - name: envoy-proxy
    image: envoy:v1.28
    restartPolicy: Always    # ← ini yang menjadikannya sidecar container
    # Dengan restartPolicy: Always di initContainer,
    # Kubernetes menjalankannya lebih dulu sebelum container utama
    # dan tidak menunggu ia selesai (berjalan terus)

  containers:
  - name: app
    image: my-app:v1
    # Dijamin envoy-proxy sudah berjalan sebelum app dimulai

Keuntungan native sidecar dibanding container biasa di spec.containers:

  • Dimulai sebelum container utama
  • Tetap berjalan saat container utama selesai (untuk Job)
  • Dihentikan setelah container utama berhenti

Kapan Tidak Menggunakan Sidecar #

Tidak setiap cross-cutting concern harus menjadi sidecar:

Jangan gunakan sidecar jika:
  ✗ Logika sangat spesifik untuk satu aplikasi
    → Masukkan ke kode aplikasi langsung

  ✗ Sidecar butuh resource yang signifikan (misalnya 30% dari total resource Pod)
    → Pertimbangkan apakah worth it; sidecar yang berat bisa mempengaruhi
       semua Pod di cluster jika dipakai sebagai standar

  ✗ Komunikasi antara sidecar dan app sangat kompleks
    → Mungkin lebih baik sebagai service terpisah

  ✗ Hanya satu Pod yang membutuhkan fungsionalitas ini
    → Masukkan ke dalam container utama saja

Gunakan sidecar jika:
  ✓ Fungsionalitas dibutuhkan oleh banyak Pod/service berbeda
  ✓ Tim berbeda yang bertanggung jawab (misalnya platform team kelola sidecar,
     dev team kelola container utama)
  ✓ Ingin upgrade/rollback sidecar independen dari aplikasi
  ✓ Tidak punya akses atau tidak ingin memodifikasi container utama

Ringkasan #

  • Sidecar = container pendamping tanpa mengubah container utama — separation of concerns yang bersih antara logika bisnis dan cross-cutting concerns.
  • Berbagi network via localhost — sidecar dan container utama berkomunikasi via localhost karena berbagi network namespace; tidak perlu Service.
  • Berbagi storage via volume — pola log shipping memanfaatkan shared volume untuk app menulis dan sidecar membaca.
  • Service mesh adalah sidecar pattern dalam skala cluster — Istio/Linkerd menyuntikkan Envoy sidecar ke setiap Pod untuk mTLS, tracing, dan circuit breaking tanpa perubahan kode.
  • Native sidecar (Kubernetes 1.29+) — gunakan restartPolicy: Always di initContainer untuk sidecar yang dijamin jalan sebelum container utama.
  • Resource sidecar punya overhead nyata — sidecar yang diterapkan ke seluruh cluster bisa signifikan secara aggregate; ukur dan tetapkan limits yang tepat.

← Sebelumnya: Init Container   Berikutnya: ReplicaSet →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact