Merge pull request #3126 from ElvinEfendi/optional-default-backend-service
do not require --default-backend-service
This commit is contained in:
commit
c3ce6b892e
12 changed files with 99 additions and 147 deletions
|
@ -31,10 +31,10 @@ func resetForTesting(usage func()) {
|
||||||
flag.Usage = usage
|
flag.Usage = usage
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMandatoryFlag(t *testing.T) {
|
func TestNoMandatoryFlag(t *testing.T) {
|
||||||
_, _, err := parseFlags()
|
_, _, err := parseFlags()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected an error about default backend service")
|
t.Fatalf("Expected no error but got: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,10 +176,6 @@ Feature backed by OpenResty Lua libraries. Requires that OCSP stapling is not en
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if *defaultSvc == "" {
|
|
||||||
return false, nil, fmt.Errorf("Please specify --default-backend-service")
|
|
||||||
}
|
|
||||||
|
|
||||||
if *ingressClass != "" {
|
if *ingressClass != "" {
|
||||||
glog.Infof("Watching for Ingress class: %s", *ingressClass)
|
glog.Infof("Watching for Ingress class: %s", *ingressClass)
|
||||||
|
|
||||||
|
|
|
@ -84,20 +84,22 @@ func main() {
|
||||||
handleFatalInitError(err)
|
handleFatalInitError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defSvcNs, defSvcName, err := k8s.ParseNameNS(conf.DefaultService)
|
if len(conf.DefaultService) > 0 {
|
||||||
if err != nil {
|
defSvcNs, defSvcName, err := k8s.ParseNameNS(conf.DefaultService)
|
||||||
glog.Fatal(err)
|
if err != nil {
|
||||||
}
|
glog.Fatal(err)
|
||||||
|
|
||||||
_, err = kubeClient.CoreV1().Services(defSvcNs).Get(defSvcName, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
// TODO (antoineco): compare with error types from k8s.io/apimachinery/pkg/api/errors
|
|
||||||
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
|
||||||
glog.Fatalf("✖ The cluster seems to be running with a restrictive Authorization mode and the Ingress controller does not have the required permissions to operate normally.")
|
|
||||||
}
|
}
|
||||||
glog.Fatalf("No service with name %v found: %v", conf.DefaultService, err)
|
|
||||||
|
_, err = kubeClient.CoreV1().Services(defSvcNs).Get(defSvcName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
// TODO (antoineco): compare with error types from k8s.io/apimachinery/pkg/api/errors
|
||||||
|
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
||||||
|
glog.Fatalf("✖ The cluster seems to be running with a restrictive Authorization mode and the Ingress controller does not have the required permissions to operate normally.")
|
||||||
|
}
|
||||||
|
glog.Fatalf("No service with name %v found: %v", conf.DefaultService, err)
|
||||||
|
}
|
||||||
|
glog.Infof("Validated %v as the default backend.", conf.DefaultService)
|
||||||
}
|
}
|
||||||
glog.Infof("Validated %v as the default backend.", conf.DefaultService)
|
|
||||||
|
|
||||||
if conf.Namespace != "" {
|
if conf.Namespace != "" {
|
||||||
_, err = kubeClient.CoreV1().Namespaces().Get(conf.Namespace, metav1.GetOptions{})
|
_, err = kubeClient.CoreV1().Namespaces().Get(conf.Namespace, metav1.GetOptions{})
|
||||||
|
|
|
@ -6,67 +6,6 @@ metadata:
|
||||||
name: ingress-nginx
|
name: ingress-nginx
|
||||||
---
|
---
|
||||||
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: default-http-backend
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
namespace: ingress-nginx
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
spec:
|
|
||||||
terminationGracePeriodSeconds: 60
|
|
||||||
containers:
|
|
||||||
- name: default-http-backend
|
|
||||||
# Any image is permissible as long as:
|
|
||||||
# 1. It serves a 404 page at /
|
|
||||||
# 2. It serves 200 on a /healthz endpoint
|
|
||||||
image: gcr.io/google_containers/defaultbackend:1.4
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
timeoutSeconds: 5
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 20Mi
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 20Mi
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: default-http-backend
|
|
||||||
namespace: ingress-nginx
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 8080
|
|
||||||
selector:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -277,7 +216,6 @@ spec:
|
||||||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
|
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
|
||||||
args:
|
args:
|
||||||
- /nginx-ingress-controller
|
- /nginx-ingress-controller
|
||||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
||||||
- --configmap=$(POD_NAMESPACE)/nginx-configuration
|
- --configmap=$(POD_NAMESPACE)/nginx-configuration
|
||||||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
|
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
|
||||||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
||||||
|
|
|
@ -54,5 +54,4 @@ spec:
|
||||||
fieldPath: metadata.namespace
|
fieldPath: metadata.namespace
|
||||||
args:
|
args:
|
||||||
- /nginx-ingress-controller
|
- /nginx-ingress-controller
|
||||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
||||||
- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb
|
- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb
|
||||||
|
|
|
@ -10,8 +10,8 @@ They are set in the container spec of the `nginx-ingress-controller` Deployment
|
||||||
| `--annotations-prefix string` | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
| `--annotations-prefix string` | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
||||||
| `--apiserver-host string` | Address of the Kubernetes API server. Takes the form "protocol://address:port". If not specified, it is assumed the program runs inside a Kubernetes cluster and local discovery is attempted. |
|
| `--apiserver-host string` | Address of the Kubernetes API server. Takes the form "protocol://address:port". If not specified, it is assumed the program runs inside a Kubernetes cluster and local discovery is attempted. |
|
||||||
| `--configmap string` | Name of the ConfigMap containing custom global configurations for the controller. |
|
| `--configmap string` | Name of the ConfigMap containing custom global configurations for the controller. |
|
||||||
| `--default-backend-service string` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service. |
|
| `--default-backend-service string` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service. If not specified, 404 page will be returned diretly from Nginx.|
|
||||||
| `--default-server-port int` | Port to use for exposing the default server (catch-all). (default 8181) |
|
| `--default-server-port int` | When `default-backend-service` is not specified or specified service does not have any endpoint, a local endpoint with this port will be used to serve 404 page from inside Nginx. |
|
||||||
| `--default-ssl-certificate string` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
| `--default-ssl-certificate string` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
||||||
| `--election-id string` | Election id to use for Ingress status updates. (default "ingress-controller-leader") |
|
| `--election-id string` | Election id to use for Ingress status updates. (default "ingress-controller-leader") |
|
||||||
| `--enable-dynamic-certificates` | Dynamically serves certificates instead of reloading NGINX when certificates are created, updated, or deleted. Currently does not support OCSP stapling, so --enable-ssl-chain-completion must be turned off. Assuming the certificate is generated with a 2048 bit RSA key/cert pair, this feature can store roughly 5000 certificates. This is an experiemental feature that currently is not ready for production use. Feature backed by OpenResty Lua libraries. (disabled by default) |
|
| `--enable-dynamic-certificates` | Dynamically serves certificates instead of reloading NGINX when certificates are created, updated, or deleted. Currently does not support OCSP stapling, so --enable-ssl-chain-completion must be turned off. Assuming the certificate is generated with a 2048 bit RSA key/cert pair, this feature can store roughly 5000 certificates. This is an experiemental feature that currently is not ready for production use. Feature backed by OpenResty Lua libraries. (disabled by default) |
|
||||||
|
|
|
@ -43,7 +43,6 @@ spec:
|
||||||
- name: nginx-ingress-internal-controller
|
- name: nginx-ingress-internal-controller
|
||||||
args:
|
args:
|
||||||
- /nginx-ingress-controller
|
- /nginx-ingress-controller
|
||||||
- '--default-backend-service=ingress/nginx-ingress-default-backend'
|
|
||||||
- '--election-id=ingress-controller-leader-internal'
|
- '--election-id=ingress-controller-leader-internal'
|
||||||
- '--ingress-class=nginx-internal'
|
- '--ingress-class=nginx-internal'
|
||||||
- '--configmap=ingress/nginx-ingress-internal-controller'
|
- '--configmap=ingress/nginx-ingress-internal-controller'
|
||||||
|
|
|
@ -362,6 +362,12 @@ func (n *NGINXController) getDefaultUpstream() *ingress.Backend {
|
||||||
Name: defUpstreamName,
|
Name: defUpstreamName,
|
||||||
}
|
}
|
||||||
svcKey := n.cfg.DefaultService
|
svcKey := n.cfg.DefaultService
|
||||||
|
|
||||||
|
if len(svcKey) == 0 {
|
||||||
|
upstream.Endpoints = append(upstream.Endpoints, n.DefaultEndpoint())
|
||||||
|
return upstream
|
||||||
|
}
|
||||||
|
|
||||||
svc, err := n.store.GetService(svcKey)
|
svc, err := n.store.GetService(svcKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Warningf("Error getting default backend %q: %v", svcKey, err)
|
glog.Warningf("Error getting default backend %q: %v", svcKey, err)
|
||||||
|
|
|
@ -584,6 +584,17 @@ http {
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
# backend for when default-backend-service is not configured or it does not have endpoints
|
||||||
|
server {
|
||||||
|
listen {{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};
|
||||||
|
{{ if $IsIPV6Enabled }}listen [::]:{{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};{{ end }}
|
||||||
|
set $proxy_upstream_name "-";
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# default server, used for NGINX healthcheck and access to nginx stats
|
# default server, used for NGINX healthcheck and access to nginx stats
|
||||||
server {
|
server {
|
||||||
listen {{ $all.ListenPorts.Status }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};
|
listen {{ $all.ListenPorts.Status }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};
|
||||||
|
|
|
@ -98,7 +98,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Alias", func() {
|
||||||
|
|
||||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||||
Expect(resp.StatusCode).Should(Equal(http.StatusNotFound))
|
Expect(resp.StatusCode).Should(Equal(http.StatusNotFound))
|
||||||
Expect(body).Should(ContainSubstring("default backend - 404"))
|
Expect(body).Should(ContainSubstring("404 Not Found"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return status code 200 for host 'foo' and 'bar'", func() {
|
It("should return status code 200 for host 'foo' and 'bar'", func() {
|
||||||
|
|
62
test/e2e/defaultbackend/custom_default_backend.go
Normal file
62
test/e2e/defaultbackend/custom_default_backend.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
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 defaultbackend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/parnurzeal/gorequest"
|
||||||
|
|
||||||
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
|
f := framework.NewDefaultFramework("custom-default-backend")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
err := f.NewEchoDeploymentWithReplicas(1)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
||||||
|
func(deployment *appsv1beta1.Deployment) error {
|
||||||
|
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||||
|
args = append(args, fmt.Sprintf("--default-backend-service=%s/%s", f.IngressController.Namespace, "http-svc"))
|
||||||
|
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||||
|
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.IngressController.Namespace).Update(deployment)
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
err = f.WaitForNginxServer("_",
|
||||||
|
func(server string) bool {
|
||||||
|
return strings.Contains(server, "set $proxy_upstream_name \"upstream-default-backend\"")
|
||||||
|
})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses custom default backend", func() {
|
||||||
|
resp, _, errs := gorequest.New().Get(f.IngressController.HTTPURL).End()
|
||||||
|
Expect(errs).Should(BeEmpty())
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,65 +1,5 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: default-http-backend
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
spec:
|
|
||||||
terminationGracePeriodSeconds: 60
|
|
||||||
containers:
|
|
||||||
- name: default-http-backend
|
|
||||||
# Any image is permissible as long as:
|
|
||||||
# 1. It serves a 404 page at /
|
|
||||||
# 2. It serves 200 on a /healthz endpoint
|
|
||||||
image: gcr.io/google_containers/defaultbackend:1.4
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
timeoutSeconds: 5
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 20Mi
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 20Mi
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: default-http-backend
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 8080
|
|
||||||
selector:
|
|
||||||
app.kubernetes.io/name: default-http-backend
|
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -275,7 +215,6 @@ spec:
|
||||||
image: ingress-controller/nginx-ingress-controller:dev
|
image: ingress-controller/nginx-ingress-controller:dev
|
||||||
args:
|
args:
|
||||||
- /nginx-ingress-controller
|
- /nginx-ingress-controller
|
||||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
||||||
- --configmap=$(POD_NAMESPACE)/nginx-configuration
|
- --configmap=$(POD_NAMESPACE)/nginx-configuration
|
||||||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
|
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
|
||||||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
||||||
|
|
Loading…
Reference in a new issue