Skip to content

Commit df1119e

Browse files
authored
Rate limit with zone sync and scale (#7521)
1 parent 12cf0fa commit df1119e

File tree

13 files changed

+878
-72
lines changed

13 files changed

+878
-72
lines changed

internal/configs/ingress.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ func generateNginxCfg(p NginxCfgParams) (version1.IngressNginxConfig, Warnings)
272272

273273
if cfgParams.LimitReqRate != "" {
274274
zoneName := p.ingEx.Ingress.Namespace + "/" + p.ingEx.Ingress.Name
275+
if p.ingEx.ZoneSync {
276+
zoneName = fmt.Sprintf("%v_sync", zoneName)
277+
}
275278
loc.LimitReq = &version1.LimitReq{
276279
Zone: zoneName,
277280
Burst: cfgParams.LimitReqBurst,
@@ -284,7 +287,12 @@ func generateNginxCfg(p NginxCfgParams) (version1.IngressNginxConfig, Warnings)
284287
if !limitReqZoneExists(limitReqZones, zoneName) {
285288
rate := cfgParams.LimitReqRate
286289
if cfgParams.LimitReqScale && p.ingressControllerReplicas > 0 {
287-
rate = scaleRatelimit(rate, p.ingressControllerReplicas)
290+
if p.ingEx.ZoneSync {
291+
warningText := fmt.Sprintf("Ingress %s/%s: both zone sync and rate limit scale are enabled, the rate limit scale value will not be used.", p.ingEx.Ingress.Namespace, p.ingEx.Ingress.Name)
292+
nl.Warn(l, warningText)
293+
} else {
294+
rate = scaleRatelimit(rate, p.ingressControllerReplicas)
295+
}
288296
}
289297
limitReqZones = append(limitReqZones, version1.LimitReqZone{
290298
Name: zoneName,

internal/configs/ingress_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ func TestGenerateNginxCfgForLimitReqZoneSync(t *testing.T) {
11731173

11741174
expectedZones := []version1.LimitReqZone{
11751175
{
1176-
Name: "default/cafe-ingress",
1176+
Name: "default/cafe-ingress_sync",
11771177
Key: "${request_uri}",
11781178
Size: "11m",
11791179
Rate: "200r/s",
@@ -1337,14 +1337,11 @@ func TestGenerateNginxCfgForLimitReqWithScaling(t *testing.T) {
13371337
for _, server := range result.Servers {
13381338
for _, location := range server.Locations {
13391339
if !reflect.DeepEqual(location.LimitReq, expectedReqs) {
1340-
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", result.LimitReqZones, expectedZones)
1340+
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", location.LimitReq, expectedReqs)
13411341
}
13421342
}
13431343
}
13441344

1345-
if !reflect.DeepEqual(result.LimitReqZones, expectedZones) {
1346-
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", result.LimitReqZones, expectedZones)
1347-
}
13481345
if len(warnings) != 0 {
13491346
t.Errorf("generateNginxCfg returned warnings: %v", warnings)
13501347
}
@@ -1431,9 +1428,6 @@ func TestGenerateNginxCfgForMergeableIngressesForLimitReqWithScaling(t *testing.
14311428
}
14321429
}
14331430

1434-
if !reflect.DeepEqual(result.LimitReqZones, expectedZones) {
1435-
t.Errorf("generateNginxCfg returned \n%v, but expected \n%v", result.LimitReqZones, expectedZones)
1436-
}
14371431
if len(warnings) != 0 {
14381432
t.Errorf("generateNginxCfg returned warnings: %v", warnings)
14391433
}

internal/configs/version1/__snapshots__/template_test.snap

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ server {
12171217
# configuration for default/myingress
12181218
12191219
1220-
limit_req_zone ${binary_remote_addr} zone=default/zone1:10m rate=200r/s sync;
1220+
limit_req_zone ${binary_remote_addr} zone=default/zone1_sync:10m rate=200r/s sync;
12211221
12221222
12231223
@@ -1235,6 +1235,33 @@ server {
12351235
12361236
12371237
1238+
location / {
1239+
set $service "";
1240+
status_zone "";
1241+
proxy_http_version 1.1;
1242+
1243+
proxy_connect_timeout ;
1244+
proxy_read_timeout ;
1245+
proxy_send_timeout ;
1246+
client_max_body_size ;
1247+
1248+
proxy_set_header Host $host;
1249+
proxy_set_header X-Real-IP $remote_addr;
1250+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
1251+
proxy_set_header X-Forwarded-Host $host;
1252+
proxy_set_header X-Forwarded-Port $server_port;
1253+
proxy_set_header X-Forwarded-Proto $scheme;
1254+
proxy_buffering off;
1255+
proxy_pass http://test;
1256+
1257+
1258+
limit_req zone=default/myingress_sync burst=100;
1259+
1260+
1261+
limit_req_status 429;
1262+
1263+
}
1264+
12381265
}
12391266
12401267
---

internal/configs/version1/nginx-plus.ingress.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ server {
321321
{{- end}}
322322

323323
{{with $location.LimitReq}}
324-
limit_req zone={{ $location.LimitReq.Zone }} {{if $location.LimitReq.Burst}}burst={{$location.LimitReq.Burst}}{{end}} {{if $location.LimitReq.NoDelay}}nodelay{{else if $location.LimitReq.Delay}}delay={{$location.LimitReq.Delay}}{{end}};
324+
limit_req zone={{ $location.LimitReq.Zone }}{{- if $location.LimitReq.Burst }} burst={{$location.LimitReq.Burst}}{{- end }}{{- if $location.LimitReq.NoDelay }} nodelay{{- else if $location.LimitReq.Delay }} delay={{$location.LimitReq.Delay}}{{- end }};
325325
{{if $location.LimitReq.DryRun}}limit_req_dry_run on;{{end}}
326326
{{if $location.LimitReq.LogLevel}}limit_req_log_level {{$location.LimitReq.LogLevel}};{{end}}
327327
{{if $location.LimitReq.RejectCode}}limit_req_status {{$location.LimitReq.RejectCode}};{{end}}

internal/configs/version1/template_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,11 +1829,22 @@ func TestExecuteTemplate_ForIngressForNGINXPlusWithRequestRateLimitZoneSync(t *t
18291829
Servers: []Server{
18301830
{
18311831
Name: "test.example.com",
1832+
Locations: []Location{
1833+
{
1834+
Path: "/",
1835+
Upstream: testUpstream,
1836+
LimitReq: &LimitReq{
1837+
Zone: "default/myingress_sync",
1838+
Burst: 100,
1839+
RejectCode: 429,
1840+
},
1841+
},
1842+
},
18321843
},
18331844
},
18341845
LimitReqZones: []LimitReqZone{
18351846
{
1836-
Name: "default/zone1",
1847+
Name: "default/zone1_sync",
18371848
Key: "${binary_remote_addr}",
18381849
Size: "10m",
18391850
Rate: "200r/s",
@@ -1850,7 +1861,8 @@ func TestExecuteTemplate_ForIngressForNGINXPlusWithRequestRateLimitZoneSync(t *t
18501861
ingConf := buf.String()
18511862

18521863
wantDirectives := []string{
1853-
"limit_req_zone ${binary_remote_addr} zone=default/zone1:10m rate=200r/s sync;",
1864+
"limit_req_zone ${binary_remote_addr} zone=default/zone1_sync:10m rate=200r/s sync;",
1865+
"limit_req zone=default/myingress_sync burst=100;",
18541866
}
18551867

18561868
for _, want := range wantDirectives {

internal/configs/version2/__snapshots__/templates_test.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,7 @@ map $http_x_version $match_0_0 {
29132913
default 0;
29142914
}
29152915
# HTTP snippet
2916-
limit_req_zone $url zone=pol_rl_test_test_test:10m rate=10r/s sync;
2916+
limit_req_zone $url zone=pol_rl_test_test_test_sync:10m rate=10r/s sync;
29172917

29182918
server {
29192919
listen 80 proxy_protocol;
@@ -2948,7 +2948,7 @@ server {
29482948
allow all;
29492949
limit_req_log_level error;
29502950
limit_req_status 503;
2951-
limit_req zone=pol_rl_test_test_test burst=5 delay=10;
2951+
limit_req zone=pol_rl_test_test_test_sync burst=5 delay=10;
29522952
auth_jwt "My Api";
29532953
auth_jwt_key_file jwk-secret;
29542954
app_protect_enable on;
@@ -3021,7 +3021,7 @@ server {
30213021
deny all;
30223022
deny 127.0.0.1;
30233023
allow all;
3024-
limit_req zone=loc_pol_rl_test_test_test;
3024+
limit_req zone=loc_pol_rl_test_test_test_sync;
30253025

30263026

30273027
proxy_ssl_certificate egress-mtls-secret.pem;

0 commit comments

Comments
 (0)