Portal/Notes πŸ“
Cka

Ingress: Rate Limit

Versi Bahasa Indonesia. Baca dalam Bahasa Inggris

Di production, setup rate limit itu sangat penting. Ini bisa digunakan untuk memitigasi serangan DDoS.

Setup Rate Limit

Nginx ingress memiliki banyak annotations dan beberapa di antaranya bisa digunakan untuk setup rate limit.

  • nginx.ingress.kubernetes.io/limit-rps
    • Jumlah request yang diterima dari suatu IP setiap detik.
    • Burst limit per detik adalah limit-rps * limit-burst-multiplier.
  • nginx.ingress.kubernetes.io/limit-burst-multiplier
    • Default: 5.

Mari update definisi ingress kita dan tambahkan annotations di atas di bagian metadata.annotations.

annotations:
  nginx.ingress.kubernetes.io/limit-rps: "1"
  nginx.ingress.kubernetes.io/limit-burst-multiplier: "1"

Annotation ini akan membatasi request per detik hanya 1.

Apply perubahannya dan validasi menggunakan kubectl describe. Kita seharusnya melihat annotations di hasilnya.

➜ kubectl describe ingress simple-ingress          
Name:             simple-ingress
Labels:           <none>
Namespace:        default
Address:          192.168.49.2
Ingress Class:    nginx
Default backend:  <default>
TLS:
  simple-tls terminates simple-go.mine
Rules:
  Host            Path  Backends
  ----            ----  --------
  simple-go.mine  
                  /   simple-go:8080 (10.244.0.88:8080,10.244.0.89:8080,10.244.0.90:8080)
Annotations:      nginx.ingress.kubernetes.io/limit-burst-multiplier: 1
                  nginx.ingress.kubernetes.io/limit-rps: 1
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    71s (x7 over 27h)  nginx-ingress-controller  Scheduled for sync

Mari test menggunakan curl dengan request berurutan seperti ini.

➜ curl --resolve "simple-go.mine:443:127.0.0.1" -i -k \
    https://simple-go.mine \
    https://simple-go.mine \
    https://simple-go.mine

Output:

HTTP/2 200 
date: Sat, 01 Feb 2025 06:31:29 GMT
content-type: text/plain; charset=utf-8
content-length: 65

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
HTTP/2 200 
date: Sat, 01 Feb 2025 06:31:29 GMT
content-type: text/plain; charset=utf-8
content-length: 65

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
HTTP/2 503 
date: Sat, 01 Feb 2025 06:31:29 GMT
content-type: text/html
content-length: 190

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>

Kita bisa lihat dari output di atas bahwa rate limiting bekerja sesuai ekspektasi. Ini akan mengembalikan response status 503 jika limit terlampaui. Request kedua diizinkan karena diinterpretasikan sebagai request tunggal di detik yang berbeda.

Kita mungkin ingin mengubah default response status menjadi 429 Too Many Requests, karena ini adalah status response yang lebih tepat untuk memberi tahu user bahwa rate limit terlampaui.

Status code 429 mengindikasikan bahwa user telah mengirim terlalu banyak request dalam jangka waktu tertentu ("rate limiting").

Untuk mengubah default response status code untuk rate limit yang terlampaui, kita perlu mengubah configmap nginx ingress yang bernama ingress-nginx-controller di namespace ingress-nginx. Kita bisa menggunakan perintah kubectl edit di bawah untuk mengedit configmap, yang akan membuka editor vim.

➜ kubectl -n ingress-nginx edit configmaps ingress-nginx-controller 

Tambahkan key value pair ini ke bagian data.

limit-req-status-code: "429"

Simpan dan tunggu beberapa detik untuk ingress melakukan sync dengan configmap terbaru. Lalu test lagi menggunakan perintah curl yang sama. Kita akan melihat response berubah menjadi 429 Too Many Requests.

HTTP/2 200 
date: Sat, 01 Feb 2025 07:03:03 GMT
content-type: text/plain; charset=utf-8
content-length: 65

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
HTTP/2 200 
date: Sat, 01 Feb 2025 07:03:04 GMT
content-type: text/plain; charset=utf-8
content-length: 65

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
HTTP/2 429 
date: Sat, 01 Feb 2025 07:03:04 GMT
content-type: text/html
content-length: 162

<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx</center>
</body>
</html>

Kita juga bisa mengecualikan alamat IP tertentu dari rate limiting menggunakan annotation nginx.ingress.kubernetes.io/limit-whitelist. Untuk daftar annotations yang didukung oleh nginx ingress, bisa baca lebih lanjut di sini.

References


Edit on GitHub

Last updated on

Ingress: Rate Limit | Faisal Affan