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: Alwaysdi 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.