1
0
Fork 0

Rework servers load-balancer to use the WRR

Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
Julien Salleyron 2022-11-16 11:38:07 +01:00 committed by GitHub
parent 67d9c8da0b
commit fadee5e87b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 2085 additions and 2211 deletions

View file

@ -307,7 +307,13 @@ func (c configBuilder) buildServersLB(namespace string, svc v1alpha1.LoadBalance
passHostHeader := true
lb.PassHostHeader = &passHostHeader
}
lb.ResponseForwarding = conf.ResponseForwarding
if conf.ResponseForwarding != nil && conf.ResponseForwarding.FlushInterval != "" {
err := lb.ResponseForwarding.FlushInterval.Set(conf.ResponseForwarding.FlushInterval)
if err != nil {
return nil, fmt.Errorf("unable to parse flushInterval: %w", err)
}
}
lb.Sticky = svc.Sticky

View file

@ -1283,7 +1283,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:8080",
},
},
PassHostHeader: func(i bool) *bool { return &i }(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-external-svc-with-ipv6-8080": {
@ -1293,7 +1296,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7347]:8080",
},
},
PassHostHeader: func(i bool) *bool { return &i }(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-test-route-6b204d94623b3df4370c": {
@ -1510,6 +1516,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1578,6 +1587,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1629,6 +1641,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1686,6 +1701,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1734,6 +1752,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-test-route-77c62dfe9517144aeeaa": {
@ -1747,6 +1768,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1805,6 +1829,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami2-8080": {
@ -1818,6 +1845,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1871,6 +1901,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1917,6 +1950,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -1988,6 +2024,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami5-8080": {
@ -2001,6 +2040,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-wrr2": {
@ -2028,6 +2070,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami7-8080": {
@ -2041,6 +2086,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2108,6 +2156,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2187,6 +2238,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami5-8080": {
@ -2200,6 +2254,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2270,6 +2327,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"foo-wrr1": {
@ -2305,6 +2365,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"foo-mirror1": {
@ -2328,6 +2391,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"bar-mirrored": {
@ -2430,6 +2496,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami5-8080": {
@ -2443,6 +2512,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2514,6 +2586,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami5-8080": {
@ -2527,6 +2602,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2584,6 +2662,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-whoami2-8080": {
@ -2597,6 +2678,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2717,6 +2801,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2786,6 +2873,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2834,6 +2924,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2903,6 +2996,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -2973,6 +3069,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3041,6 +3140,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3098,6 +3200,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3156,6 +3261,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3200,6 +3308,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3243,6 +3354,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3286,6 +3400,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3533,6 +3650,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3575,7 +3695,7 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(false),
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: "10s"},
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: ptypes.Duration(10 * time.Second)},
},
},
},
@ -3630,6 +3750,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3687,6 +3810,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3733,6 +3859,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3774,6 +3903,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3813,6 +3945,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3852,6 +3987,9 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -3949,7 +4087,10 @@ func TestLoadIngressRoutes(t *testing.T) {
URL: "https://external.domain:443",
},
},
PassHostHeader: Bool(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "default-test",
},
},
@ -3963,7 +4104,10 @@ func TestLoadIngressRoutes(t *testing.T) {
URL: "https://10.10.0.6:8443",
},
},
PassHostHeader: Bool(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "default-default-test",
},
},
@ -4036,6 +4180,9 @@ func TestLoadIngressRoutes(t *testing.T) {
"default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -4923,6 +5070,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -4998,6 +5148,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-test-crossnamespace-route-9313b71dbe6a649d5049": {
@ -5011,6 +5164,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-test-errorpage-errorpage-service": {
@ -5024,6 +5180,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-test-crossnamespace-route-a1963878aac7331b7950": {
@ -5037,6 +5196,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -5111,7 +5273,10 @@ func TestCrossNamespace(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
PassHostHeader: Bool(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "foo-test@kubernetescrd",
},
},
@ -5126,6 +5291,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"default-tr-svc-wrr1": {
@ -5181,6 +5349,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -5227,6 +5398,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
"cross-ns-tr-svc-mirror2": {
@ -5251,6 +5425,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -5294,7 +5471,10 @@ func TestCrossNamespace(t *testing.T) {
URL: "http://10.10.0.2:80",
},
},
PassHostHeader: Bool(true),
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
ServersTransport: "cross-ns-st-cross-ns@kubernetescrd",
},
},
@ -5387,6 +5567,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -5431,6 +5614,9 @@ func TestCrossNamespace(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
@ -5936,6 +6122,9 @@ func TestExternalNameService(t *testing.T) {
},
},
PassHostHeader: Bool(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},

View file

@ -110,7 +110,7 @@ type LoadBalancerSpec struct {
// By default, passHostHeader is true.
PassHostHeader *bool `json:"passHostHeader,omitempty"`
// ResponseForwarding defines how Traefik forwards the response from the upstream Kubernetes Service to the client.
ResponseForwarding *dynamic.ResponseForwarding `json:"responseForwarding,omitempty"`
ResponseForwarding *ResponseForwarding `json:"responseForwarding,omitempty"`
// ServersTransport defines the name of ServersTransport resource to use.
// It allows to configure the transport between Traefik and your servers.
// Can only be used on a Kubernetes Service.
@ -121,6 +121,15 @@ type LoadBalancerSpec struct {
Weight *int `json:"weight,omitempty"`
}
type ResponseForwarding struct {
// FlushInterval defines the interval, in milliseconds, in between flushes to the client while copying the response body.
// A negative value means to flush immediately after each write to the client.
// This configuration is ignored when ReverseProxy recognizes a response as a streaming response;
// for such responses, writes are flushed to the client immediately.
// Default: 100ms
FlushInterval string `json:"flushInterval,omitempty"`
}
// Service defines an upstream HTTP service to proxy traffic to.
type Service struct {
LoadBalancerSpec `json:",inline"`

View file

@ -559,7 +559,7 @@ func (in *LoadBalancerSpec) DeepCopyInto(out *LoadBalancerSpec) {
}
if in.ResponseForwarding != nil {
in, out := &in.ResponseForwarding, &out.ResponseForwarding
*out = new(dynamic.ResponseForwarding)
*out = new(ResponseForwarding)
**out = **in
}
if in.Weight != nil {
@ -973,6 +973,22 @@ func (in *RateLimit) DeepCopy() *RateLimit {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResponseForwarding) DeepCopyInto(out *ResponseForwarding) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseForwarding.
func (in *ResponseForwarding) DeepCopy() *ResponseForwarding {
if in == nil {
return nil
}
out := new(ResponseForwarding)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Retry) DeepCopyInto(out *Retry) {
*out = *in