Merge pull request #1186 from diazjf/client-body-buffer-size
Add annotation for client-body-buffer-size per location
This commit is contained in:
commit
9863140b8c
9 changed files with 165 additions and 17 deletions
|
@ -65,6 +65,7 @@ The following annotations are supported:
|
|||
|[ingress.kubernetes.io/upstream-fail-timeout](#custom-nginx-upstream-checks)|number|
|
||||
|[ingress.kubernetes.io/whitelist-source-range](#whitelist-source-range)|CIDR|
|
||||
|[ingress.kubernetes.io/server-alias](#server-alias)|string|
|
||||
|[ingress.kubernetes.io/client-body-buffer-size](#client-body-buffer-size)|string|
|
||||
|
||||
#### Custom NGINX template
|
||||
|
||||
|
@ -173,6 +174,23 @@ the new server configuration will take place over the alias configuration.
|
|||
|
||||
For more information please see http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
|
||||
|
||||
### Client Body Buffer Size
|
||||
|
||||
Sets buffer size for reading client request body per location. In case the request body is larger than the buffer,
|
||||
the whole body or only its part is written to a temporary file. By default, buffer size is equal to two memory pages.
|
||||
This is 8K on x86, other 32-bit platforms, and x86-64. It is usually 16K on other 64-bit platforms. This annotation is
|
||||
applied to each location provided in the ingress rule.
|
||||
|
||||
*Note:* The annotation value must be given in a valid format otherwise the
|
||||
For example to set the client-body-buffer-size the following can be done:
|
||||
* `ingress.kubernetes.io/client-body-buffer-size: "1000"` # 1000 bytes
|
||||
* `ingress.kubernetes.io/client-body-buffer-size: 1k` # 1 kilobyte
|
||||
* `ingress.kubernetes.io/client-body-buffer-size: 1K` # 1 kilobyte
|
||||
* `ingress.kubernetes.io/client-body-buffer-size: 1m` # 1 megabyte
|
||||
* `ingress.kubernetes.io/client-body-buffer-size: 1M` # 1 megabyte
|
||||
|
||||
For more information please see http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
|
||||
|
||||
### External Authentication
|
||||
|
||||
To use an existing service that provides authentication the Ingress rule can be annotated with `ingress.kubernetes.io/auth-url` to indicate the URL where the HTTP request should be sent.
|
||||
|
|
|
@ -555,6 +555,9 @@ stream {
|
|||
proxy_ssl_server_name on;
|
||||
|
||||
client_max_body_size "{{ $location.Proxy.BodySize }}";
|
||||
{{ if $location.ClientBodyBufferSize }}
|
||||
client_body_buffer_size {{ $location.ClientBodyBufferSize }};
|
||||
{{ end }}
|
||||
|
||||
set $target {{ $location.ExternalAuth.URL }};
|
||||
proxy_pass $target;
|
||||
|
@ -621,6 +624,9 @@ stream {
|
|||
{{ end }}
|
||||
|
||||
client_max_body_size "{{ $location.Proxy.BodySize }}";
|
||||
{{ if $location.ClientBodyBufferSize }}
|
||||
client_body_buffer_size {{ $location.ClientBodyBufferSize }};
|
||||
{{ end }}
|
||||
|
||||
proxy_set_header Host $best_http_host;
|
||||
|
||||
|
|
41
core/pkg/ingress/annotations/clientbodybuffersize/main.go
Normal file
41
core/pkg/ingress/annotations/clientbodybuffersize/main.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clientbodybuffersize
|
||||
|
||||
import (
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
||||
const (
|
||||
annotation = "ingress.kubernetes.io/client-body-buffer-size"
|
||||
)
|
||||
|
||||
type clientBodyBufferSize struct {
|
||||
}
|
||||
|
||||
// NewParser creates a new clientBodyBufferSize annotation parser
|
||||
func NewParser() parser.IngressAnnotation {
|
||||
return clientBodyBufferSize{}
|
||||
}
|
||||
|
||||
// Parse parses the annotations contained in the ingress rule
|
||||
// used to add an client-body-buffer-size to the provided locations
|
||||
func (a clientBodyBufferSize) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
return parser.GetStringAnnotation(annotation, ing)
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clientbodybuffersize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
ap := NewParser()
|
||||
if ap == nil {
|
||||
t.Fatalf("expected a parser.IngressAnnotation but returned nil")
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
annotations map[string]string
|
||||
expected string
|
||||
}{
|
||||
{map[string]string{annotation: "8k"}, "8k"},
|
||||
{map[string]string{annotation: "16k"}, "16k"},
|
||||
{map[string]string{annotation: ""}, ""},
|
||||
{map[string]string{}, ""},
|
||||
{nil, ""},
|
||||
}
|
||||
|
||||
ing := &extensions.Ingress{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.IngressSpec{},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
ing.SetAnnotations(testCase.annotations)
|
||||
result, _ := ap.Parse(ing)
|
||||
if result != testCase.expected {
|
||||
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ import (
|
|||
"k8s.io/ingress/core/pkg/ingress/annotations/sslpassthrough"
|
||||
"k8s.io/ingress/core/pkg/ingress/errors"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/clientbodybuffersize"
|
||||
)
|
||||
|
||||
type extractorConfig interface {
|
||||
|
@ -73,6 +74,7 @@ func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
|
|||
"SSLPassthrough": sslpassthrough.NewParser(),
|
||||
"ConfigurationSnippet": snippet.NewParser(),
|
||||
"Alias": alias.NewParser(),
|
||||
"ClientBodyBufferSize": clientbodybuffersize.NewParser(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +114,7 @@ const (
|
|||
sessionAffinity = "SessionAffinity"
|
||||
serviceUpstream = "ServiceUpstream"
|
||||
serverAlias = "Alias"
|
||||
clientBodyBufferSize = "ClientBodyBufferSize"
|
||||
)
|
||||
|
||||
func (e *annotationExtractor) ServiceUpstream(ing *extensions.Ingress) bool {
|
||||
|
@ -143,6 +146,11 @@ func (e *annotationExtractor) Alias(ing *extensions.Ingress) string {
|
|||
return val.(string)
|
||||
}
|
||||
|
||||
func (e *annotationExtractor) ClientBodyBufferSize(ing *extensions.Ingress) string {
|
||||
val, _ := e.annotations[clientBodyBufferSize].Parse(ing)
|
||||
return val.(string)
|
||||
}
|
||||
|
||||
func (e *annotationExtractor) SessionAffinity(ing *extensions.Ingress) *sessionaffinity.AffinityConfig {
|
||||
val, _ := e.annotations[sessionAffinity].Parse(ing)
|
||||
return val.(*sessionaffinity.AffinityConfig)
|
||||
|
|
|
@ -633,6 +633,9 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
|
|||
|
||||
anns := ic.annotations.Extract(ing)
|
||||
|
||||
// setup client-buffer-body-size based on annotations
|
||||
clientBufferBodySizeAnnotation := ic.annotations.ClientBodyBufferSize(ing)
|
||||
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
host := rule.Host
|
||||
if host == "" {
|
||||
|
@ -685,6 +688,7 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
|
|||
}
|
||||
break
|
||||
}
|
||||
loc.ClientBodyBufferSize = clientBufferBodySizeAnnotation
|
||||
}
|
||||
// is a new location
|
||||
if addLoc {
|
||||
|
@ -695,6 +699,7 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
|
|||
IsDefBackend: false,
|
||||
Service: ups.Service,
|
||||
Port: ups.Port,
|
||||
ClientBodyBufferSize: clientBufferBodySizeAnnotation,
|
||||
}
|
||||
mergeLocationAnnotations(loc, anns)
|
||||
if loc.Redirect.FromToWWW {
|
||||
|
@ -1060,6 +1065,9 @@ func (ic *GenericController) createServers(data []interface{},
|
|||
}
|
||||
}
|
||||
|
||||
// setup client-buffer-body-size based on annotations
|
||||
clientBufferBodySizeAnnotation := ic.annotations.ClientBodyBufferSize(ing)
|
||||
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
host := rule.Host
|
||||
if host == "" {
|
||||
|
@ -1079,6 +1087,7 @@ func (ic *GenericController) createServers(data []interface{},
|
|||
Backend: un,
|
||||
Proxy: ngxProxy,
|
||||
Service: &api.Service{},
|
||||
ClientBodyBufferSize: clientBufferBodySizeAnnotation,
|
||||
},
|
||||
}, SSLPassthrough: sslpt}
|
||||
}
|
||||
|
|
|
@ -303,6 +303,10 @@ type Location struct {
|
|||
// ConfigurationSnippet contains additional configuration for the backend
|
||||
// to be considered in the configuration of the location
|
||||
ConfigurationSnippet string `json:"configuration-snippet"`
|
||||
// ClientBodyBufferSize allows for the configuration of the client body
|
||||
// buffer size for a specific location.
|
||||
// +optional
|
||||
ClientBodyBufferSize string `json:"client-body-buffer-size,omitempty"`
|
||||
}
|
||||
|
||||
// SSLPassthroughBackend describes a SSL upstream server configured
|
||||
|
|
|
@ -379,6 +379,9 @@ func (l1 *Location) Equal(l2 *Location) bool {
|
|||
if l1.ConfigurationSnippet != l2.ConfigurationSnippet {
|
||||
return false
|
||||
}
|
||||
if l1.ClientBodyBufferSize != l2.ClientBodyBufferSize {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue