delete upstream healthcheck annotation

This commit is contained in:
Elvin Efendi 2018-10-08 21:29:58 -04:00
parent 9cf4f9e7ae
commit 78f12c25c5
16 changed files with 25 additions and 481 deletions

View file

@ -1,44 +0,0 @@
# Custom Upstream server checks
This example shows how is possible to create a custom configuration for a particular upstream associated with an Ingress rule.
```
echo "
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: http-svc
annotations:
nginx.ingress.kubernetes.io/upstream-fail-timeout: "30"
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: http-svc
servicePort: 80
" | kubectl create -f -
```
Check the annotation is present in the Ingress rule:
```
kubectl get ingress http-svc -o yaml
```
Check the NGINX configuration is updated using kubectl or the status page:
```
$ kubectl exec nginx-ingress-controller-v1ppm cat /etc/nginx/nginx.conf
```
```
....
upstream default-http-svc-x-80 {
least_conn;
server 10.2.92.2:8080 max_fails=5 fail_timeout=30;
}
....
```

View file

@ -65,8 +65,6 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|[nginx.ingress.kubernetes.io/session-cookie-hash](#cookie-affinity)|string|
|[nginx.ingress.kubernetes.io/ssl-redirect](#server-side-https-enforcement-through-redirect)|"true" or "false"|
|[nginx.ingress.kubernetes.io/ssl-passthrough](#ssl-passthrough)|"true" or "false"|
|[nginx.ingress.kubernetes.io/upstream-max-fails](#custom-nginx-upstream-checks)|number|
|[nginx.ingress.kubernetes.io/upstream-fail-timeout](#custom-nginx-upstream-checks)|number|
|[nginx.ingress.kubernetes.io/upstream-hash-by](#custom-nginx-upstream-hashing)|string|
|[nginx.ingress.kubernetes.io/load-balance](#custom-nginx-load-balancing)|string|
|[nginx.ingress.kubernetes.io/upstream-vhost](#custom-nginx-upstream-vhost)|string|
@ -149,29 +147,6 @@ nginx.ingress.kubernetes.io/auth-realm: "realm string"
!!! example
Please check the [auth](../../examples/auth/basic/README.md) example.
### Custom NGINX upstream checks
NGINX exposes some flags in the [upstream configuration](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream) that enable the configuration of each server in the upstream. The Ingress controller allows custom `max_fails` and `fail_timeout` parameters in a global context using `upstream-max-fails` and `upstream-fail-timeout` in the NGINX ConfigMap or in a particular Ingress rule. `upstream-max-fails` defaults to 0. This means NGINX will respect the container's `readinessProbe` if it is defined. If there is no probe and no values for `upstream-max-fails` NGINX will continue to send traffic to the container.
!!! tip
With the default configuration NGINX will not health check your backends. Whenever the endpoints controller notices a readiness probe failure, that pod's IP will be removed from the list of endpoints. This will trigger the NGINX controller to also remove it from the upstreams.**
To use custom values in an Ingress rule define these annotations:
`nginx.ingress.kubernetes.io/upstream-max-fails`: number of unsuccessful attempts to communicate with the server that should occur in the duration set by the `upstream-fail-timeout` parameter to consider the server unavailable.
`nginx.ingress.kubernetes.io/upstream-fail-timeout`: time in seconds during which the specified number of unsuccessful attempts to communicate with the server should occur to consider the server unavailable. This is also the period of time the server will be considered unavailable.
In NGINX, backend server pools are called "[upstreams](http://nginx.org/en/docs/http/ngx_http_upstream_module.html)". Each upstream contains the endpoints for a service. An upstream is created for each service that has Ingress rules defined.
!!! attention
All Ingress rules using the same service will use the same upstream.
Only one of the Ingress rules should define annotations to configure the upstream servers.
!!! example
Please check the [custom upstream check](../../examples/customization/custom-upstream-check/README.md) example.
### Custom NGINX upstream hashing
NGINX supports load balancing by client-server mapping based on [consistent hashing](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash) for a given key. The key can contain text, variables or any combination thereof. This feature allows for request stickiness other than client IP or cookies. The [ketama](http://www.last.fm/user/RJ/journal/2007/04/10/392555/) consistent hashing method will be used which ensures only a few keys would be remapped to different servers on upstream group changes.

View file

@ -34,7 +34,6 @@ import (
"k8s.io/ingress-nginx/internal/ingress/annotations/connection"
"k8s.io/ingress-nginx/internal/ingress/annotations/cors"
"k8s.io/ingress-nginx/internal/ingress/annotations/defaultbackend"
"k8s.io/ingress-nginx/internal/ingress/annotations/healthcheck"
"k8s.io/ingress-nginx/internal/ingress/annotations/influxdb"
"k8s.io/ingress-nginx/internal/ingress/annotations/ipwhitelist"
"k8s.io/ingress-nginx/internal/ingress/annotations/loadbalancing"
@ -76,7 +75,6 @@ type Ingress struct {
DefaultBackend *apiv1.Service
Denied error
ExternalAuth authreq.Config
HealthCheck healthcheck.Config
Proxy proxy.Config
RateLimit ratelimit.Config
Redirect redirect.Config
@ -116,7 +114,6 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
"CorsConfig": cors.NewParser(cfg),
"DefaultBackend": defaultbackend.NewParser(cfg),
"ExternalAuth": authreq.NewParser(cfg),
"HealthCheck": healthcheck.NewParser(cfg),
"Proxy": proxy.NewParser(cfg),
"RateLimit": ratelimit.NewParser(cfg),
"Redirect": redirect.NewParser(cfg),

View file

@ -31,8 +31,6 @@ import (
var (
annotationSecureVerifyCACert = parser.GetAnnotationWithPrefix("secure-verify-ca-secret")
annotationUpsMaxFails = parser.GetAnnotationWithPrefix("upstream-max-fails")
annotationUpsFailTimeout = parser.GetAnnotationWithPrefix("upstream-fail-timeout")
annotationPassthrough = parser.GetAnnotationWithPrefix("ssl-passthrough")
annotationAffinityType = parser.GetAnnotationWithPrefix("affinity")
annotationCorsEnabled = parser.GetAnnotationWithPrefix("enable-cors")
@ -146,36 +144,6 @@ func TestSecureVerifyCACert(t *testing.T) {
}
}
func TestHealthCheck(t *testing.T) {
ec := NewAnnotationExtractor(mockCfg{})
ing := buildIngress()
fooAnns := []struct {
annotations map[string]string
eumf int
euft int
}{
{map[string]string{annotationUpsMaxFails: "3", annotationUpsFailTimeout: "10"}, 3, 10},
{map[string]string{annotationUpsMaxFails: "3"}, 3, 0},
{map[string]string{annotationUpsFailTimeout: "10"}, 0, 10},
{map[string]string{}, 0, 0},
{nil, 0, 0},
}
for _, foo := range fooAnns {
ing.SetAnnotations(foo.annotations)
r := ec.Extract(ing).HealthCheck
if r.FailTimeout != foo.euft {
t.Errorf("Returned %d but expected %d for FailTimeout", r.FailTimeout, foo.euft)
}
if r.MaxFails != foo.eumf {
t.Errorf("Returned %d but expected %d for MaxFails", r.MaxFails, foo.eumf)
}
}
}
func TestSSLPassthrough(t *testing.T) {
ec := NewAnnotationExtractor(mockCfg{})
ing := buildIngress()

View file

@ -1,61 +0,0 @@
/*
Copyright 2016 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 healthcheck
import (
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)
// Config returns the URL and method to use check the status of
// the upstream server/s
type Config struct {
MaxFails int `json:"maxFails"`
FailTimeout int `json:"failTimeout"`
}
type healthCheck struct {
r resolver.Resolver
}
// NewParser creates a new health check annotation parser
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
return healthCheck{r}
}
// ParseAnnotations parses the annotations contained in the ingress
// rule used to configure upstream check parameters
func (hc healthCheck) Parse(ing *extensions.Ingress) (interface{}, error) {
defBackend := hc.r.GetDefaultBackend()
if ing.GetAnnotations() == nil {
return &Config{defBackend.UpstreamMaxFails, defBackend.UpstreamFailTimeout}, nil
}
mf, err := parser.GetIntAnnotation("upstream-max-fails", ing)
if err != nil {
mf = defBackend.UpstreamMaxFails
}
ft, err := parser.GetIntAnnotation("upstream-fail-timeout", ing)
if err != nil {
ft = defBackend.UpstreamFailTimeout
}
return &Config{mf, ft}, nil
}

View file

@ -1,95 +0,0 @@
/*
Copyright 2016 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 healthcheck
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/defaults"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)
func buildIngress() *extensions.Ingress {
defaultBackend := extensions.IngressBackend{
ServiceName: "default-backend",
ServicePort: intstr.FromInt(80),
}
return &extensions.Ingress{
ObjectMeta: meta_v1.ObjectMeta{
Name: "foo",
Namespace: api.NamespaceDefault,
},
Spec: extensions.IngressSpec{
Backend: &extensions.IngressBackend{
ServiceName: "default-backend",
ServicePort: intstr.FromInt(80),
},
Rules: []extensions.IngressRule{
{
Host: "foo.bar.com",
IngressRuleValue: extensions.IngressRuleValue{
HTTP: &extensions.HTTPIngressRuleValue{
Paths: []extensions.HTTPIngressPath{
{
Path: "/foo",
Backend: defaultBackend,
},
},
},
},
},
},
},
}
}
type mockBackend struct {
resolver.Mock
}
func (m mockBackend) GetDefaultBackend() defaults.Backend {
return defaults.Backend{UpstreamFailTimeout: 1}
}
func TestIngressHealthCheck(t *testing.T) {
ing := buildIngress()
data := map[string]string{}
data[parser.GetAnnotationWithPrefix("upstream-max-fails")] = "2"
ing.SetAnnotations(data)
hzi, _ := NewParser(mockBackend{}).Parse(ing)
nginxHz, ok := hzi.(*Config)
if !ok {
t.Errorf("expected a Upstream type")
}
if nginxHz.MaxFails != 2 {
t.Errorf("expected 2 as max-fails but returned %v", nginxHz.MaxFails)
}
if nginxHz.FailTimeout != 1 {
t.Errorf("expected 0 as fail-timeout but returned %v", nginxHz.FailTimeout)
}
}

View file

@ -70,7 +70,6 @@ type mockBackend struct {
func (m mockBackend) GetDefaultBackend() defaults.Backend {
return defaults.Backend{
UpstreamFailTimeout: 1,
ProxyConnectTimeout: 10,
ProxySendTimeout: 15,
ProxyReadTimeout: 20,

View file

@ -33,7 +33,6 @@ import (
clientset "k8s.io/client-go/kubernetes"
"k8s.io/ingress-nginx/internal/ingress"
"k8s.io/ingress-nginx/internal/ingress/annotations/healthcheck"
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
"k8s.io/ingress-nginx/internal/k8s"
@ -237,7 +236,7 @@ func (n *NGINXController) getDefaultUpstream() *ingress.Backend {
return upstream
}
endps := getEndpoints(svc, &svc.Spec.Ports[0], apiv1.ProtocolTCP, &healthcheck.Config{}, n.store.GetServiceEndpoints)
endps := getEndpoints(svc, &svc.Spec.Ports[0], apiv1.ProtocolTCP, n.store.GetServiceEndpoints)
if len(endps) == 0 {
glog.Warningf("Service %q does not have any active Endpoint", svcKey)
endps = []ingress.Endpoint{n.DefaultEndpoint()}
@ -434,7 +433,7 @@ func (n *NGINXController) getBackendServers(ingresses []*extensions.Ingress) ([]
// check if the location contains endpoints and a custom default backend
if location.DefaultBackend != nil {
sp := location.DefaultBackend.Spec.Ports[0]
endps := getEndpoints(location.DefaultBackend, &sp, apiv1.ProtocolTCP, &healthcheck.Config{}, n.store.GetServiceEndpoints)
endps := getEndpoints(location.DefaultBackend, &sp, apiv1.ProtocolTCP, n.store.GetServiceEndpoints)
if len(endps) > 0 {
glog.V(3).Infof("Using custom default backend for location %q in server %q (Service \"%v/%v\")",
location.Path, server.Hostname, location.DefaultBackend.Namespace, location.DefaultBackend.Name)
@ -544,7 +543,7 @@ func (n *NGINXController) createUpstreams(data []*extensions.Ingress, du *ingres
}
if len(upstreams[defBackend].Endpoints) == 0 {
endps, err := n.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String(), &anns.HealthCheck)
endps, err := n.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String())
upstreams[defBackend].Endpoints = append(upstreams[defBackend].Endpoints, endps...)
if err != nil {
glog.Warningf("Error creating upstream %q: %v", defBackend, err)
@ -597,7 +596,7 @@ func (n *NGINXController) createUpstreams(data []*extensions.Ingress, du *ingres
}
if len(upstreams[name].Endpoints) == 0 {
endp, err := n.serviceEndpoints(svcKey, path.Backend.ServicePort.String(), &anns.HealthCheck)
endp, err := n.serviceEndpoints(svcKey, path.Backend.ServicePort.String())
if err != nil {
glog.Warningf("Error obtaining Endpoints for Service %q: %v", svcKey, err)
continue
@ -654,10 +653,8 @@ func (n *NGINXController) getServiceClusterEndpoint(svcKey string, backend *exte
return endpoint, err
}
// serviceEndpoints returns the upstream servers (Endpoints) associated with a
// Service.
func (n *NGINXController) serviceEndpoints(svcKey, backendPort string,
hz *healthcheck.Config) ([]ingress.Endpoint, error) {
// serviceEndpoints returns the upstream servers (Endpoints) associated with a Service.
func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingress.Endpoint, error) {
svc, err := n.store.GetService(svcKey)
var upstreams []ingress.Endpoint
@ -672,7 +669,7 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string,
servicePort.TargetPort.String() == backendPort ||
servicePort.Name == backendPort {
endps := getEndpoints(svc, &servicePort, apiv1.ProtocolTCP, hz, n.store.GetServiceEndpoints)
endps := getEndpoints(svc, &servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints)
if len(endps) == 0 {
glog.Warningf("Service %q does not have any active Endpoint.", svcKey)
}
@ -706,7 +703,7 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string,
Port: int32(externalPort),
TargetPort: intstr.FromString(backendPort),
}
endps := getEndpoints(svc, &servicePort, apiv1.ProtocolTCP, hz, n.store.GetServiceEndpoints)
endps := getEndpoints(svc, &servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints)
if len(endps) == 0 {
glog.Warningf("Service %q does not have any active Endpoint.", svcKey)
return upstreams, nil

View file

@ -27,12 +27,11 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/ingress-nginx/internal/ingress"
"k8s.io/ingress-nginx/internal/ingress/annotations/healthcheck"
"k8s.io/ingress-nginx/internal/k8s"
)
// getEndpoints returns a list of Endpoint structs for a given service/target port combination.
func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Protocol, hz *healthcheck.Config,
func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Protocol,
getServiceEndpoints func(string) (*corev1.Endpoints, error)) []ingress.Endpoint {
upsServers := []ingress.Endpoint{}
@ -66,10 +65,8 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot
}
return append(upsServers, ingress.Endpoint{
Address: s.Spec.ExternalName,
Port: fmt.Sprintf("%v", targetPort),
MaxFails: hz.MaxFails,
FailTimeout: hz.FailTimeout,
Address: s.Spec.ExternalName,
Port: fmt.Sprintf("%v", targetPort),
})
}
@ -106,11 +103,9 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot
continue
}
ups := ingress.Endpoint{
Address: epAddress.IP,
Port: fmt.Sprintf("%v", targetPort),
MaxFails: hz.MaxFails,
FailTimeout: hz.FailTimeout,
Target: epAddress.TargetRef,
Address: epAddress.IP,
Port: fmt.Sprintf("%v", targetPort),
Target: epAddress.TargetRef,
}
upsServers = append(upsServers, ups)
processedUpstreamServers[ep] = struct{}{}

View file

@ -23,7 +23,6 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/ingress-nginx/internal/ingress"
"k8s.io/ingress-nginx/internal/ingress/annotations/healthcheck"
)
func TestGetEndpoints(t *testing.T) {
@ -32,7 +31,6 @@ func TestGetEndpoints(t *testing.T) {
svc *corev1.Service
port *corev1.ServicePort
proto corev1.Protocol
hz *healthcheck.Config
fn func(string) (*corev1.Endpoints, error)
result []ingress.Endpoint
}{
@ -41,7 +39,6 @@ func TestGetEndpoints(t *testing.T) {
nil,
nil,
corev1.ProtocolTCP,
nil,
func(string) (*corev1.Endpoints, error) {
return nil, nil
},
@ -52,7 +49,6 @@ func TestGetEndpoints(t *testing.T) {
&corev1.Service{},
nil,
corev1.ProtocolTCP,
nil,
func(string) (*corev1.Endpoints, error) {
return nil, nil
},
@ -63,7 +59,6 @@ func TestGetEndpoints(t *testing.T) {
&corev1.Service{},
&corev1.ServicePort{Name: "default"},
corev1.ProtocolTCP,
nil,
func(string) (*corev1.Endpoints, error) {
return &corev1.Endpoints{}, nil
},
@ -78,7 +73,6 @@ func TestGetEndpoints(t *testing.T) {
},
&corev1.ServicePort{Name: "default"},
corev1.ProtocolTCP,
nil,
func(string) (*corev1.Endpoints, error) {
return &corev1.Endpoints{}, nil
},
@ -103,19 +97,13 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
return &corev1.Endpoints{}, nil
},
[]ingress.Endpoint{
{
Address: "10.0.0.1.xip.io",
Port: "80",
MaxFails: 0,
FailTimeout: 0,
Address: "10.0.0.1.xip.io",
Port: "80",
},
},
},
@ -138,10 +126,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
return &corev1.Endpoints{}, nil
},
@ -166,10 +150,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
return nil, fmt.Errorf("unexpected error")
},
@ -194,10 +174,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
nodeName := "dummy"
return &corev1.Endpoints{
@ -239,10 +215,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
nodeName := "dummy"
return &corev1.Endpoints{
@ -284,10 +256,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
nodeName := "dummy"
return &corev1.Endpoints{
@ -331,10 +299,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromInt(80),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
nodeName := "dummy"
return &corev1.Endpoints{
@ -359,10 +323,8 @@ func TestGetEndpoints(t *testing.T) {
},
[]ingress.Endpoint{
{
Address: "1.1.1.1",
Port: "80",
MaxFails: 0,
FailTimeout: 0,
Address: "1.1.1.1",
Port: "80",
},
},
},
@ -385,10 +347,6 @@ func TestGetEndpoints(t *testing.T) {
TargetPort: intstr.FromString("port-1"),
},
corev1.ProtocolTCP,
&healthcheck.Config{
MaxFails: 0,
FailTimeout: 0,
},
func(string) (*corev1.Endpoints, error) {
nodeName := "dummy"
return &corev1.Endpoints{
@ -418,10 +376,8 @@ func TestGetEndpoints(t *testing.T) {
},
[]ingress.Endpoint{
{
Address: "1.1.1.1",
Port: "80",
MaxFails: 0,
FailTimeout: 0,
Address: "1.1.1.1",
Port: "80",
},
},
},
@ -429,7 +385,7 @@ func TestGetEndpoints(t *testing.T) {
for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
result := getEndpoints(testCase.svc, testCase.port, testCase.proto, testCase.hz, testCase.fn)
result := getEndpoints(testCase.svc, testCase.port, testCase.proto, testCase.fn)
if len(testCase.result) != len(result) {
t.Errorf("Expected %d Endpoints but got %d", len(testCase.result), len(result))
}

View file

@ -773,10 +773,8 @@ func configureDynamically(pcfg *ingress.Configuration, port int, isDynamicCertif
var endpoints []ingress.Endpoint
for _, endpoint := range backend.Endpoints {
endpoints = append(endpoints, ingress.Endpoint{
Address: endpoint.Address,
FailTimeout: endpoint.FailTimeout,
MaxFails: endpoint.MaxFails,
Port: endpoint.Port,
Address: endpoint.Address,
Port: endpoint.Port,
})
}

View file

@ -107,18 +107,6 @@ type Backend struct {
// Default: false
UsePortInRedirects bool `json:"use-port-in-redirects"`
// Number of unsuccessful attempts to communicate with the server that should happen in the
// duration set by the fail_timeout parameter to consider the server unavailable
// http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
// Default: 0, ie use platform liveness probe
UpstreamMaxFails int `json:"upstream-max-fails"`
// Time during which the specified number of unsuccessful attempts to communicate with
// the server should happen to consider the server unavailable
// http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
// Default: 0, ie use platform liveness probe
UpstreamFailTimeout int `json:"upstream-fail-timeout"`
// Enable stickiness by client-server mapping based on a NGINX variable, text or a combination of both.
// A consistent hashing method will be used which ensures only a few keys would be remapped to different
// servers on upstream group changes

View file

@ -119,14 +119,6 @@ type Endpoint struct {
Address string `json:"address"`
// Port number of the TCP port
Port string `json:"port"`
// MaxFails returns the number of unsuccessful attempts to communicate
// allowed before this should be considered down.
// Setting 0 indicates that the check is performed by a Kubernetes probe
MaxFails int `json:"maxFails"`
// FailTimeout returns the time in seconds during which the specified number
// of unsuccessful attempts to communicate with the server should happen
// to consider the endpoint unavailable
FailTimeout int `json:"failTimeout"`
// Target returns a reference to the object providing the endpoint
Target *apiv1.ObjectReference `json:"target,omitempty"`
}

View file

@ -186,12 +186,6 @@ func (e1 *Endpoint) Equal(e2 *Endpoint) bool {
if e1.Port != e2.Port {
return false
}
if e1.MaxFails != e2.MaxFails {
return false
}
if e1.FailTimeout != e2.FailTimeout {
return false
}
if e1.Target != e2.Target {
if e1.Target == nil || e2.Target == nil {

View file

@ -417,7 +417,7 @@ http {
keepalive {{ $cfg.UpstreamKeepaliveConnections }};
{{ end }}
{{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};
{{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }};
{{ end }}
}
{{ end }}
@ -429,7 +429,7 @@ http {
keepalive {{ $cfg.UpstreamKeepaliveConnections }};
{{ end }}
{{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};
{{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }};
{{ end }}
}
{{ end }}

View file

@ -1,115 +0,0 @@
/*
Copyright 2018 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 annotations
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/ingress-nginx/test/e2e/framework"
)
var _ = framework.IngressNginxDescribe("Annotations - HealthCheck", func() {
f := framework.NewDefaultFramework("healthcheck")
BeforeEach(func() {
err := f.DisableDynamicConfiguration()
Expect(err).NotTo(HaveOccurred())
err = f.NewEchoDeploymentWithReplicas(2)
Expect(err).NotTo(HaveOccurred())
})
AfterEach(func() {
})
It("should set upstream-max-fails to 11", func() {
host := "healthcheck.foo.com"
annotations := map[string]string{
"nginx.ingress.kubernetes.io/upstream-max-fails": "11",
}
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
_, err := f.EnsureIngress(ing)
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxConfiguration(
func(server string) bool {
return Expect(server).Should(ContainSubstring("max_fails=11 fail_timeout=0;"))
})
Expect(err).NotTo(HaveOccurred())
})
It("should not set upstream-max-fails to 11s", func() {
host := "healthcheck.foo.com"
annotations := map[string]string{
"nginx.ingress.kubernetes.io/upstream-max-fails": "11s",
}
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
_, err := f.EnsureIngress(ing)
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxConfiguration(
func(server string) bool {
return Expect(server).ShouldNot(ContainSubstring("max_fails=11s fail_timeout=0;"))
})
Expect(err).NotTo(HaveOccurred())
})
It("should set upstream-fail-timeout to 15", func() {
host := "healthcheck.foo.com"
annotations := map[string]string{
"nginx.ingress.kubernetes.io/upstream-fail-timeout": "15",
}
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
_, err := f.EnsureIngress(ing)
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxConfiguration(
func(server string) bool {
return Expect(server).Should(ContainSubstring("max_fails=0 fail_timeout=15;"))
})
Expect(err).NotTo(HaveOccurred())
})
It("should not set upstream-fail-timeout to 15s", func() {
host := "healthcheck.foo.com"
annotations := map[string]string{
"nginx.ingress.kubernetes.io/upstream-fail-timeout": "15s",
}
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
_, err := f.EnsureIngress(ing)
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxConfiguration(
func(server string) bool {
return Expect(server).ShouldNot(ContainSubstring("max_fails=0 fail_timeout=15s;"))
})
Expect(err).NotTo(HaveOccurred())
})
})