Remove interface

This commit is contained in:
Manuel de Brito Fontes 2016-11-11 20:43:35 -03:00
parent ed9a416b01
commit f2b627486d
13 changed files with 72 additions and 872 deletions

View file

@ -1,470 +1,2 @@
[![Build Status](https://travis-ci.org/aledbf/ingress-controller.svg?branch=master)](https://travis-ci.org/aledbf/ingress-controller)
[![Coverage Status](https://coveralls.io/repos/github/aledbf/ingress-controller/badge.svg?branch=master)](https://coveralls.io/github/aledbf/ingress-controller?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/aledbf/ingress-controller)](https://goreportcard.com/report/github.com/aledbf/ingress-controller)
# Nginx Ingress Controller
This is an nginx Ingress controller that uses [ConfigMap](https://github.com/kubernetes/kubernetes/blob/master/docs/design/configmap.md) to store the nginx configuration. See [Ingress controller documentation](../README.md) for details on how it works.
## Contents
* [Recent changes](#recent-changes)
* [Conventions](#conventions)
* [Requirements](#what-it-provides)
* [Deployment](#deployment)
* [Health checks](#health-checks)
* [HTTP](#http)
* [HTTPS](#https)
* [Default SSL Certificate](#default-ssl-certificate)
* [HTTPS enforcement](#server-side-https-enforcement)
* [HSTS](#http-strict-transport-security)
* [Kube-Lego](#automated-certificate-management-with-kube-lego)
* [TCP Services](#exposing-tcp-services)
* [UDP Services](#exposing-udp-services)
* [Proxy Protocol](#proxy-protocol)
* [Service Integration](#service-integration)
* [NGINX customization](configuration.md)
* [NGINX status page](#nginx-status-page)
* [Running multiple ingress controllers](#running-multiple-ingress-controllers)
* [Running on Cloudproviders](#running-on-cloudproviders)
* [Disabling NGINX ingress controller](#disabling-nginx-ingress-controller)
* [Log format](#log-format)
* [Local cluster](#local-cluster)
* [Debug & Troubleshooting](#troubleshooting)
* [Why endpoints and not services?](#why-endpoints-and-not-services)
* [Metrics](#metrics)
* [Limitations](#limitations)
* [NGINX Notes](#nginx-notes)
## Recent changes
Change history is available in [CHANGELOG.md](CHANGELOG.md)
## Conventions
Anytime we reference a tls secret, we mean (x509, pem encoded, RSA 2048, etc). You can generate such a certificate with:
`openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout $(KEY) -out $(CERT) -subj "/CN=$(HOST)/O=$(HOST)"`
and create the secret via `kubectl create secret tls --key file --cert file`
## Requirements
- Default backend [404-server](https://github.com/kubernetes/contrib/tree/master/404-server)
## Deployment
First create a default backend:
```
$ kubectl create -f examples/default-backend.yaml
$ kubectl expose rc default-http-backend --port=80 --target-port=8080 --name=default-http-backend
```
Loadbalancers are created via a ReplicationController or Daemonset:
```
$ kubectl create -f examples/default/rc-default.yaml
```
## Health checks
The proveded examples in the Ingress controller use a `readiness` and `liveness` probe. By default the URL is `/healthz` and the port `18080`.
Using the flag `--health-check-path` is possible to specify a custom path.
In some environments only port 80 is allowed to enable health checks. For this reason the Ingress controller exposes this path in the default server.
If PROXY protocol is enabled the health check must use the default port `18080`. This is required because Kubernetes probes do not understand PROXY protocol.
## HTTP
First we need to deploy some application to publish. To keep this simple we will use the [echoheaders app](https://github.com/kubernetes/contrib/blob/master/ingress/echoheaders/echo-app.yaml) that just returns information about the http request as output
```
kubectl run echoheaders --image=gcr.io/google_containers/echoserver:1.4 --replicas=1 --port=8080
```
Now we expose the same application in two different services (so we can create different Ingress rules)
```
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-y
```
Next we create a couple of Ingress rules
```
kubectl create -f examples/ingress.yaml
```
we check that ingress rules are defined:
```
$ kubectl get ing
NAME RULE BACKEND ADDRESS
echomap -
foo.bar.com
/foo echoheaders-x:80
bar.baz.com
/bar echoheaders-y:80
/foo echoheaders-x:80
```
Before the deploy of the Ingress controller we need a default backend [404-server](https://github.com/kubernetes/contrib/tree/master/404-server)
```
kubectl create -f examples/default-backend.yaml
kubectl expose rc default-http-backend --port=80 --target-port=8080 --name=default-http-backend
```
Check NGINX it is running with the defined Ingress rules:
```
$ LBIP=$(kubectl get node `kubectl get po -l name=nginx-ingress-lb --template '{{range .items}}{{.spec.nodeName}}{{end}}'` --template '{{range $i, $n := .status.addresses}}{{if eq $n.type "ExternalIP"}}{{$n.address}}{{end}}{{end}}')
$ curl $LBIP/foo -H 'Host: foo.bar.com'
```
## HTTPS
You can secure an Ingress by specifying a secret that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. This controller supports SNI. The TLS secret must contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS, eg:
```
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret
namespace: default
type: Opaque
```
Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS:
```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: no-rules-map
spec:
tls:
secretName: testsecret
backend:
serviceName: s1
servicePort: 80
```
Please follow [test.sh](https://github.com/bprashanth/Ingress/blob/master/examples/sni/nginx/test.sh) as a guide on how to generate secrets containing SSL certificates. The name of the secret can be different than the name of the certificate.
Check the [example](examples/tls/README.md)
### Default SSL Certificate
NGINX provides the option [server name](http://nginx.org/en/docs/http/server_names.html) as a catch-all in case of requests that do not match one of the configured server names. This configuration works without issues for HTTP traffic. In case of HTTPS NGINX requires a certificate. For this reason the Ingress controller provides the flag `--default-ssl-certificate`. The secret behind this flag contains the default certificate to be used in the mentioned case.
If this flag is not provided NGINX will use a self signed certificate.
Running without the flag `--default-ssl-certificate`:
```
$ curl -v https://10.2.78.7:443 -k
* Rebuilt URL to: https://10.2.78.7:443/
* Trying 10.2.78.4...
* Connected to 10.2.78.7 (10.2.78.7) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=foo.bar.com
* start date: Apr 13 00:50:56 2016 GMT
* expire date: Apr 13 00:50:56 2017 GMT
* issuer: CN=foo.bar.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: 10.2.78.7
> User-Agent: curl/7.47.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.11.1
< Date: Thu, 21 Jul 2016 15:38:46 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Strict-Transport-Security: max-age=15724800; includeSubDomains; preload
<
<span>The page you're looking for could not be found.</span>
* Connection #0 to host 10.2.78.7 left intact
```
Specifying `--default-ssl-certificate=default/foo-tls`:
```
core@localhost ~ $ curl -v https://10.2.78.7:443 -k
* Rebuilt URL to: https://10.2.78.7:443/
* Trying 10.2.78.7...
* Connected to 10.2.78.7 (10.2.78.7) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=foo.bar.com
* start date: Apr 13 00:50:56 2016 GMT
* expire date: Apr 13 00:50:56 2017 GMT
* issuer: CN=foo.bar.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: 10.2.78.7
> User-Agent: curl/7.47.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.11.1
< Date: Mon, 18 Jul 2016 21:02:59 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Strict-Transport-Security: max-age=15724800; includeSubDomains; preload
<
<span>The page you're looking for could not be found.</span>
* Connection #0 to host 10.2.78.7 left intact
```
### Server-side HTTPS enforcement
By default the controller redirects (301) to HTTPS if TLS is enabled for that ingress . If you want to disable that behaviour globally, you can use `ssl-redirect: "false"` in the NGINX config map.
To configure this feature for specific ingress resources, you can use the `ingress.kubernetes.io/ssl-redirect: "false"` annotation in the particular resource.
### HTTP Strict Transport Security
HTTP Strict Transport Security (HSTS) is an opt-in security enhancement specified through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS.
By default the controller redirects (301) to HTTPS if there is a TLS Ingress rule.
To disable this behavior use `hsts=false` in the NGINX config map.
### Automated Certificate Management with Kube-Lego
[Kube-Lego] automatically requests missing certificates or expired from
[Let's Encrypt] by monitoring ingress resources and its referenced secrets. To
enable this for an ingress resource you have to add an annotation:
```
kubectl annotate ing ingress-demo kubernetes.io/tls-acme="true"
```
To setup Kube-Lego you can take a look at this [full example]. The first
version to fully support Kube-Lego is nginx Ingress controller 0.8.
[full example]:https://github.com/jetstack/kube-lego/tree/master/examples
[Kube-Lego]:https://github.com/jetstack/kube-lego
[Let's Encrypt]:https://letsencrypt.org
## Exposing TCP services
Ingress does not support TCP services (yet). For this reason this Ingress controller uses the flag `--tcp-services-configmap` to point to an existing config map where the key is the external port to use and the value is `<namespace/service name>:<service port>`
It is possible to use a number or the name of the port.
The next example shows how to expose the service `example-go` running in the namespace `default` in the port `8080` using the port `9000`
```
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-configmap-example
data:
9000: "default/example-go:8080"
```
Please check the [tcp services](examples/tcp/README.md) example
## Exposing UDP services
Since 1.9.13 NGINX provides [UDP Load Balancing](https://www.nginx.com/blog/announcing-udp-load-balancing/).
Ingress does not support UDP services (yet). For this reason this Ingress controller uses the flag `--udp-services-configmap` to point to an existing config map where the key is the external port to use and the value is `<namespace/service name>:<service port>`
It is possible to use a number or the name of the port.
The next example shows how to expose the service `kube-dns` running in the namespace `kube-system` in the port `53` using the port `53`
```
apiVersion: v1
kind: ConfigMap
metadata:
name: udp-configmap-example
data:
53: "kube-system/kube-dns:53"
```
Please check the [udp services](examples/udp/README.md) example
## Proxy Protocol
If you are using a L4 proxy to forward the traffic to the NGINX pods and terminate HTTP/HTTPS there, you will lose the remote endpoint's IP addresses. To prevent this you could use the [Proxy Protocol](http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) for forwarding traffic, this will send the connection details before forwarding the actual TCP connection itself.
Amongst others [ELBs in AWS](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html) and [HAProxy](http://www.haproxy.org/) support Proxy Protocol.
Please check the [proxy-protocol](examples/proxy-protocol/) example
## Service Integration
On clouds like AWS or GCE, using a service with `Type=LoadBalancer` allows the default kubernetes integration, which can save a lot of work.
By passing the `--publish-service` argument to the controller, the ingress status will be updated with the load balancer configuration of the service, rather than the IP/s of the node/s.
### Custom errors
In case of an error in a request the body of the response is obtained from the `default backend`. Each request to the default backend includes two headers:
- `X-Code` indicates the HTTP code
- `X-Format` the value of the `Accept` header
Using this two headers is possible to use a custom backend service like [this one](https://github.com/aledbf/contrib/tree/nginx-debug-server/Ingress/images/nginx-error-server) that inspect each request and returns a custom error page with the format expected by the client. Please check the example [custom-errors](examples/custom-errors/README.md)
### NGINX status page
The ngx_http_stub_status_module module provides access to basic status information. This is the default module active in the url `/nginx_status`.
This controller provides an alternative to this module using [nginx-module-vts](https://github.com/vozlt/nginx-module-vts) third party module.
To use this module just provide a config map with the key `enable-vts-status=true`. The URL is exposed in the port 8080.
Please check the example `example/rc-default.yaml`
![nginx-module-vts screenshot](https://cloud.githubusercontent.com/assets/3648408/10876811/77a67b70-8183-11e5-9924-6a6d0c5dc73a.png "screenshot with filter")
To extract the information in JSON format the module provides a custom URL: `/nginx_status/format/json`
### Running multiple ingress controllers
If you're running multiple ingress controllers, or running on a cloudprovider that natively handles
ingress, you need to specify the annotation `kubernetes.io/ingress.class: "nginx"` in all ingresses
that you would like this controller to claim. Not specifying the annotation will lead to multiple
ingress controllers claiming the same ingress. Specifying the wrong value will result in all ingress
controllers ignoring the ingress. Multiple ingress controllers running in the same cluster was not
supported in Kubernetes versions < 1.3.
### Running on Cloudproviders
If you're running this ingress controller on a cloudprovider, you should assume the provider also has a native
Ingress controller and specify the ingress.class annotation as indicated in this section.
In addition to this, you will need to add a firewall rule for each port this controller is listening on, i.e :80 and :443.
### Disabling NGINX ingress controller
Setting the annotation `kubernetes.io/ingress.class` to any value other than "nginx" or the empty string, will force the NGINX Ingress controller to ignore your Ingress. Do this if you wish to use one of the other Ingress controllers at the same time as the NGINX controller.
### Log format
The default configuration uses a custom logging format to add additional information about upstreams
```
log_format upstreaminfo '{{ if $cfg.useProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - '
'[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" '
'$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status';
```
Sources:
- [upstream variables](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables)
- [embedded variables](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables)
Description:
- `$proxy_protocol_addr`: if PROXY protocol is enabled
- `$remote_addr`: if PROXY protocol is disabled (default)
- `$proxy_add_x_forwarded_for`: the `X-Forwarded-For` client request header field with the $remote_addr variable appended to it, separated by a comma
- `$remote_user`: user name supplied with the Basic authentication
- `$time_local`: local time in the Common Log Format
- `$request`: full original request line
- `$status`: response status
- `$body_bytes_sent`: number of bytes sent to a client, not counting the response header
- `$http_referer`: value of the Referer header
- `$http_user_agent`: value of User-Agent header
- `$request_length`: request length (including request line, header, and request body)
- `$request_time`: time elapsed since the first bytes were read from the client
- `$proxy_upstream_name`: name of the upstream. The format is `upstream-<namespace>-<service name>-<service port>`
- `$upstream_addr`: keeps the IP address and port, or the path to the UNIX-domain socket of the upstream server. If several servers were contacted during request processing, their addresses are separated by commas
- `$upstream_response_length`: keeps the length of the response obtained from the upstream server
- `$upstream_response_time`: keeps time spent on receiving the response from the upstream server; the time is kept in seconds with millisecond resolution
- `$upstream_status`: keeps status code of the response obtained from the upstream server
### Local cluster
Using [`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh) is possible to start a local kubernetes cluster consisting of a master and a single node. Please read [running-locally.md](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/running-locally.md) for more details.
Use of `hostNetwork: true` in the ingress controller is required to falls back at localhost:8080 for the apiserver if every other client creation check fails (eg: service account not present, kubeconfig doesn't exist, no master env vars...)
### Debug & Troubleshooting
Using the flag `--v=XX` it is possible to increase the level of logging.
In particular:
- `--v=2` shows details using `diff` about the changes in the configuration in nginx
```
I0316 12:24:37.581267 1 utils.go:148] NGINX configuration diff a//etc/nginx/nginx.conf b//etc/nginx/nginx.conf
I0316 12:24:37.581356 1 utils.go:149] --- /tmp/922554809 2016-03-16 12:24:37.000000000 +0000
+++ /tmp/079811012 2016-03-16 12:24:37.000000000 +0000
@@ -235,7 +235,6 @@
upstream default-echoheadersx {
least_conn;
- server 10.2.112.124:5000;
server 10.2.208.50:5000;
}
I0316 12:24:37.610073 1 command.go:69] change in configuration detected. Reloading...
```
- `--v=3` shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format
- `--v=5` configures NGINX in [debug mode](http://nginx.org/en/docs/debugging_log.html)
### Metrics
Using the doc [Instrumenting Kubernetes with a new metric](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/instrumentation.md#instrumenting-kubernetes-with-a-new-metric) the Ingress controller
exposes the registered metrics via HTTP. Besides the default metrics provided by Prometheus is possible to get the number of reloads `reload_operations` and reloads with error `reload_operations_errors`,
ie error in validation in the configuration file before the reload. The metrics are exposed in port `10254` and path `/metrics`.
Using curl: `curl -v <pod ip>:10254/metrics`
### Limitations
- Ingress rules for TLS require the definition of the field `host`
### Why endpoints and not services
The NGINX ingress controller does not uses [Services](http://kubernetes.io/docs/user-guide/services) to route traffic to the pods. Instead it uses the Endpoints API in order to bypass [kube-proxy](http://kubernetes.io/docs/admin/kube-proxy/) to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT.
### NGINX notes
Since `gcr.io/google_containers/nginx-slim:0.8` NGINX contains the next patches:
- Dynamic TLS record size [nginx__dynamic_tls_records.patch](https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/)
NGINX provides the parameter `ssl_buffer_size` to adjust the size of the buffer. Default value in NGINX is 16KB. The ingress controller changes the default to 4KB. This improves the [TLS Time To First Byte (TTTFB)](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) but the size is fixed. This patches adapts the size of the buffer to the content is being served helping to improve the perceived latency.

View file

@ -21,8 +21,8 @@
there are 3 ways to customize nginx
1. config map: create a stand alone config map, use this if you want a different global configuration
2. annoations: [annotate the ingress](#annotations), use this if you want a specific configuration for the site defined in the ingress rule
3. custom template: when is required a specific setting like [open_file_cache](http://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), custom [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format), adjust [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change an through the config map
2. annotations: [annotate the ingress](#annotations), use this if you want a specific configuration for the site defined in the Ingress rule
3. custom template: when more specific settings are required, like [open_file_cache](http://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), custom [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format), adjust [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change an through the config map
#### Custom NGINX configuration

View file

@ -43,7 +43,7 @@ func main() {
}
}
func handleSigterm(ic controller.Interface) {
func handleSigterm(ic *controller.GenericController) {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM)
<-signalChan

View file

@ -240,8 +240,8 @@ func (n NGINXController) OnUpdate(cmap *api.ConfigMap, ingressCfg ingress.Config
conf["upstreams"] = ingressCfg.Upstreams
conf["passthroughUpstreams"] = ingressCfg.PassthroughUpstreams
conf["servers"] = ingressCfg.Servers
conf["tcpUpstreams"] = ingressCfg.TCPUpstreams
conf["udpUpstreams"] = ingressCfg.UDPUpstreams
conf["tcpUpstreams"] = ingressCfg.TCPEndpoints
conf["udpUpstreams"] = ingressCfg.UPDEndpoints
conf["healthzURL"] = ingressCfg.HealthzURL
conf["defResolver"] = cfg.Resolver
conf["sslDHParam"] = ""

View file

@ -197,7 +197,7 @@ func buildProxyPass(input interface{}) string {
proto = "https"
}
// defProxyPass returns the default proxy_pass, just the name of the upstream
defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Upstream.Name)
defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Backend.Name)
// if the path in the ingress rule is equals to the target: no special rewrite
if path == location.Redirect.Target {
return defProxyPass
@ -227,13 +227,13 @@ func buildProxyPass(input interface{}) string {
rewrite %s(.*) /$1 break;
rewrite %s / break;
proxy_pass %s://%s;
%v`, path, location.Path, proto, location.Upstream.Name, abu)
%v`, path, location.Path, proto, location.Backend.Name, abu)
}
return fmt.Sprintf(`
rewrite %s(.*) %s/$1 break;
proxy_pass %s://%s;
%v`, path, location.Redirect.Target, proto, location.Upstream.Name, abu)
%v`, path, location.Redirect.Target, proto, location.Backend.Name, abu)
}
// default proxy_pass

View file

@ -88,7 +88,7 @@ func TestBuildProxyPass(t *testing.T) {
loc := &ingress.Location{
Path: tc.Path,
Redirect: rewrite.Redirect{Target: tc.Target, AddBaseURL: tc.AddBaseURL},
Upstream: ingress.Upstream{Name: "upstream-name"},
Upstream: ingress.Backend{Name: "upstream-name"},
}
pp := buildProxyPass(loc)

View file

@ -1,107 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
k8s-app: default-http-backend
---
apiVersion: v1
kind: ReplicationController
metadata:
name: default-http-backend
spec:
replicas: 1
selector:
k8s-app: default-http-backend
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable 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.0
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: ReplicationController
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-lb
spec:
replicas: 1
selector:
k8s-app: nginx-ingress-lb
template:
metadata:
labels:
k8s-app: nginx-ingress-lb
name: nginx-ingress-lb
spec:
terminationGracePeriodSeconds: 60
containers:
- image: gcr.io/google_containers/nginx-ingress-controller:0.8.3
name: nginx-ingress-lb
imagePullPolicy: Always
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
# use downward API
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
# we expose 18080 to access nginx stats in url /nginx-status
# this is optional
- containerPort: 18080
hostPort: 18080
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend

View file

@ -173,7 +173,7 @@ http {
{{ else }}
least_conn;
{{ end }}
{{ range $server := $upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};
{{ range $server := $upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};
{{ end }}
}
{{ end }}
@ -300,7 +300,7 @@ http {
proxy_set_header Accept-Encoding "";
{{ end }}
set $proxy_upstream_name "{{ $location.Upstream.Name }}";
set $proxy_upstream_name "{{ $location.Backend.Name }}";
{{ buildProxyPass $location }}
}
{{ end }}
@ -396,7 +396,7 @@ stream {
{{ range $i, $passthrough := .passthroughUpstreams }}
upstream {{ $passthrough.Name }}-{{ $i }}-pt {
{{ range $server := $passthrough.Backends }}server {{ $server.Address }}:{{ $server.Port }};
{{ range $server := $passthrough.Endpoints }}server {{ $server.Address }}:{{ $server.Port }};
{{ end }}
}
{{ end }}
@ -413,7 +413,7 @@ stream {
# TCP services
{{ range $i, $tcpServer := .tcpUpstreams }}
upstream tcp-{{ $tcpServer.Upstream.Name }} {
{{ range $server := $tcpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }};
{{ range $server := $tcpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }};
{{ end }}
}
@ -428,7 +428,7 @@ stream {
# UDP services
{{ range $i, $udpServer := .udpUpstreams }}
upstream udp-{{ $udpServer.Upstream.Name }} {
{{ range $server := $udpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }};
{{ range $server := $udpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }};
{{ end }}
}

View file

@ -31,8 +31,8 @@ import (
ssl "k8s.io/ingress/core/pkg/net/ssl"
)
// syncSecret keeps in sync Secrets used by Ingress rules with files to allow
// being used in controllers.
// syncSecret keeps in sync Secrets used by Ingress rules with the files on
// disk to allow being used in controllers.
func (ic *GenericController) syncSecret(k interface{}) error {
if ic.secretQueue.IsShuttingDown() {
return nil
@ -67,7 +67,6 @@ func (ic *GenericController) syncSecret(k interface{}) error {
key = k.(string)
// get secret
secObj, exists, err := ic.secrLister.Store.GetByKey(key)
if err != nil {
return fmt.Errorf("error getting secret %v: %v", key, err)
@ -128,7 +127,7 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
return s, nil
}
// check if secret is referenced in this controller's config
// secrReferenced checks if a secret is referenced or not by one or more Ingress rules
func (ic *GenericController) secrReferenced(name, namespace string) bool {
for _, ingIf := range ic.ingLister.Store.List() {
ing := ingIf.(*extensions.Ingress)
@ -136,7 +135,6 @@ func (ic *GenericController) secrReferenced(name, namespace string) bool {
if err == nil && str == fmt.Sprintf("%v/%v", namespace, name) {
return true
}
if ing.Namespace != namespace {
continue
}
@ -149,7 +147,7 @@ func (ic *GenericController) secrReferenced(name, namespace string) bool {
return false
}
// sslCertTracker ...
// sslCertTracker holds a store of referenced Secrets in Ingress rules
type sslCertTracker struct {
cache.ThreadSafeStore
}

View file

@ -76,17 +76,7 @@ var (
reservedPorts = []string{"80", "443", "8181", "18080"}
)
// Interface holds the methods to handle an Ingress backend
type Interface interface {
Start()
Stop() error
Info() string
healthz.HealthzChecker
}
// GenericController watches the kubernetes api and adds/removes services from the loadbalancer
// GenericController holds the boilerplate code required to build an Ingress controlller.
type GenericController struct {
healthz.HealthzChecker
@ -143,12 +133,13 @@ type Configuration struct {
DefaultHealthzURL string
// optional
PublishService string
// Backend is the particular implementation to be used.
// (for instance NGINX)
Backend ingress.Controller
}
// newIngressController creates an Ingress controller
func newIngressController(config *Configuration) Interface {
func newIngressController(config *Configuration) *GenericController {
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(glog.Infof)
@ -280,7 +271,7 @@ func newIngressController(config *Configuration) Interface {
IngressLister: ic.ingLister,
})
return ic
return &ic
}
func (ic *GenericController) controllersInSync() bool {
@ -365,8 +356,8 @@ func (ic *GenericController) sync(key interface{}) error {
}
}
upstreams, servers := ic.getUpstreamServers()
var passUpstreams []*ingress.SSLPassthroughUpstreams
upstreams, servers := ic.getBackendServers()
var passUpstreams []*ingress.SSLPassthroughBackend
for _, server := range servers {
if !server.SSLPassthrough {
continue
@ -376,8 +367,8 @@ func (ic *GenericController) sync(key interface{}) error {
if loc.Path != rootLocation {
continue
}
passUpstreams = append(passUpstreams, &ingress.SSLPassthroughUpstreams{
Upstream: loc.Upstream,
passUpstreams = append(passUpstreams, &ingress.SSLPassthroughBackend{
Upstream: loc.Backend,
Host: server.Name,
})
break
@ -388,8 +379,8 @@ func (ic *GenericController) sync(key interface{}) error {
HealthzURL: ic.cfg.DefaultHealthzURL,
Upstreams: upstreams,
Servers: servers,
TCPUpstreams: ic.getTCPServices(),
UDPUpstreams: ic.getUDPServices(),
TCPEndpoints: ic.getTCPServices(),
UPDEndpoints: ic.getUDPServices(),
PassthroughUpstreams: passUpstreams,
})
if err != nil {
@ -497,7 +488,7 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api
svc := svcObj.(*api.Service)
var endps []ingress.UpstreamServer
var endps []ingress.Endpoint
targetPort, err := strconv.Atoi(svcPort)
if err != nil {
for _, sp := range svc.Spec.Ports {
@ -516,7 +507,7 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api
}
}
sort.Sort(ingress.UpstreamServerByAddrPort(endps))
sort.Sort(ingress.EndpointByAddrPort(endps))
// tcp upstreams cannot contain empty upstreams and there is no
// default backend equivalent for TCP
@ -527,9 +518,9 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api
svcs = append(svcs, &ingress.Location{
Path: k,
Upstream: ingress.Upstream{
Upstream: ingress.Backend{
Name: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port),
Backends: endps,
Endpoints: endps,
},
})
}
@ -540,21 +531,21 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api
// getDefaultUpstream returns an upstream associated with the
// default backend service. In case of error retrieving information
// configure the upstream to return http code 503.
func (ic *GenericController) getDefaultUpstream() *ingress.Upstream {
upstream := &ingress.Upstream{
func (ic *GenericController) getDefaultUpstream() *ingress.Backend {
upstream := &ingress.Backend{
Name: defUpstreamName,
}
svcKey := ic.cfg.DefaultService
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey)
if err != nil {
glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err)
upstream.Backends = append(upstream.Backends, newDefaultServer())
upstream.Endpoints = append(upstream.Endpoints, newDefaultServer())
return upstream
}
if !svcExists {
glog.Warningf("service %v does not exists", svcKey)
upstream.Backends = append(upstream.Backends, newDefaultServer())
upstream.Endpoints = append(upstream.Endpoints, newDefaultServer())
return upstream
}
@ -562,10 +553,10 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Upstream {
endps := ic.getEndpoints(svc, svc.Spec.Ports[0].TargetPort, api.ProtocolTCP, &healthcheck.Upstream{})
if len(endps) == 0 {
glog.Warningf("service %v does not have any active endpoints", svcKey)
endps = []ingress.UpstreamServer{newDefaultServer()}
endps = []ingress.Endpoint{newDefaultServer()}
}
upstream.Backends = append(upstream.Backends, endps...)
upstream.Endpoints = append(upstream.Endpoints, endps...)
return upstream
}
@ -579,9 +570,9 @@ func (c ingressByRevision) Less(i, j int) bool {
return ir < jr
}
// getUpstreamServers returns a list of Upstream and Server to be used by the backend
// getBackendServers returns a list of Upstream and Server to be used by the backend
// An upstream can be used in multiple servers if the namespace, service name and port are the same
func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingress.Server) {
func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress.Server) {
ings := ic.ingLister.Store.List()
sort.Sort(ingressByRevision(ings))
@ -699,19 +690,19 @@ func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingre
addLoc = false
if !loc.IsDefBackend {
glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name)
glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name)
break
}
glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name)
loc.Upstream = *ups
glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name)
loc.Backend = *ups
loc.IsDefBackend = false
loc.BasicDigestAuth = *nginxAuth
loc.RateLimit = *rl
loc.Redirect = *locRew
loc.SecureUpstream = secUpstream
loc.Whitelist = *wl
loc.Upstream = *ups
loc.Backend = *ups
loc.EnableCORS = eCORS
loc.ExternalAuth = ra
loc.Proxy = *prx
@ -744,16 +735,16 @@ func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingre
// TODO: find a way to make this more readable
// The structs must be ordered to always generate the same file
// if the content does not change.
aUpstreams := make([]*ingress.Upstream, 0, len(upstreams))
aUpstreams := make([]*ingress.Backend, 0, len(upstreams))
for _, value := range upstreams {
if len(value.Backends) == 0 {
if len(value.Endpoints) == 0 {
glog.V(3).Infof("upstream %v does not have any active endpoints. Using default backend", value.Name)
value.Backends = append(value.Backends, newDefaultServer())
value.Endpoints = append(value.Endpoints, newDefaultServer())
}
sort.Sort(ingress.UpstreamServerByAddrPort(value.Backends))
sort.Sort(ingress.EndpointByAddrPort(value.Endpoints))
aUpstreams = append(aUpstreams, value)
}
sort.Sort(ingress.UpstreamByNameServers(aUpstreams))
sort.Sort(ingress.BackendByNameServers(aUpstreams))
aServers := make([]*ingress.Server, 0, len(servers))
for _, value := range servers {
@ -781,8 +772,8 @@ func (ic *GenericController) getAuthCertificate(secretName string) (*authtls.SSL
// createUpstreams creates the NGINX upstreams for each service referenced in
// Ingress rules. The servers inside the upstream are endpoints.
func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ingress.Upstream {
upstreams := make(map[string]*ingress.Upstream)
func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ingress.Backend {
upstreams := make(map[string]*ingress.Backend)
upstreams[defUpstreamName] = ic.getDefaultUpstream()
upsDefaults := ic.cfg.Backend.UpstreamDefaults()
@ -803,7 +794,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName)
endps, err := ic.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String(), hz)
upstreams[defBackend].Backends = append(upstreams[defBackend].Backends, endps...)
upstreams[defBackend].Endpoints = append(upstreams[defBackend].Endpoints, endps...)
if err != nil {
glog.Warningf("error creating upstream %v: %v", defBackend, err)
}
@ -833,7 +824,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
glog.Warningf("error obtaining service endpoints: %v", err)
continue
}
upstreams[name].Backends = endp
upstreams[name].Endpoints = endp
}
}
}
@ -844,10 +835,10 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
// serviceEndpoints returns the upstream servers (endpoints) associated
// to a service.
func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
hz *healthcheck.Upstream) ([]ingress.UpstreamServer, error) {
hz *healthcheck.Upstream) ([]ingress.Endpoint, error) {
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey)
var upstreams []ingress.UpstreamServer
var upstreams []ingress.Endpoint
if err != nil {
return upstreams, fmt.Errorf("error getting service %v from the cache: %v", svcKey, err)
}
@ -878,7 +869,7 @@ func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
return upstreams, nil
}
func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Upstream) map[string]*ingress.Server {
func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Backend) map[string]*ingress.Server {
servers := make(map[string]*ingress.Server)
ngxProxy := *proxy.ParseAnnotations(ic.cfg.Backend.UpstreamDefaults(), nil)
@ -973,15 +964,15 @@ func (ic *GenericController) getEndpoints(
s *api.Service,
servicePort intstr.IntOrString,
proto api.Protocol,
hz *healthcheck.Upstream) []ingress.UpstreamServer {
hz *healthcheck.Upstream) []ingress.Endpoint {
glog.V(3).Infof("getting endpoints for service %v/%v and port %v", s.Namespace, s.Name, servicePort.String())
ep, err := ic.endpLister.GetServiceEndpoints(s)
if err != nil {
glog.Warningf("unexpected error obtaining service endpoints: %v", err)
return []ingress.UpstreamServer{}
return []ingress.Endpoint{}
}
upsServers := []ingress.UpstreamServer{}
upsServers := []ingress.Endpoint{}
for _, ss := range ep.Subsets {
for _, epPort := range ss.Ports {
@ -1023,7 +1014,7 @@ func (ic *GenericController) getEndpoints(
}
for _, epAddress := range ss.Addresses {
ups := ingress.UpstreamServer{
ups := ingress.Endpoint{
Address: epAddress.IP,
Port: fmt.Sprintf("%v", targetPort),
MaxFails: hz.MaxFails,

View file

@ -23,8 +23,8 @@ import (
kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
// NewIngressController returns a configured Ingress controller ready to start
func NewIngressController(backend ingress.Controller) Interface {
// NewIngressController returns a configured Ingress controller
func NewIngressController(backend ingress.Controller) *GenericController {
var (
flags = pflag.NewFlagSet("", pflag.ExitOnError)
@ -33,7 +33,7 @@ func NewIngressController(backend ingress.Controller) Interface {
namespace/name. The controller uses the first node port of this Service for
the default backend.`)
ingressClass = flags.String("ingress-class", "nginx",
ingressClass = flags.String("ingress-class", "",
`Name of the ingress class to route through this controller.`)
configMap = flags.String("configmap", "",
@ -49,7 +49,7 @@ func NewIngressController(backend ingress.Controller) Interface {
The key in the map indicates the external port to be used. The value is the name of the
service with the format namespace/serviceName and the port of the service could be a
number of the name of the port.
The ports 80 and 443 are not allowed as external ports. This ports are reserved for nginx`)
The ports 80 and 443 are not allowed as external ports. This ports are reserved for the backend`)
udpConfigMapName = flags.String("udp-services-configmap", "",
`Name of the ConfigMap that contains the definition of the UDP services to expose.
@ -152,7 +152,7 @@ func NewIngressController(backend ingress.Controller) Interface {
return ic
}
func registerHandlers(enableProfiling bool, port int, ic Interface) {
func registerHandlers(enableProfiling bool, port int, ic *GenericController) {
mux := http.NewServeMux()
healthz.InstallHandler(mux, ic)

View file

@ -25,16 +25,16 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions"
)
// newDefaultServer return an UpstreamServer to be use as default server that returns 503.
func newDefaultServer() ingress.UpstreamServer {
return ingress.UpstreamServer{Address: "127.0.0.1", Port: "8181"}
// newDefaultServer return an BackendServer to be use as default server that returns 503.
func newDefaultServer() ingress.Endpoint {
return ingress.Endpoint{Address: "127.0.0.1", Port: "8181"}
}
// newUpstream creates an upstream without servers.
func newUpstream(name string) *ingress.Upstream {
return &ingress.Upstream{
func newUpstream(name string) *ingress.Backend {
return &ingress.Backend{
Name: name,
Backends: []ingress.UpstreamServer{},
Endpoints: []ingress.Endpoint{},
}
}

View file

@ -1,214 +0,0 @@
/*
Copyright 2015 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 ingress
import (
"os/exec"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"
"k8s.io/ingress/core/pkg/ingress/annotations/authtls"
"k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist"
"k8s.io/ingress/core/pkg/ingress/annotations/proxy"
"k8s.io/ingress/core/pkg/ingress/annotations/ratelimit"
"k8s.io/ingress/core/pkg/ingress/annotations/rewrite"
"k8s.io/ingress/core/pkg/ingress/defaults"
)
var (
// DefaultSSLDirectory defines the location where the SSL certificates will be generated
DefaultSSLDirectory = "/ingress-controller/ssl"
)
// Controller ...
type Controller interface {
// Start returns the command is executed to start the backend.
// The command must run in foreground.
Start()
// Stop stops the backend
Stop() error
// Restart reload the backend with the a configuration file returning
// the combined output of Stdout and Stderr
Restart(data []byte) ([]byte, error)
// Tests returns a commands that checks if the configuration file is valid
// Example: nginx -t -c <file>
Test(file string) *exec.Cmd
// OnUpdate callback invoked from the sync queue https://k8s.io/ingress/core/blob/master/pkg/ingress/controller/controller.go#L355
// when an update occurs. This is executed frequently because Ingress
// controllers watches changes in:
// - Ingresses: main work
// - Secrets: referenced from Ingress rules with TLS configured
// - ConfigMaps: where the controller reads custom configuration
// - Services: referenced from Ingress rules and required to obtain
// information about ports and annotations
// - Endpoints: referenced from Services and what the backend uses
// to route traffic
//
// ConfigMap content of --configmap
// Configuration returns the translation from Ingress rules containing
// information about all the upstreams (service endpoints ) "virtual"
// servers (FQDN)
// and all the locations inside each server. Each location contains
// information about all the annotations were configured
// https://k8s.io/ingress/core/blob/master/pkg/ingress/types.go#L48
OnUpdate(*api.ConfigMap, Configuration) ([]byte, error)
// UpstreamDefaults returns the minimum settings required to configure the
// communication to upstream servers (endpoints)
UpstreamDefaults() defaults.Backend
// IsReloadRequired checks if the backend must be reloaded or not.
// The parameter contains the new rendered template
IsReloadRequired([]byte) bool
// Info returns information about the ingress controller
// This can include build version, repository, etc.
Info() string
}
// Configuration describes
type Configuration struct {
HealthzURL string
Upstreams []*Upstream
Servers []*Server
TCPUpstreams []*Location
UDPUpstreams []*Location
PassthroughUpstreams []*SSLPassthroughUpstreams
}
// Upstream describes an upstream server (endpoint)
type Upstream struct {
// Secure indicates if the communication with the en
Secure bool
// Name represents an unique api.Service name formatted
// as <namespace>-<name>-<port>
Name string
// Backends
Backends []UpstreamServer
}
// SSLPassthroughUpstreams describes an SSL upstream server configured
// as passthrough (no TLS termination)
type SSLPassthroughUpstreams struct {
Upstream
Host string
}
// UpstreamByNameServers sorts upstreams by name
type UpstreamByNameServers []*Upstream
func (c UpstreamByNameServers) Len() int { return len(c) }
func (c UpstreamByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c UpstreamByNameServers) Less(i, j int) bool {
return c[i].Name < c[j].Name
}
// UpstreamServer describes a server in an upstream
type UpstreamServer struct {
// Address IP address of the endpoint
Address string
Port string
// MaxFails returns the maximum number of check failures
// allowed before this should be considered dow.
// Setting 0 indicates that the check is performed by a Kubernetes probe
MaxFails int
FailTimeout int
}
// Server describes a virtual server
type Server struct {
Name string
SSL bool
SSLPassthrough bool
SSLCertificate string
//SSLCertificateKey string
SSLPemChecksum string
Locations []*Location
}
// Location describes a server location
type Location struct {
IsDefBackend bool
SecureUpstream bool
EnableCORS bool
Path string
Upstream Upstream
BasicDigestAuth auth.BasicDigest
RateLimit ratelimit.RateLimit
Redirect rewrite.Redirect
Whitelist ipwhitelist.SourceRange
ExternalAuth authreq.External
Proxy proxy.Configuration
CertificateAuth authtls.SSLCert
}
// UpstreamServerByAddrPort sorts upstream servers by address and port
type UpstreamServerByAddrPort []UpstreamServer
func (c UpstreamServerByAddrPort) Len() int { return len(c) }
func (c UpstreamServerByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c UpstreamServerByAddrPort) Less(i, j int) bool {
iName := c[i].Address
jName := c[j].Address
if iName != jName {
return iName < jName
}
iU := c[i].Port
jU := c[j].Port
return iU < jU
}
// ServerByName sorts server by name
type ServerByName []*Server
func (c ServerByName) Len() int { return len(c) }
func (c ServerByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c ServerByName) Less(i, j int) bool {
return c[i].Name < c[j].Name
}
// LocationByPath sorts location by path
// Location / is the last one
type LocationByPath []*Location
func (c LocationByPath) Len() int { return len(c) }
func (c LocationByPath) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c LocationByPath) Less(i, j int) bool {
return c[i].Path > c[j].Path
}
// SSLCert describes a SSL certificate to be used in a server
type SSLCert struct {
api.ObjectMeta
//CertFileName string
//KeyFileName string
CAFileName string
// PemFileName contains the path to the file with the certificate and key concatenated
PemFileName string
// PemSHA contains the sha1 of the pem file.
// This is used to detect changes in the secret that contains the certificates
PemSHA string
// CN contains all the common names defined in the SSL certificate
CN []string
}
// GetObjectKind implements the ObjectKind interface as a noop
func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }