Portal/Notes πŸ“
Cka

Ingress: CRD (Custom Resource Definition)

Versi Bahasa Indonesia. Baca dalam Bahasa Inggris

Ingress CRD adalah custom resource yang dibuat untuk memperluas Kubernetes dan menyediakan kemampuan ingress yang lebih canggih dibandingkan resource Ingress standar.

Sementara object Ingress Kubernetes standar menangani routing dasar (seperti memetakan URL path ke service), beberapa use case membutuhkan fleksibilitas yang lebih. Contohnya:

  • Advanced traffic management (misalnya: canary releases, A/B testing).
  • Complex routing (misalnya: routing berdasarkan headers atau cookies).
  • Security policies (misalnya: JWT authentication, IP whitelisting).

Untuk mencapai ini, banyak Ingress controller (seperti NGINX, Traefik, Istio) mendefinisikan CRD mereka sendiri untuk mengaktifkan konfigurasi yang lebih canggih.

NGINX

NGINX Ingress Controller untuk Kubernetes mendukung custom resource canggih yang disebut VirtualServer dan VirtualServerRoute yang memungkinkan routing kompleks, traffic splitting, custom load balancing, dan konfigurasi granular. Ini lebih fleksibel daripada resource Ingress standar dan berguna untuk skenario tingkat lanjut.

Resource VirtualServer dan VirtualServerRoute adalah konfigurasi load balancing yang direkomendasikan sebagai alternatif untuk resource Ingress.

Memasang NGINX CRD cukup canggih dan sulit, pastikan kamu membaca dan mengikuti panduan instalasi di Dokumentasi Resmi.

Traffic Splitting

Salah satu skenario yang bisa kita gunakan adalah traffic splitting atau canary deployment. Kamu juga bisa menggunakan ini untuk A/B testing.

Untuk menambahkan traffic splitting di NGINX VirtualServer relatif mudah. Kita hanya perlu menambahkan daftar upstream (2 atau lebih) dan kemudian di spec routes.action kita tambahkan split dan weight untuk setiap upstream.

Create Deployment

Mari buat dua deployment menggunakan image nginxdemos/nginx-hello:plain-text, image ini akan mengembalikan informasi request dan server sehingga kita bisa membedakan responsenya.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app-v1
  template:
    metadata:
      labels:
        app: my-app-v1
    spec:
      containers:
      - name: my-app-v1
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 8080

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app-v2
  template:
    metadata:
      labels:
        app: my-app-v2
    spec:
      containers:
      - name: my-app-v2
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 8080

Create Service

Kemudian buat service untuk kedua aplikasi kita menggunakan perintah kubectl expose dan cek apakah service sudah terbuat dengan benar.

➜ kubectl expose deployment my-app-v1 --port=80 --target-port=8080                  
service/my-app-v1 exposed
➜ kubectl expose deployment my-app-v2 --port=80 --target-port=8080                 
service/my-app-v2 exposed
➜ kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    25d
my-app-v1    ClusterIP   10.101.208.134   <none>        80/TCP     9s
my-app-v2    ClusterIP   10.97.235.79     <none>        80/TCP     4s

Create VirtualServer

Sekarang mari buat definisi VirtualServer. Berikut contoh pembagian traffic ke 2 upstream yang berbeda dengan weight 80 dan 20. Ini berarti 80% traffic akan menuju my-app-v1 dan sisanya ke my-app-v2.

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: my-app
spec:
  host: my-app.local
  upstreams:
  - name: my-app-v1
    service: my-app-v1
    port: 80
  - name: my-app-v2
    service: my-app-v2
    port: 80
  routes:
  - path: "/"
    splits:
    - weight: 80
      action:
        pass: my-app-v1
    - weight: 20
      action:
        pass: my-app-v2

Apply file yaml tersebut dan kamu bisa menggunakan kubectl describe untuk mendapatkan detail dan statusnya. Karena kita menggunakan minikube, jangan lupa untuk memulai minikube tunnel setelah mengaplikasikan VirtualServer.

➜ kubectl apply -f ingress-nginx-crd.yaml 
virtualserver.k8s.nginx.org/my-app created
➜ kubectl describe virtualserver my-app
Name:         my-app
...
Status:
  External Endpoints:
    Ip:     127.0.0.1
    Ports:  [80,443]
  Message:  Configuration for default/my-app was added or updated 
  Reason:   AddedOrUpdated
  State:    Valid
Events:
  Type     Reason                     Age   From                      Message
  ----     ------                     ----  ----                      -------
  Normal   AddedOrUpdated             10m   nginx-ingress-controller  Configuration for default/my-app was added or updated

Test and Validate

Kemudian kita bisa mencoba membuat beberapa request curl ke custom ingress CRD yang baru saja kita buat seperti ini.

➜ curl --resolve "my-app.local:80:127.0.0.1" \
    http://my-app.local \
    http://my-app.local \
    http://my-app.local \
    http://my-app.local \
    http://my-app.local

Server address: 10.244.0.96:8080
Server name: my-app-v1-6dd7f778db-js6kr
Date: 06/Mar/2025:06:18:32 +0000
URI: /
Request ID: 5e251a15a14de4174b461bbe54369b15

Server address: 10.244.0.95:8080
Server name: my-app-v1-6dd7f778db-5766t
Date: 06/Mar/2025:06:18:32 +0000
URI: /
Request ID: 37b1233a3d8d90900c419d799a523675

Server address: 10.244.0.95:8080
Server name: my-app-v1-6dd7f778db-5766t
Date: 06/Mar/2025:06:18:32 +0000
URI: /
Request ID: 206b75cc134cad35c9b2efde77d8cb8c

Server address: 10.244.0.95:8080
Server name: my-app-v1-6dd7f778db-5766t
Date: 06/Mar/2025:06:18:32 +0000
URI: /
Request ID: 2de3128b19fe664e0eef02ffbbef6044

Server address: 10.244.0.94:8080
Server name: my-app-v2-6fd4d596c4-8pdb6
Date: 06/Mar/2025:06:18:32 +0000
URI: /
Request ID: af3f2fb5e2848d2b79bbf367845b544b

Seperti yang bisa dilihat, dari 5 request berturut-turut, 4 di antaranya menuju my-app-v1 dan hanya 1 menuju my-app-v2 sesuai ekspektasi. Ini sangat berguna jika kamu ingin melakukan Canary release untuk memastikan bahwa versi baru akan berjalan seperti yang diharapkan sebelum memindahkan semua traffic ke versi tersebut.

References


Edit on GitHub

Last updated on

Ingress: CRD (Custom Resource Definition) | Faisal Affan