Skip to content

Conversation

DeshDeepakKant
Copy link
Contributor

This PR adds comprehensive documentation for the rate limiting feature in Kmesh's Kernel-Native mode. This guide includes:

  1. Overview of rate limiting and its benefits in Kmesh
  2. Detailed explanation of how rate limiting works in Kmesh using the token bucket algorithm
  3. Configuration instructions with YAML examples for both regular and external services
  4. Testing procedures using fortio to validate rate limiting functionality
  5. Troubleshooting tips and best practices

The documentation is structured to help users understand, configure, and test rate limiting in Kmesh's Kernel-Native mode, providing them with the tools to protect their services from excessive traffic directly at the kernel level.

Fixes kmesh-net/kmesh#859

@kmesh-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign lizhencheng9527 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

netlify bot commented Jun 11, 2025

Deploy Preview for kmesh-net ready!

Name Link
🔨 Latest commit 53976b9
🔍 Latest deploy log https://app.netlify.com/projects/kmesh-net/deploys/68495a4a57640f0008188bf2
😎 Deploy Preview https://deploy-preview-204--kmesh-net.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@DeshDeepakKant
Copy link
Contributor Author

I have tested this docs on my local Linux system, here is the terminal logs for reference

=== KMESH RATE LIMITING TEST ===
Step 1: Checking Kubernetes and Kmesh status
Client Version: v1.32.5
Kustomize Version: v5.5.0
Server Version: v1.30.0
WARNING: version difference between client (1.32) and server (1.30) exceeds the
supported minor
 version skew of +/-1
               kmesh-system         kmesh-rkw8b
    1/1     Running   47 (135m
 ago)   4d5h
anya@pop-os:~/kmesh$ echo "Step 2: Applying the rate limit example configuration" && kubectl ap
ply -f website/docs/aecho "Step 2: Applying the rate limit example configuration" && kubectl ap
ply -f website/docs/application-layer/examples/rate-limit-example.yaml
Step 2: Applying the rate limit example configuration
service/httpbin created
deployment.apps/httpbin created
envoyfilter.networking.istio.io/httpbin-ratelimit created
serviceentry.networking.istio.io/external-svc created
envoyfilter.networking.istio.io/external-service-ratelimit created
service/sleep created
deployment.apps/sleep created
anya@pop-os:~/kmesh$ echo "Step 3: Waiting for pods to be ready" && sleep 5 && kubectl get pods
 -l app=httpbin && kuecho "Step 3: Waiting for pods to be ready" && sleep 5 && kubectl get pods
 -l app=httpbin && kubectl get pods -l app=sleep
Step 3: Waiting for pods to be ready
NAME                       READY   STATUS    RESTARTS   AGE
httpbin-54cb7c6776-twxwz   2/2     Running   0          14s
NAME                     READY   STATUS    RESTARTS   AGE
sleep-58764cf474-fz4m6   2/2     Running   0          14s
anya@pop-os:~/kmesh$ echo "Step 4: Verifying the EnvoyFilter configuration" && kubectl get envo
yfilter httpbin-ratelecho "Step 4: Verifying the EnvoyFilter configuration" && kubectl get envo
yfilter httpbin-ratelimit -o yaml | grep -A10 token_bucket
Step 4: Verifying the EnvoyFilter configuration
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"EnvoyFilter","metadata":{"annotation
s":{},"name":"httpbin-ratelimit","namespace":"default"},"spec":{"configPatches":[{"applyTo":"NE
TWORK_FILTER","match":{"context":"SIDECAR_INBOUND","listener":{"filterChain":{"filter":{"name":
"envoy.filters.network.tcp_proxy"}}}},"patch":{"operation":"INSERT_BEFORE","value":{"name":"env
oy.filters.network.local_ratelimit","typed_config":{"@type":"type.googleapis.com/envoy.extensio
ns.filters.network.local_ratelimit.v3.LocalRateLimit","stat_prefix":"local_rate_limit","token_b
ucket":{"fill_interval":"60s","max_tokens":5,"tokens_per_fill":5}}}}}],"workloadSelector":{"lab
els":{"app":"httpbin"}}}}
  creationTimestamp: "2025-06-11T06:23:09Z"
  generation: 1
  name: httpbin-ratelimit
  namespace: default
  resourceVersion: "218445"
  uid: 09139523-6f1e-40c9-8265-b9c0eca73eb6
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
--
          token_bucket:
            fill_interval: 60s
            max_tokens: 5
            tokens_per_fill: 5
  workloadSelector:
    labels:
      app: httpbin
anya@pop-os:~/kmesh$ echo "Step 5: Testing with low load (should succeed)" && kubectl exec -it 
deploy/sleep -- sh -c "for i in {1..3}; do echo \"Request $i:\" && curl -s -o /dev/null -w '%{h
ttp_code}\n' http://hecho "Step 5: Testing with low load (should succeed)" && kubectl exec -it 
deploy/sleep -- sh -c "for i in {1..3}; do echo \"Request $i:\" && curl -s -o /dev/null -w '%{h
ttp_code}\n' http://httpbin:8000/get; sleep 1; done"
Step 5: Testing with low load (should succeed)
Request :
200
anya@pop-os:~/kmesh$ echo "Step 6: Checking if fortio is available for load testing" && kubectl
 get pods -l app=fortecho "Step 6: Checking if fortio is available for load testing" && kubectl
 get pods -l app=fortio
Step 6: Checking if fortio is available for load testing
NAME                      READY   STATUS    RESTARTS        AGE
fortio-8448778768-7gx7m   1/1     Running   11 (136m ago)   4d5h
anya@pop-os:~/kmesh$ echo "Step 7: Testing with high load (should trigger rate limiting)" && ku
bectl exec -it deployecho "Step 7: Testing with high load (should trigger rate limiting)" && ku
bectl exec -it deploy/fortio -- fortio load -c 10 -qps 20 -t 5s http://httpbin:8000/get
Step 7: Testing with high load (should trigger rate limiting)
06:23:52.369 r1 [INF] scli.go:122> Starting, command="Φορτίο", version="1.69.5 h1:h+42fJ1HF61Jj
+WgPmC+C2wPtM5Ct8JLHSLDyEgGID4= go1.23.9 amd64 linux", go-max-procs=12
Fortio 1.69.5 running at 20 queries per second, 12->12 procs, for 5s: http://httpbin:8000/get
06:23:52.370 r1 [INF] httprunner.go:121> Starting http test, run=0, url="http://httpbin:8000/ge
t", threads=10, qps="20.0", warmup="parallel", conn-reuse=""
06:23:52.378 r74 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=6, run=0
06:23:52.378 r69 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=1, run=0
06:23:52.379 r75 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=7, run=0
06:23:52.380 r72 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=4, run=0
06:23:52.384 r68 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=0, run=0
06:23:52.384 r76 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=8, run=0
Aborting because of error 503 for http://httpbin:8000/get (318 bytes)
command terminated with exit code 1
anya@pop-os:~/kmesh$ echo "Step 8: Testing with moderate load (should partially trigger rate li
miting)" && kubectl exec -it deploy/fortio -- fortio load -c 5 -qps 5 -t 5s http://httpbin:8000
anya@pop-os:~/kmesh$ echo "Step 8: Testing with moderate load (should partially trigger rate li
miting)" && kubectl exec -it deploy/fortio -- fortio load -c 5 -qps 5 -t 5s http://httpbin:8000
/get
Step 8: Testing with moderate load (should partially trigger rate limiting)
06:23:57.703 r1 [INF] scli.go:122> Starting, command="Φορτίο", version="1.69.5 h1:h+42fJ1HF61Jj
+WgPmC+C2wPtM5Ct8JLHSLDyEgGID4= go1.23.9 amd64 linux", go-max-procs=12
Fortio 1.69.5 running at 5 queries per second, 12->12 procs, for 5s: http://httpbin:8000/get
06:23:57.704 r1 [INF] httprunner.go:121> Starting http test, run=0, url="http://httpbin:8000/ge
t", threads=5, qps="5.0", warmup="parallel", conn-reuse=""
06:23:57.713 r30 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=2, run=0
06:23:57.713 r31 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=3, run=0
06:23:57.713 r32 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=4, run=0
06:23:57.713 r28 [WRN] http_client.go:1151> Non ok http code, code=503, status="HTTP/1.1 503", 
thread=0, run=0
Aborting because of error 503 for http://httpbin:8000/get (318 bytes)
command terminated with exit code 1
anya@pop-os:~/kmesh$ echo "Step 9: Testing with very low load (should succeed)" && kubectl exec
 -it deploy/fortio --echo "Step 9: Testing with very low load (should succeed)" && kubectl exec
 -it deploy/fortio -- fortio load -c 1 -qps 1 -t 5s http://httpbin:8000/get
Step 9: Testing with very low load (should succeed)
06:24:02.645 r1 [INF] scli.go:122> Starting, command="Φορτίο", version="1.69.5 h1:h+42fJ1HF61Jj
+WgPmC+C2wPtM5Ct8JLHSLDyEgGID4= go1.23.9 amd64 linux", go-max-procs=12
Fortio 1.69.5 running at 1 queries per second, 12->12 procs, for 5s: http://httpbin:8000/get
06:24:02.646 r1 [INF] httprunner.go:121> Starting http test, run=0, url="http://httpbin:8000/ge
t", threads=1, qps="1.0", warmup="parallel", conn-reuse=""
Starting at 1 qps with 1 thread(s) [gomax 12] for 5s : 5 calls each (total 5)
06:24:07.660 r1 [INF] periodic.go:851> T000 ended after 5.007477737s : 5 calls. qps=0.998506685
9219867
Ended after 5.007531428s : 5 calls. qps=0.9985
06:24:07.660 r1 [INF] periodic.go:581> Run ended, run=0, elapsed=5007531428, calls=5, qps=0.998
4959798838431
Sleep times : count 4 avg 1.2445273 +/- 0.002207 min 1.242658934 max 1.2481219590000001 sum 4.9
7810936
Aggregated Function Time : count 5 avg 0.001943669 +/- 0.0001031 min 0.001804903 max 0.00207196
7 sum 0.009718345
# range, mid point, percentile, count
>= 0.0018049 <= 0.002 , 0.00190245 , 60.00, 3
> 0.002 <= 0.00207197 , 0.00203598 , 100.00, 2
# target 50% 0.00195123
# target 75% 0.00202699
# target 90% 0.00205398
# target 99% 0.00207017
# target 99.9% 0.00207179
Error cases : no data
# Socket and IP used for each connection:
[0]   1 socket used, resolved to 10.96.211.43:8000, connection timing : count 1 avg 0.000740547
 +/- 0 min 0.000740547 max 0.000740547 sum 0.000740547
Connection time histogram (s) : count 1 avg 0.000740547 +/- 0 min 0.000740547 max 0.000740547 s
um 0.000740547
# range, mid point, percentile, count
>= 0.000740547 <= 0.000740547 , 0.000740547 , 100.00, 1
# target 50% 0.000740547
# target 75% 0.000740547
# target 90% 0.000740547
# target 99% 0.000740547
# target 99.9% 0.000740547
Sockets used: 1 (for perfect keepalive, would be 1)
Uniform: false, Jitter: false, Catchup allowed: true
IP addresses distribution:
10.96.211.43:8000: 1
Code 200 : 5 (100.0 %)
Response Header Sizes : count 5 avg 307 +/- 0 min 307 max 307 sum 1535
Response Body/Total Sizes : count 5 avg 482 +/- 0 min 482 max 482 sum 2410
All done 5 calls (plus 1 warmup) 1.944 ms avg, 1.0 qps
anya@pop-os:~/kmesh$ echo "Step 10: Verifying Kmesh mode" && kubectl describe pod -n kmesh-syst
em $(kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}') | g
anya@pop-os:~/kmesh$ echo "Step 10: Verifying Kmesh mode" && kubectl describe pod -n kmesh-syst
em $(kubectl get pods -n kmesh-system -l app=kmesh -o jsonpath='{.items[0].metadata.name}') | g
rep -A2 Args
Step 10: Verifying Kmesh mode
    Args:
      ./start_kmesh.sh --mode=dual-engine --enable-bypass=false
    State:          Running
anya@pop-os:~/kmesh$ echo "Step 11: Cleaning up" && kubectl delete -f website/docs/application-
layer/examples/rate-lecho "Step 11: Cleaning up" && kubectl delete -f website/docs/application-
layer/examples/rate-limit-example.yaml
Step 11: Cleaning up
service "httpbin" deleted
deployment.apps "httpbin" deleted
envoyfilter.networking.istio.io "httpbin-ratelimit" deleted
serviceentry.networking.istio.io "external-svc" deleted
envoyfilter.networking.istio.io "external-service-ratelimit" deleted
service "sleep" deleted
deployment.apps "sleep" deleted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants