Ingress Controller Comparison #

Di dalam ekosistem Kubernetes, objek Ingress bertindak sebagai gerbang masuk terpadu yang menerima seluruh lalu lintas kueri HTTP/HTTPS dari luar kluster, kemudian menyebarkannya ke layanan-layanan internal yang tepat berdasarkan aturan kueri domain atau URL path. Namun, sebagaimana kita ketahui, objek Ingress hanyalah berkas konfigurasi statis yang disimpan di database etcd. Kita wajib memasang sebuah Ingress Controller aktif di dalam kluster agar aturan-aturan perutean tersebut dapat dieksekusi secara nyata.

Memilih Ingress Controller yang tepat adalah salah satu keputusan arsitektur awal terpenting yang memiliki dampak jangka panjang bagi stabilitas dan efisiensi biaya infrastruktur kluster kita. Mengganti Ingress Controller pada kluster produksi yang sedang berjalan (live cluster) bukanlah tugas yang sepele. Kita dipaksa menulis ulang seluruh manifes Ingress, mengonversi puluhan annotations spesifik, dan melakukan uji coba routing ulang yang berisiko memicu downtime.

Artikel ini menyajikan perbandingan mendalam antara Ingress Controller terpopuler di industri saat ini, membedah karakteristik teknis masing-masing, memberikan panduan pohon keputusan (decision tree), serta mendemonstrasikan cara mengoperasikan beberapa controller secara berdampingan (multi-controller configuration).


Analisis Karakteristik Ingress Controller Populer #

Mari kita bedah arsitektur internal, kekuatan, dan kelemahan dari lima kandidat Ingress Controller yang paling banyak digunakan di produksi saat ini:

flowchart TD
    Options["INGRESS CONTROLLER OPTIONS"]
    Options --> InCluster["In-Cluster Proxy (NGINX Ingress - Komunitas)"]
    Options --> HotReload["Hot-Reload Proxy (Traefik - Dynamic config)"]
    Options --> OutCluster["Out-of-Cluster LB (AWS Load Balancer Controller)"]

1. NGINX Ingress Controller (kubernetes/ingress-nginx) #

Ini adalah Ingress Controller resmi yang dikembangkan langsung oleh komunitas Kubernetes. Controller ini menggunakan NGINX sebagai mesin reverse proxy utama yang berjalan di dalam Pod kluster kita.

  • Cara Kerja: kube-proxy mengarahkan lalu lintas luar ke Pod NGINX. NGINX Ingress Controller memantau API Server. Setiap kali ada perubahan objek Ingress, controller akan menulis ulang file konfigurasi template nginx.conf internalnya, kemudian memicu proses reload NGINX secara graceful.
  • Kelebihan: Paling dewasa (mature), komunitas terbesar di dunia, dokumentasi melimpah, dan contoh manifest sangat mudah ditemukan. NGINX mendukung berbagai fitur canggih via annotations (rate limiting, basic auth, CORS, URL rewriting).
  • Kekurangan: Meskipun proses reload NGINX bersifat graceful, pada kluster berskala besar dengan ratusan perubahan Ingress per menit (akibat autoscaling atau deployment dinamis), proses reload beruntun dapat memicu penggunaan CPU yang tinggi pada controller dan jeda minor pada pembentukan koneksi baru.
  • Use Case Terbaik: Skenario umum kluster on-premise, kluster testing/staging, atau kluster produksi umum di mana tim operasional sudah sangat familiar dengan konfigurasi reverse proxy NGINX tradisional.

2. Traefik Ingress #

Traefik adalah reverse proxy modern yang ditulis dalam bahasa Go dan dirancang sejak awal untuk mengelola arsitektur cloud-native yang sangat dinamis.

  • Cara Kerja: Traefik berinteraksi langsung dengan Kubernetes API. Traefik menerapkan teknologi Hot Reload (pembaruan konfigurasi dinamis langsung di memori) tanpa pernah memicu proses restart atau reload proses eksekusi.
  • Kelebihan: Zero-downtime mutlak saat terjadi perubahan konfigurasi routing. Traefik menyediakan dashboard grafis internal yang sangat intuitif untuk memantau status rute. Traefik juga mendukung integrasi otomatis Let’s Encrypt secara native, serta memiliki objek Custom Resource Definition (CRD) sendiri bernama IngressRoute yang bertipe aman (type-safe).
  • Kekurangan: Footprint memori RAM sedikit lebih tinggi dibandingkan NGINX saat kondisi idle. Performa throughput puncak sedikit di bawah NGINX/HAProxy untuk kueri HTTP murni yang sangat padat.
  • Use Case Terbaik: Kluster dengan arsitektur microservices dinamis yang sangat sering melakukan pembaruan rute, kluster yang membutuhkan dashboard pemantau lalu lintas visual, dan tim yang ingin menghindari penulisan annotations NGINX yang rawan kesalahan ketik.

3. HAProxy Ingress #

HAProxy terkenal di industri sebagai salah satu perangkat lunak load balancer Layer 4 dan Layer 7 tercepat dan paling efisien dalam penggunaan memori.

  • Cara Kerja: Memanfaatkan HAProxy Runtime API untuk mengubah konfigurasi backend secara dinamis di memori tanpa memicu proses reload HAProxy.
  • Kelebihan: Latensi sub-millisecond yang sangat konsisten, penanganan stabilitas sesi pengguna (session persistence/sticky cookie) terbaik, serta throughput kueri per detik (QPS) tertinggi di antara seluruh in-cluster proxy.
  • Kekurangan: Komunitas pengguna di ekosistem Kubernetes relatif kecil dibandingkan NGINX dan Traefik. Contoh manifes dan integrasi pihak ketiga (seperti cert-manager) membutuhkan konfigurasi manual yang sedikit lebih rumit.
  • Use Case Terbaik: Workload finansial atau e-commerce dengan lalu lintas data sangat padat yang membutuhkan latensi ultra-rendah dan stabilitas sticky session yang ketat.

4. AWS Load Balancer Controller (AWS ALB) #

Berbeda dengan NGINX atau Traefik yang berjalan sebagai proxy reverse di dalam kluster (in-cluster proxy), AWS Load Balancer Controller bertindak sebagai operator kontrol yang mengelola pembuatan Application Load Balancer (ALB) fisik di luar kluster (di akun AWS kita).

Mari kita perhatikan perbedaan alur lalu lintas data di bawah ini:

In-Cluster Proxy (e.g. NGINX Ingress):
  Client ──> [Cloud Load Balancer (L4)] ──> [NGINX Pod (L7 In-Cluster)] ──> [App Pod]
                                            (Tambahan hop proxy di dalam Node)

Out-of-Cluster Controller (AWS ALB):
  Client ──> [AWS Application Load Balancer (L7 Eksternal)] ───────────────> [App Pod]
                                            (Paket langsung masuk ke Pod via Target Group AWS)
  • Cara Kerja: Setiap kali kita membuat Ingress Resource, controller ini akan memanggil API AWS untuk membuat satu unit ALB fisik. ALB akan langsung mendaftarkan alamat IP Pod aplikasi kita ke dalam AWS Target Group. Lalu lintas dari luar akan masuk ke ALB eksternal cloud, lalu mengalir langsung ke kartu jaringan virtual Pod (AWS VPC CNI target group) tanpa melewati lapisan proxy tambahan di dalam kluster.
  • Kelebihan: Integrasi native yang luar biasa dengan fitur keamanan AWS (AWS WAF untuk firewall aplikasi web, AWS Shield untuk perlindungan DDoS, dan ACM untuk sertifikat SSL otomatis). Tidak ada konsumsi RAM/CPU tambahan di dalam node worker kluster untuk memproses reverse proxy.
  • Kekurangan: Bersifat vendor-locked (hanya bisa berjalan di AWS). Setiap pembuatan ALB fisik eksternal membutuhkan waktu provisi beberapa menit dan memicu penambahan biaya tagihan AWS secara signifikan jika tidak dikonfigurasi dengan fitur IngressGroup.
  • Use Case Terbaik: Kluster produksi EKS di AWS yang memiliki persyaratan audit keamanan ketat (harus dilindungi AWS WAF) dan ingin mengoptimalkan latensi dengan memangkas lapisan in-cluster proxy.

Pohon Keputusan (Decision Tree) Pemilihan Controller #

Untuk mempermudah kita menentukan pilihan, mari kita ikuti alur keputusan berikut:

flowchart TD
    Start["Di mana kluster Kubernetes dijalankan?"] --> Cloud{"Cloud Publik atau On-Premise?"}
    
    Cloud -- "AWS EKS" --> AWSRequirement{"Butuh AWS WAF / Shield untuk compliance?"}
    AWSRequirement -- "Ya" --> AWSALB["Gunakan AWS Load Balancer Controller (ALB)"]
    AWSRequirement -- "Tidak" --> Performance{"Sering rolling update / ganti konfigurasi rute?"}
    
    Cloud -- "GCP GKE" --> GKECDN{"Butuh Google Cloud CDN / Armor?"}
    GKECDN -- "Ya" --> GKEIngress["Gunakan GKE Ingress bawaan"]
    GKECDN -- "Tidak" --> Performance
    
    Cloud -- "On-Premise / Bare-Metal" --> Performance
    
    Performance -- "Ya (Dinamis)" --> Traefik["Gunakan Traefik Ingress (CRD IngressRoute)"]
    Performance -- "Tidak (Statis)" --> CoreChoice{"Butuh throughput maksimal & latensi konsisten?"}
    
    CoreChoice -- "Ya (Ultra Perf)" --> HAProxy["Gunakan HAProxy Ingress"]
    CoreChoice -- "Tidak (Umum)" --> Nginx["Gunakan NGINX Ingress Controller (kubernetes/ingress-nginx)"]

Mengoperasikan Multi-Ingress Controller Berdampingan #

Pada kluster produksi skala besar, kita sering kali membutuhkan lebih dari satu Ingress Controller secara bersamaan. Sebagai contoh, kita mendeploy NGINX Ingress Controller untuk menangani lalu lintas internal antar tim developer, dan mendeploy AWS ALB Controller untuk menangani lalu lintas publik yang membutuhkan proteksi AWS WAF.

Untuk memfasilitasi skenario ini, kita menggunakan objek IngressClass untuk mendaftarkan dan memisahkan setiap controller.

1. Mendaftarkan IngressClass #

Pertama, kita daftarkan kelas nginx-internal dan aws-alb-public ke API Server Kubernetes:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx-internal
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true" # Jadikan kelas ini sebagai default jika spec dikosongkan
spec:
  controller: k8s.io/ingress-nginx # Menunjuk driver NGINX
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: aws-alb-public
spec:
  controller: ingress.k8s.aws/alb # Menunjuk driver AWS Load Balancer Controller

2. Mengarahkan Ingress Resource ke Controller yang Tepat #

Developer cukup menuliskan properti ingressClassName di dalam manifes Ingress Resource mereka untuk memilih pintu gerbang mana yang ingin mereka gunakan:

# Ingress A: Menggunakan NGINX Internal
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: internal-api-route
  namespace: production
spec:
  ingressClassName: nginx-internal # Memilih gerbang NGINX
  rules:
    - host: internal.mycompany.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: user-service
                port:
                  number: 80
---
# Ingress B: Menggunakan AWS ALB Public
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: public-web-route
  namespace: production
spec:
  ingressClassName: aws-alb-public # Memilih gerbang AWS ALB
  rules:
    - host: www.mycompany.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: landing-page-service
                port:
                  number: 80

Anti-Pattern vs Solusi dalam Pemilihan Ingress Controller #

Mari kita pelajari beberapa kesalahan fatal terkait deployment Ingress Controller di kluster produksi beserta perbandingan kodenya.

Anti-Pattern 1: Mengabaikan Pengelompokan ALB (IngressGroup) di AWS EKS #

Kita membuat 15 manifes Ingress Resource yang berbeda untuk mengarahkan rute 15 microservices di AWS EKS menggunakan AWS Load Balancer Controller tanpa menyertakan parameter pengelompokan.

Kode Manifest Salah (Satu Ingress = Satu ALB Fisik Baru) #

# JANGAN LAKUKAN INI: Memboroskan biaya cloud provider
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: service-billing-ingress
  namespace: production
spec:
  ingressClassName: aws-alb-public
  rules:
    - host: app.mycompany.com
      http:
        paths:
          - path: /billing
            pathType: Prefix
            backend:
              service:
                name: billing-service
                port:
                  number: 80

Konsekuensi Buruk #

AWS Load Balancer Controller akan memicu pembuatan 15 unit Application Load Balancer (ALB) fisik terpisah di akun AWS kita. Hal ini memicu lonjakan tagihan AWS bulanan hingga ratusan dolar secara tidak berguna, karena kita terpaksa membayar biaya sewa 15 load balancer fisik luar yang sebenarnya masing-masing hanya menangani lalu lintas data yang sedikit.

Kode Solusi (Menggunakan IngressGroup untuk Berbagi Satu ALB) #

Kita wajib menambahkan annotation alb.ingress.kubernetes.io/group.name pada setiap manifes Ingress. Hal ini menginstruksikan AWS Controller agar menggabungkan aturan routing dari seluruh Ingress ke dalam satu unit ALB fisik yang sama untuk menghemat pengeluaran biaya cloud.

# SOLUSI: Mengelompokkan banyak Ingress ke dalam satu ALB fisik
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: service-billing-ingress
  namespace: production
  annotations:
    alb.ingress.kubernetes.io/group.name: "production-shared-alb" # Nama group wajib sama antar Ingress
spec:
  ingressClassName: aws-alb-public
  rules:
    - host: app.mycompany.com
      http:
        paths:
          - path: /billing
            pathType: Prefix
            backend:
              service:
                name: billing-service
                port:
                  number: 80

Anti-Pattern 2: Menuliskan Puluhan Annotations Kompleks pada Ingress Standard #

Kita menggunakan Ingress standar Kubernetes, tetapi kita membutuhkan konfigurasi routing yang sangat rumit (seperti validasi CORS kustom, penambahan header HTTP dinamis, rate limiting per IP, dan URL redirection). Kita menuliskan semua logic ini di dalam blok annotations.

Kode Manifest Salah (Annotations Hell pada Ingress Standar) #

# JANGAN LAKUKAN INI: Manifes menjadi kotor dan rawan kesalahan ketik (typo)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: messy-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/limit-connections: "5"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "15"
    # Puluhan baris anotasi tidak aman tanpa validasi sintaksis YAML
spec:
  ingressClassName: nginx
  # ... rules ...

Konsekuensi Buruk #

Annotations di Kubernetes hanyalah tipe data string mentah bebas (untyped free-text). Kubernetes API Server tidak dapat melakukan validasi tipe data (type safety) terhadap nilai annotations. Jika kita salah mengetikkan satu huruf pada nama annotation (misalnya typo cors-allow-methdos), aturan tersebut akan diabaikan oleh controller secara diam-diam tanpa ada pesan error, memicu celah keamanan atau kegagalan konfigurasi yang sulit dilacak.

Kode Solusi (Menggunakan CRD IngressRoute Traefik yang Tipe-Aman) #

Jika kita menggunakan Traefik Ingress, kita disarankan menggunakan objek Custom Resource Definition (CRD) bawaan mereka, yaitu IngressRoute. Objek ini menggantikan annotations standar dengan struktur kode deklaratif yang tipe-aman dan tervalidasi langsung oleh API Server saat dijalankan.

# SOLUSI: Konfigurasi bersih dan tervalidasi dengan IngressRoute CRD Traefik
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: clean-ingress-route
  namespace: production
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.mycompany.com`) && PathPrefix(`/billing`)
      kind: Rule
      services:
        - name: billing-service
          port: 80
      middlewares:
        - name: secure-headers-middleware # Menunjuk ke middleware terpisah yang terstruktur
        - name: strict-ratelimit-middleware

Ringkasan #

  • NGINX Ingress adalah standar umum: Sangat dewasa dan memiliki komunitas terbesar; namun proses reload konfigurasinya dapat memberikan dampak minor pada kluster skala sangat raksasa.
  • Traefik unggul dalam kedinamisan: Menerapkan hot-reload tanpa restart proses untuk zero-downtime, memiliki dashboard visual internal, serta mendukung CRD IngressRoute yang tipe-aman.
  • HAProxy untuk latensi ultra-rendah: Memberikan throughput tertinggi dan penanganan sticky session terbaik; namun komunitas penggunanya di Kubernetes relatif lebih kecil.
  • AWS ALB Controller memotong in-cluster proxy: Mengintegrasikan Ingress langsung dengan Application Load Balancer fisik AWS VPC CNI target group; menghemat RAM/CPU node worker.
  • Wajib gunakan IngressGroup di AWS: Kelompokkan objek Ingress kita menggunakan parameter group.name untuk menghindari pembengkakan biaya tagihan cloud akibat pembuatan ALB fisik terpisah.
  • Gunakan IngressClass untuk multi-controller: Daftarkan objek IngressClass terpisah untuk membagi lalu lintas secara teratur (misalnya memisahkan gerbang internal NGINX dengan gerbang publik ALB).

← Sebelumnya: Service Mesh   Berikutnya: Network Troubleshooting →

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