# Zero-Downtime Traffic Routing dengan Envoy Service Mesh

> Diterbitkan oleh Literally Web ID pada 21 Oct 2026
> Sumber: https://literally.web.id/articles/zero-downtime-traffic-routing-dengan-envoy-service-mesh

---

Dalam 15 menit ke depan, kita akan merakit sebuah sistem *traffic routing* berskala masif tanpa *downtime* menggunakan Envoy Proxy dan Kubernetes. Bayangkan kita sedang berada di dapur produksi sebuah platform e-commerce dengan jutaan *request* per detik, di mana satu kesalahan *deploy* bisa berakibat jutaan rupiah melayang. Mari kita tinggalkan teori buku teks yang membosankan dan langsung tangan-tangan kotor meracik infrastruktur tangguh.

## 1. Menu Kita Hari Ini & Alat yang Perlu Disiapkan

Sebelum kita menyalakan kompor, pastikan meja kerja kita sudah bersih dari gangguan. Kita tidak butuh ramuan magis, cukup perkakas standar industri modern yang biasa kita pegang di server produksi:
- Kluster Kubernetes (minikube atau kind untuk eksperimen lokal sudah lebih dari cukup).
- `kubectl` yang sudah terhubung rapi ke kluster.
- `envoy` CLI (opsional, karena kita akan membungkusnya dalam pod Kubernetes).
- Secangkir kopi hangat untuk menemani proses *debugging* kilat.

> [!IMPORTANT]
> Pastikan versi Envoy yang digunakan minimal v1.25+ agar fitur *Outlier Detection* dan *Weighted Routing* berjalan stabil tanpa *legacy bug*.

Dari perkakas ini, kita akan langsung melangkah ke cetak biru arsitektur yang akan kita bangun agar bayangan sistemnya semakin nyata di kepala kita.

## 2. Peta Jalan Singkat: Apa yang Sedang Kita Rakit

Perjalanan kita terbagi menjadi tiga fase utama dapur infrastruktur:
1. **Arsitektur Sidecar Proxy**: Menyisipkan Envoy tepat di samping aplikasi backend kita (entah itu ditulis dengan Go, Node.js, atau PHP-FPM) untuk mencegat seluruh lalu lintas masuk dan keluar.
2. **Canary Deployment dengan Weighted Routing**: Mengalirkan 90% trafik ke versi stabil (v1) dan 10% sisanya ke versi eksperimental (v2) tanpa membuat koneksi klien terputus.
3. **Circuit Breaking dan Outlier Detection**: Memasang rem otomatis jika salah satu *pod* backend mulai megap-megap karena lonjakan beban, sehingga kegagalan tidak merembet ke seluruh sistem.

Mari kita mulai meracik fondasi pertama kita di kluster Kubernetes.

## 3. Langkah 1: Mempersiapkan Fondasi & Environment

Kita mulai dengan menyiapkan *namespace* khusus agar eksperimen kita terisolasi dengan rapi dari namespace `default`. Jalankan perintah berikut di terminal Anda:

```bash
kubectl create namespace envoy-mesh
```

Setelah namespace siap, kita siapkan konfigurasi *ConfigMap* untuk Envoy. Di sinilah otak perutean kita diletakkan. Buat file bernama `envoy-config.yaml`:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy-conf
  namespace: envoy-mesh
data:
  envoy.yaml: |
    admin:
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 9901
    static_resources:
      listeners:
      - name: listener_0
        address:
          socket_address:
            address: 0.0.0.0
            port_value: 80
        filter_chains:
        - filters:
          - name: envoy.filters.network.http_connection_manager
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
              stat_prefix: ingress_http
              route_config:
                name: local_route
                virtual_hosts:
                - name: backend_service
                  domains: ["*"]
                  routes:
                  - match:
                      prefix: "/"
                    route:
                      weighted_clusters:
                        clusters:
                        - name: web_v1
                          weight: 90
                        - name: web_v2
                          weight: 10
              http_filters:
              - name: envoy.filters.http.router
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
      clusters:
      - name: web_v1
        connect_timeout: 0.25s
        type: STRICT_DNS
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: web_v1
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: web-v1-service
                    port_value: 8080
      - name: web_v2
        connect_timeout: 0.25s
        type: STRICT_DNS
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: web_v2
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: web-v2-service
                    port_value: 8080
```

> [!TIP]
> Perhatikan bagian `weighted_clusters`. Di sinilah keajaiban *Canary Deployment* terjadi secara instan tanpa perlu memodifikasi kode aplikasi backend.

Konfigurasi ini baru permukaannya saja. Sekarang, mari kita perdalam racikan ini dengan menyusun detail *routing* dan kebijakan *circuit breaking* agar dapur kita benar-benar tahan banting.

## 4. Langkah 2: Meracik Konfigurasi Inti Tanpa Basa-basi

Sebuah arsitektur mesh yang matang tidak hanya membagi trafik, tapi juga tahu kapan harus menghentikan pengiriman permintaan ke server yang sedang sekarat. Kita akan menyempurnakan konfigurasi kluster kita dengan menambahkan *Outlier Detection* (pembersihan otomatis *pod* yang error) pada file `envoy-config.yaml` kita.

Tambahkan blok `outlier_detection` di dalam masing-masing *cluster*:

```yaml
      clusters:
      - name: web_v1
        connect_timeout: 0.25s
        type: STRICT_DNS
        lb_policy: ROUND_ROBIN
        outlier_detection:
          consecutive_5xx: 3
          interval: 5s
          base_ejection_time: 30s
          max_ejection_percent: 50
        load_assignment:
          cluster_name: web_v1
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: web-v1-service
                    port_value: 8080
```

> [!WARNING]
> Jika `consecutive_5xx` terlalu rendah, *pod* yang mengalami lonjakan trafik sesaat (spike) bisa langsung di-kick keluar dari rotasi, menyebabkan *false positive* pada ketersediaan layanan.

Dengan aturan ini, jika Envoy mendeteksi sebuah *pod* di kluster `web_v1` memuntahkan *error* 5xx sebanyak 3 kali berturut-turut, Envoy akan langsung mengeluarkannya dari peredaran selama 30 detik. Aplikasi tetap berjalan mulus, sementara sistem melakukan pemulihan otomatis di latar belakang.

## 5. Langkah 3: Sentuhan Akhir Keamanan & Optimasi

Sebelum kita lepaskan ke ranah publik, kita pastikan akses manajemen Envoy (Admin Panel di port 9901) terkunci rapat dari luar kluster. Kita juga menambahkan *health check* dan *readiness probe* pada pod Envoy kita agar orkestrasi Kubernetes mengenali kapan proxy ini benar-benar siap menerima beban.

Buat file manifest deployment `envoy-deployment.yaml`:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: envoy-gateway
  namespace: envoy-mesh
spec:
  replicas: 2
  selector:
    matchLabels:
      app: envoy-gateway
  template:
    metadata:
      labels:
        app: envoy-gateway
    spec:
      containers:
      - name: envoy
        image: envoyproxy/envoy:v1.26-latest
        ports:
        - containerPort: 80
        - containerPort: 9901
        volumeMounts:
        - name: config-volume
          mountPath: /etc/envoy
        readinessProbe:
          httpGet:
            path: /ready
            port: 9901
          initialDelaySeconds: 3
          periodSeconds: 5
      volumes:
      - name: config-volume
        configMap:
          name: envoy-conf
```

Terapkan konfigurasi ini ke kluster:

```bash
kubectl apply -f envoy-config.yaml
kubectl apply -f envoy-deployment.yaml
```

Perhatikan respons di terminal: `deployment.apps/envoy-gateway created`. Itu tanda bahwa prajurit Envoy kita sudah berdiri tegak di garis depan. Sekarang saatnya kita uji coba rasanya.

## 6. Tes Rasa: Memastikan Semuanya Berjalan Sempurna

Saatnya kita buktikan apakah ramuan kita bekerja sesuai ekspektasi. Kita akan melakukan *port-forwarding* ke pod Envoy lokal kita dan menembaknya menggunakan utilitas `curl` secara berulang.

Jalankan perintah ini di terminal terpisah:

```bash
kubectl port-forward svc/envoy-gateway-service 8080:80 -n envoy-mesh
```
*(Catatan: pastikan Anda sudah membuat service `ClusterIP` untuk Envoy gateway, atau gunakan port-forward langsung ke pod).* 

Lalu tembak endpoint tersebut sebanyak 10 kali:

```bash
for i in {1..10}; do curl -s -I http://localhost:8080/; done
```

Perhatikan header respons yang dikembalikan. Anda akan melihat sekitar 9 respons mengarah ke versi `web_v1` dan 1 respons mendarat di `web_v2`. Proporsi 90:10 berjalan presisi tanpa ada satupun *request* yang berstatus *connection refused* atau terputus di tengah jalan.

## 7. Pertolongan Pertama: Jika Terjadi Kendala Kecil

Di lapangan, terkadang ada saja kerikil kecil yang mengadang. Berikut pertolongan pertama pada kecelakaan (P3K) infrastruktur:
- **Kendala 1**: Muncul *error* `Cluster not found` pada log Envoy.
  - *Solusi kilat*: Periksa kembali nama *cluster* di bagian `weighted_clusters` apakah sudah persis sama dengan nama yang dideklarasikan di blok `static_resources.clusters`.
- **Kendala 2**: Trafik 100% lari ke v1, mengabaikan porsi v2.
  - *Solusi kilat*: Cek koneksi DNS Kubernetes dengan memastikan *service* `web-v2-service` aktif dan memiliki *endpoints* yang valid di dalam namespace yang sama.

Tarik napas dalam-dalam, infrastruktur kelas produksi Anda kini sudah siap menghadapi badai trafik harian.
