Merge pull request #11 from aledbf/remove-examples
Remove nginx-alpha, examples and simplify read files
This commit is contained in:
commit
1c8773fc98
45 changed files with 0 additions and 2395 deletions
|
@ -9,131 +9,3 @@ Configuring a webserver or loadbalancer is harder than it should be. Most webser
|
|||
## What is an Ingress Controller?
|
||||
|
||||
An Ingress Controller is a daemon, deployed as a Kubernetes Pod, that watches the ApiServer's `/ingresses` endpoint for updates to the [Ingress resource](https://github.com/kubernetes/kubernetes/blob/master/docs/user-guide/ingress.md). Its job is to satisfy requests for ingress.
|
||||
|
||||
## Writing an Ingress Controller
|
||||
|
||||
Writing an Ingress controller is simple. By way of example, the [nginx controller] (nginx-alpha) does the following:
|
||||
* Poll until apiserver reports a new Ingress
|
||||
* Write the nginx config file based on a [go text/template](https://golang.org/pkg/text/template/)
|
||||
* Reload nginx
|
||||
|
||||
Pay attention to how it denormalizes the Kubernetes Ingress object into an nginx config:
|
||||
```go
|
||||
const (
|
||||
nginxConf = `
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
{{range $ing := .Items}}
|
||||
{{range $rule := $ing.Spec.Rules}}
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{$rule.Host}};
|
||||
{{ range $path := $rule.HTTP.Paths }}
|
||||
location {{$path.Path}} {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://{{$path.Backend.ServiceName}}.{{$ing.Namespace}}.svc.cluster.local:{{$path.Backend.ServicePort}};
|
||||
}{{end}}
|
||||
}{{end}}{{end}}
|
||||
}`
|
||||
)
|
||||
```
|
||||
|
||||
You can take a similar approach to denormalize the Ingress to a [haproxy config](https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/template.cfg) or use it to configure a cloud loadbalancer such as a [GCE L7](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/README.md).
|
||||
|
||||
And here is the Ingress controller's control loop:
|
||||
|
||||
```go
|
||||
for {
|
||||
rateLimiter.Accept()
|
||||
ingresses, err := ingClient.List(labels.Everything(), fields.Everything())
|
||||
if err != nil || reflect.DeepEqual(ingresses.Items, known.Items) {
|
||||
continue
|
||||
}
|
||||
if w, err := os.Create("/etc/nginx/nginx.conf"); err != nil {
|
||||
log.Fatalf("Failed to open %v: %v", nginxConf, err)
|
||||
} else if err := tmpl.Execute(w, ingresses); err != nil {
|
||||
log.Fatalf("Failed to write template %v", err)
|
||||
}
|
||||
shellOut("nginx -s reload")
|
||||
}
|
||||
```
|
||||
|
||||
All this is doing is:
|
||||
* List Ingresses, optionally you can watch for changes (see [GCE Ingress controller](https://github.com/kubernetes/contrib/blob/master/ingress/controllers/gce/controller/controller.go) for an example)
|
||||
* Executes the template and writes results to `/etc/nginx/nginx.conf`
|
||||
* Reloads nginx
|
||||
|
||||
You can deploy this controller to a Kubernetes cluster by [creating an RC](nginx-alpha/rc.yaml). After doing so, if you were to create an Ingress such as:
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: test
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: fooSvc
|
||||
servicePort: 80
|
||||
- host: bar.baz.com
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: barSvc
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
Where `fooSvc` and `barSvc` are 2 services running in your Kubernetes cluster. The controller would satisfy the Ingress by writing a configuration file to /etc/nginx/nginx.conf:
|
||||
```nginx
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
server_name foo.bar.com;
|
||||
|
||||
location /foo {
|
||||
proxy_pass http://fooSvc;
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
server_name bar.baz.com;
|
||||
|
||||
location /bar {
|
||||
proxy_pass http://barSvc;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And you can reach the `/foo` and `/bar` endpoints on the publicIP of the VM the nginx-ingress pod landed on.
|
||||
```
|
||||
$ kubectl get pods -o wide
|
||||
NAME READY STATUS RESTARTS AGE NODE
|
||||
nginx-ingress-tk7dl 1/1 Running 0 3m e2e-test-beeps-minion-15p3
|
||||
|
||||
$ kubectl get nodes e2e-test-beeps-minion-15p3 -o yaml | grep -i externalip -B 1
|
||||
- address: 104.197.203.179
|
||||
type: ExternalIP
|
||||
|
||||
$ curl --resolve foo.bar.com:80:104.197.203.179 foo.bar.com/foo
|
||||
```
|
||||
|
||||
## Future work
|
||||
|
||||
This section can also bear the title "why anyone would want to write an Ingress controller instead of directly configuring Services". There is more to Ingress than webserver configuration. *Real* HA usually involves the configuration of gateways and packet forwarding devices, which most cloud providers allow you to do through an API. See the GCE Loadbalancer Controller, which is deployed as a [cluster addon](https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/cluster-loadbalancing/glbc) in GCE and GKE clusters for more advanced Ingress configuration examples. Post 1.2 the Ingress resource will support at least the following:
|
||||
* More TLS options (SNI, re-encrypt etc)
|
||||
* L4 and L7 loadbalancing (it currently only supports HTTP rules)
|
||||
* Ingress Rules that are not limited to a simple path regex (eg: redirect rules, session persistence)
|
||||
|
||||
And is expected to be the way one configures "frontends" that handle user traffic for a Kubernetes cluster.
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
# Copyright 2015 The Kubernetes Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
FROM gcr.io/google_containers/nginx
|
||||
COPY controller /
|
||||
COPY default.conf /etc/nginx/nginx.conf
|
||||
CMD ["/controller"]
|
|
@ -1,17 +0,0 @@
|
|||
all: push
|
||||
|
||||
# 0.0 shouldn't clobber any release builds
|
||||
TAG = 0.0
|
||||
PREFIX = gcr.io/google_containers/nginx-ingress
|
||||
|
||||
controller: controller.go
|
||||
CGO_ENABLED=0 GOOS=linux godep go build -a -installsuffix cgo -ldflags '-w' -o controller ./controller.go
|
||||
|
||||
container: controller
|
||||
docker build -t $(PREFIX):$(TAG) .
|
||||
|
||||
push: container
|
||||
gcloud docker push $(PREFIX):$(TAG)
|
||||
|
||||
clean:
|
||||
rm -f controller
|
|
@ -1,116 +0,0 @@
|
|||
# Nginx Ingress Controller
|
||||
|
||||
This is a simple nginx Ingress controller. Expect it to grow up. See [Ingress controller documentation](../README.md) for details on how it works.
|
||||
|
||||
## Deploying the controller
|
||||
|
||||
Deploying the controller is as easy as creating the RC in this directory. Having done so you can test it with the following echoheaders application:
|
||||
|
||||
```yaml
|
||||
# 3 Services for the 3 endpoints of the Ingress
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: echoheaders-x
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
nodePort: 30301
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: echoheaders
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: echoheaders-default
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
nodePort: 30302
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: echoheaders
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: echoheaders-y
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
nodePort: 30284
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: echoheaders
|
||||
---
|
||||
# A single RC matching all Services
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: echoheaders
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
containers:
|
||||
- name: echoheaders
|
||||
image: gcr.io/google_containers/echoserver:1.0
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
---
|
||||
# An Ingress with 2 hosts and 3 endpoints
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: echomap
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
||||
- host: bar.baz.com
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: echoheaders-y
|
||||
servicePort: 80
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
||||
```
|
||||
You should be able to access the Services on the public IP of the node the nginx pod lands on.
|
||||
|
||||
## Wishlist
|
||||
|
||||
* SSL/TLS
|
||||
* Production ready options
|
||||
* Dynamic adding backends
|
||||
* Varied loadbalancing algorithms
|
||||
|
||||
... this list goes on. If you feel you know nginx better than I do, please contribute.
|
||||
|
|
@ -1,95 +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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"text/template"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util/flowcontrol"
|
||||
)
|
||||
|
||||
const (
|
||||
nginxConf = `
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
# http://nginx.org/en/docs/http/ngx_http_core_module.html
|
||||
types_hash_max_size 2048;
|
||||
server_names_hash_max_size 512;
|
||||
server_names_hash_bucket_size 64;
|
||||
|
||||
{{range $ing := .Items}}
|
||||
{{range $rule := $ing.Spec.Rules}}
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{$rule.Host}};
|
||||
{{ range $path := $rule.HTTP.Paths }}
|
||||
location {{$path.Path}} {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://{{$path.Backend.ServiceName}}.{{$ing.Namespace}}.svc.cluster.local:{{$path.Backend.ServicePort}};
|
||||
}{{end}}
|
||||
}{{end}}{{end}}
|
||||
}`
|
||||
)
|
||||
|
||||
func shellOut(cmd string) {
|
||||
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to execute %v: %v, err: %v", cmd, string(out), err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var ingClient client.IngressInterface
|
||||
if kubeClient, err := client.NewInCluster(); err != nil {
|
||||
log.Fatalf("Failed to create client: %v.", err)
|
||||
} else {
|
||||
ingClient = kubeClient.Extensions().Ingress(api.NamespaceAll)
|
||||
}
|
||||
tmpl, _ := template.New("nginx").Parse(nginxConf)
|
||||
rateLimiter := flowcontrol.NewTokenBucketRateLimiter(0.1, 1)
|
||||
known := &extensions.IngressList{}
|
||||
|
||||
// Controller loop
|
||||
shellOut("nginx")
|
||||
for {
|
||||
rateLimiter.Accept()
|
||||
ingresses, err := ingClient.List(api.ListOptions{})
|
||||
if err != nil {
|
||||
log.Printf("Error retrieving ingresses: %v", err)
|
||||
continue
|
||||
}
|
||||
if reflect.DeepEqual(ingresses.Items, known.Items) {
|
||||
continue
|
||||
}
|
||||
known = ingresses
|
||||
if w, err := os.Create("/etc/nginx/nginx.conf"); err != nil {
|
||||
log.Fatalf("Failed to open %v: %v", nginxConf, err)
|
||||
} else if err := tmpl.Execute(w, ingresses); err != nil {
|
||||
log.Fatalf("Failed to write template %v", err)
|
||||
}
|
||||
shellOut("nginx -s reload")
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
# A very simple nginx configuration file that forces nginx to start as a daemon.
|
||||
events {}
|
||||
http {}
|
||||
daemon on;
|
|
@ -1,22 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx-ingress
|
||||
labels:
|
||||
app: nginx-ingress
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
app: nginx-ingress
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-ingress
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/google_containers/nginx-ingress:0.1
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
hostPort: 80
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
All the examples references the services `echoheaders-x` and `echoheaders-y`
|
||||
|
||||
```
|
||||
kubectl run echoheaders --image=gcr.io/google_containers/echoserver:1.4 --replicas=1 --port=8080
|
||||
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
|
||||
kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
|
||||
```
|
|
@ -1,126 +0,0 @@
|
|||
|
||||
This example shows how to add authentication in a Ingress rule using a secret that contains a file generated with `htpasswd`.
|
||||
|
||||
|
||||
```
|
||||
$ htpasswd -c auth foo
|
||||
New password: <bar>
|
||||
New password:
|
||||
Re-type new password:
|
||||
Adding password for user foo
|
||||
```
|
||||
|
||||
```
|
||||
$ kubectl create secret generic basic-auth --from-file=auth
|
||||
secret "basic-auth" created
|
||||
```
|
||||
|
||||
```
|
||||
$ kubectl get secret basic-auth -o yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
auth: Zm9vOiRhcHIxJE9GRzNYeWJwJGNrTDBGSERBa29YWUlsSDkuY3lzVDAK
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: basic-auth
|
||||
namespace: default
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
```
|
||||
echo "
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-with-auth
|
||||
annotations:
|
||||
# type of authentication
|
||||
ingress.kubernetes.io/auth-type: basic
|
||||
# name of the secret that contains the user/password definitions
|
||||
ingress.kubernetes.io/auth-secret: basic-auth
|
||||
# message to display with an appropiate context why the authentication is required
|
||||
ingress.kubernetes.io/auth-realm: "Authentication Required - foo"
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
```
|
||||
$ curl -v http://10.2.29.4/ -H 'Host: foo.bar.com'
|
||||
* Trying 10.2.29.4...
|
||||
* Connected to 10.2.29.4 (10.2.29.4) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: foo.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 401 Unauthorized
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 11 May 2016 05:27:23 GMT
|
||||
< Content-Type: text/html
|
||||
< Content-Length: 195
|
||||
< Connection: keep-alive
|
||||
< WWW-Authenticate: Basic realm="Authentication Required - foo"
|
||||
<
|
||||
<html>
|
||||
<head><title>401 Authorization Required</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>401 Authorization Required</h1></center>
|
||||
<hr><center>nginx/1.10.0</center>
|
||||
</body>
|
||||
</html>
|
||||
* Connection #0 to host 10.2.29.4 left intact
|
||||
```
|
||||
|
||||
```
|
||||
$ curl -v http://10.2.29.4/ -H 'Host: foo.bar.com' -u 'foo:bar'
|
||||
* Trying 10.2.29.4...
|
||||
* Connected to 10.2.29.4 (10.2.29.4) port 80 (#0)
|
||||
* Server auth using Basic with user 'foo'
|
||||
> GET / HTTP/1.1
|
||||
> Host: foo.bar.com
|
||||
> Authorization: Basic Zm9vOmJhcg==
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 11 May 2016 06:05:26 GMT
|
||||
< Content-Type: text/plain
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.29.4
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://foo.bar.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.11 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
authorization=Basic Zm9vOmJhcg==
|
||||
connection=close
|
||||
host=foo.bar.com
|
||||
user-agent=curl/7.43.0
|
||||
x-forwarded-for=10.2.29.1
|
||||
x-forwarded-host=foo.bar.com
|
||||
x-forwarded-port=80
|
||||
x-forwarded-proto=http
|
||||
x-real-ip=10.2.29.1
|
||||
BODY:
|
||||
* Connection #0 to host 10.2.29.4 left intact
|
||||
-no body in request-
|
||||
```
|
|
@ -1,57 +0,0 @@
|
|||
The next command shows the defaults:
|
||||
```
|
||||
$ ./nginx-third-party-lb --dump-nginx—configuration
|
||||
Example of ConfigMap to customize NGINX configuration:
|
||||
data:
|
||||
body-size: 1m
|
||||
error-log-level: info
|
||||
gzip-types: application/atom+xml application/javascript application/json application/rss+xml
|
||||
application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json
|
||||
application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon
|
||||
text/css text/plain text/x-component
|
||||
hts-include-subdomains: "true"
|
||||
hts-max-age: "15724800"
|
||||
keep-alive: "75"
|
||||
max-worker-connections: "16384"
|
||||
proxy-connect-timeout: "30"
|
||||
proxy-read-timeout: "30"
|
||||
proxy-real-ip-cidr: 0.0.0.0/0
|
||||
proxy-send-timeout: "30"
|
||||
server-name-hash-bucket-size: "64"
|
||||
server-name-hash-max-size: "512"
|
||||
ssl-buffer-size: 4k
|
||||
ssl-ciphers: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
|
||||
ssl-protocols: TLSv1 TLSv1.1 TLSv1.2
|
||||
ssl-session-cache: "true"
|
||||
ssl-session-cache-size: 10m
|
||||
ssl-session-tickets: "true"
|
||||
ssl-session-timeout: 10m
|
||||
use-gzip: "true"
|
||||
use-hts: "true"
|
||||
worker-processes: "8"
|
||||
metadata:
|
||||
name: custom-name
|
||||
namespace: a-valid-namespace
|
||||
```
|
||||
|
||||
For instance, if we want to change the timeouts we need to create a ConfigMap:
|
||||
```
|
||||
$ cat nginx-load-balancer-conf.yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
proxy-connect-timeout: "10"
|
||||
proxy-read-timeout: "120"
|
||||
proxy-send-imeout: "120"
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-load-balancer-conf
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
$ kubectl create -f nginx-load-balancer-conf.yaml
|
||||
```
|
||||
|
||||
Please check the example `rc-custom-configuration.yaml`
|
||||
|
||||
If the Configmap it is updated, NGINX will be reloaded with the new configuration
|
|
@ -1,52 +0,0 @@
|
|||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --nginx-configmap=$(POD_NAMESPACE)/nginx-load-balancer-conf
|
|
@ -1,80 +0,0 @@
|
|||
|
||||
This example shows how is possible to use a custom backend to render custom error pages. The code of this example is located here [nginx-debug-server](https://github.com/aledbf/contrib/tree/nginx-debug-server)
|
||||
|
||||
|
||||
The idea is to use the headers `X-Code` and `X-Format` that NGINX pass to the backend in case of an error to find out the best existent representation of the response to be returned. i.e. if the request contains an `Accept` header of type `json` the error should be in that format and not in `html` (the default in NGINX).
|
||||
|
||||
First create the custom backend to use in the Ingress controller
|
||||
|
||||
```$ kubectl create -f custom-default-backend.yaml
|
||||
service "nginx-errors" created
|
||||
replicationcontroller "nginx-errors" created
|
||||
```
|
||||
|
||||
```$ kubectl get svc
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
echoheaders 10.3.0.7 nodes 80/TCP 23d
|
||||
kubernetes 10.3.0.1 <none> 443/TCP 34d
|
||||
nginx-errors 10.3.0.102 <none> 80/TCP 11s
|
||||
```
|
||||
|
||||
```$ kubectl get rc
|
||||
CONTROLLER REPLICAS AGE
|
||||
echoheaders 1 19d
|
||||
nginx-errors 1 19s
|
||||
```
|
||||
|
||||
Next create the Ingress controller executing
|
||||
```
|
||||
$ kubectl create -f rc-custom-errors.yaml
|
||||
```
|
||||
|
||||
Now to check if this is working we use curl:
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: 172.17.4.99
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 04 May 2016 02:53:45 GMT
|
||||
< Content-Type: text/html
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
<span>The page you're looking for could not be found.</span>
|
||||
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
Specifying json as expected format:
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/ -H 'Accept: application/json'
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: 172.17.4.99
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: application/json
|
||||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 04 May 2016 02:54:00 GMT
|
||||
< Content-Type: text/html
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
{ "message": "The page you're looking for could not be found" }
|
||||
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
By default the Ingress controller provides support for `html`, `json` and `XML`.
|
|
@ -1,31 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-errors
|
||||
labels:
|
||||
app: nginx-errors
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: nginx-errors
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx-errors
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-errors
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-errors
|
||||
image: aledbf/nginx-error-server:0.1
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -1,51 +0,0 @@
|
|||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/nginx-errors
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
This example shows how is possible to use a custom template
|
||||
|
||||
First create a configmap with a template inside running:
|
||||
```
|
||||
kubectl create configmap nginx-template --from-file=nginx.tmpl=../../nginx.tmpl
|
||||
```
|
||||
|
||||
Next create the rc `kubectl create -f custom-template.yaml`
|
|
@ -1,62 +0,0 @@
|
|||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/template
|
||||
name: nginx-template-volume
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: nginx-template-volume
|
||||
configMap:
|
||||
name: nginx-template
|
||||
items:
|
||||
- key: nginx.tmpl
|
||||
path: nginx.tmpl
|
|
@ -1,45 +0,0 @@
|
|||
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: echoheaders
|
||||
annotations:
|
||||
ingress.kubernetes.io/upstream-fail-timeout: "30"
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
Check the annotation is present in the Ingress rule:
|
||||
```
|
||||
kubectl get ingress echoheaders -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-echoheaders-x-80 {
|
||||
least_conn;
|
||||
server 10.2.92.2:8080 max_fails=5 fail_timeout=30;
|
||||
|
||||
}
|
||||
....
|
||||
```
|
||||
|
||||
|
||||

|
Binary file not shown.
Before Width: | Height: | Size: 59 KiB |
|
@ -1,8 +0,0 @@
|
|||
|
||||
In some cases could be required to run the Ingress controller in all the nodes in cluster.
|
||||
Using [DaemonSet](https://github.com/kubernetes/kubernetes/blob/master/docs/design/daemon.md) it is possible to do this.
|
||||
The file `as-daemonset.yaml` contains an example
|
||||
|
||||
```
|
||||
kubectl create -f as-daemonset.yaml
|
||||
```
|
|
@ -1,45 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: nginx-ingress-lb
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -1,36 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: default-http-backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
app: default-http-backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
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
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
Create the Ingress controller
|
||||
```
|
||||
kubectl create -f rc-default.yaml
|
||||
```
|
||||
|
||||
To test if evertyhing is working correctly:
|
||||
|
||||
`curl -v http://<node IP address>:80/foo -H 'Host: foo.bar.com'`
|
||||
|
||||
You should see an output similar to
|
||||
```
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET /foo HTTP/1.1
|
||||
> Host: foo.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: nginx/1.9.8
|
||||
< Date: Tue, 15 Dec 2015 13:45:13 GMT
|
||||
< Content-Type: text/plain
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.84.43
|
||||
command=GET
|
||||
real path=/foo
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://foo.bar.com:8080/foo
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.7 - lua: 9019
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
host=foo.bar.com
|
||||
user-agent=curl/7.43.0
|
||||
x-forwarded-for=172.17.4.1
|
||||
x-forwarded-host=foo.bar.com
|
||||
x-forwarded-server=foo.bar.com
|
||||
x-real-ip=172.17.4.1
|
||||
BODY:
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
If we try to get a non exising route like `/foobar` we should see
|
||||
```
|
||||
$ curl -v 172.17.4.99/foobar -H 'Host: foo.bar.com'
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET /foobar HTTP/1.1
|
||||
> Host: foo.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
< Server: nginx/1.9.8
|
||||
< Date: Tue, 15 Dec 2015 13:48:18 GMT
|
||||
< Content-Type: text/html
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
default backend - 404
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
(this test checked that the default backend is properly working)
|
||||
|
||||
*Replacing the default backend with a custom one we can change the default error pages provided by nginx*
|
|
@ -1,51 +0,0 @@
|
|||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -1,148 +0,0 @@
|
|||
# External authentication
|
||||
|
||||
### Example 1:
|
||||
|
||||
Use an external service (Basic Auth) located in `https://httpbin.org`
|
||||
|
||||
```
|
||||
$ kubectl create -f ingress.yaml
|
||||
ingress "external-auth" created
|
||||
$ kubectl get ing external-auth
|
||||
NAME HOSTS ADDRESS PORTS AGE
|
||||
external-auth external-auth-01.sample.com 172.17.4.99 80 13s
|
||||
$ kubectl get ing external-auth -o yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
ingress.kubernetes.io/auth-url: https://httpbin.org/basic-auth/user/passwd
|
||||
creationTimestamp: 2016-10-03T13:50:35Z
|
||||
generation: 1
|
||||
name: external-auth
|
||||
namespace: default
|
||||
resourceVersion: "2068378"
|
||||
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/external-auth
|
||||
uid: 5c388f1d-8970-11e6-9004-080027d2dc94
|
||||
spec:
|
||||
rules:
|
||||
- host: external-auth-01.sample.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
path: /
|
||||
status:
|
||||
loadBalancer:
|
||||
ingress:
|
||||
- ip: 172.17.4.99
|
||||
$
|
||||
```
|
||||
|
||||
Test 1: no username/password (expect code 401)
|
||||
```
|
||||
$ curl -k http://172.17.4.99 -v -H 'Host: external-auth-01.sample.com'
|
||||
* Rebuilt URL to: http://172.17.4.99/
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: external-auth-01.sample.com
|
||||
> User-Agent: curl/7.50.1
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 401 Unauthorized
|
||||
< Server: nginx/1.11.3
|
||||
< Date: Mon, 03 Oct 2016 14:52:08 GMT
|
||||
< Content-Type: text/html
|
||||
< Content-Length: 195
|
||||
< Connection: keep-alive
|
||||
< WWW-Authenticate: Basic realm="Fake Realm"
|
||||
<
|
||||
<html>
|
||||
<head><title>401 Authorization Required</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>401 Authorization Required</h1></center>
|
||||
<hr><center>nginx/1.11.3</center>
|
||||
</body>
|
||||
</html>
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
Test 2: valid username/password (expect code 200)
|
||||
```
|
||||
$ curl -k http://172.17.4.99 -v -H 'Host: external-auth-01.sample.com' -u 'user:passwd'
|
||||
* Rebuilt URL to: http://172.17.4.99/
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
* Server auth using Basic with user 'user'
|
||||
> GET / HTTP/1.1
|
||||
> Host: external-auth-01.sample.com
|
||||
> Authorization: Basic dXNlcjpwYXNzd2Q=
|
||||
> User-Agent: curl/7.50.1
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: nginx/1.11.3
|
||||
< Date: Mon, 03 Oct 2016 14:52:50 GMT
|
||||
< Content-Type: text/plain
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
<
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.60.2
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://external-auth-01.sample.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.11 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
authorization=Basic dXNlcjpwYXNzd2Q=
|
||||
connection=close
|
||||
host=external-auth-01.sample.com
|
||||
user-agent=curl/7.50.1
|
||||
x-forwarded-for=10.2.60.1
|
||||
x-forwarded-host=external-auth-01.sample.com
|
||||
x-forwarded-port=80
|
||||
x-forwarded-proto=http
|
||||
x-real-ip=10.2.60.1
|
||||
BODY:
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
-no body in request-
|
||||
```
|
||||
|
||||
Test 3: invalid username/password (expect code 401)
|
||||
```
|
||||
curl -k http://172.17.4.99 -v -H 'Host: external-auth-01.sample.com' -u 'user:user'
|
||||
* Rebuilt URL to: http://172.17.4.99/
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
* Server auth using Basic with user 'user'
|
||||
> GET / HTTP/1.1
|
||||
> Host: external-auth-01.sample.com
|
||||
> Authorization: Basic dXNlcjp1c2Vy
|
||||
> User-Agent: curl/7.50.1
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 401 Unauthorized
|
||||
< Server: nginx/1.11.3
|
||||
< Date: Mon, 03 Oct 2016 14:53:04 GMT
|
||||
< Content-Type: text/html
|
||||
< Content-Length: 195
|
||||
< Connection: keep-alive
|
||||
* Authentication problem. Ignoring this.
|
||||
< WWW-Authenticate: Basic realm="Fake Realm"
|
||||
<
|
||||
<html>
|
||||
<head><title>401 Authorization Required</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>401 Authorization Required</h1></center>
|
||||
<hr><center>nginx/1.11.3</center>
|
||||
</body>
|
||||
</html>
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
|
@ -1,15 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
ingress.kubernetes.io/auth-url: "https://httpbin.org/basic-auth/user/passwd"
|
||||
name: external-auth
|
||||
spec:
|
||||
rules:
|
||||
- host: external-auth-01.sample.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
path: /
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
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
|
||||
volumes:
|
||||
- name: dhparam-example
|
||||
secret:
|
||||
secretName: dhparam-example
|
||||
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
|
||||
- containerPort: 8080
|
||||
hostPort: 9000
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx-ssl/dhparam
|
||||
name: dhparam-example
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-configmap-example
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -1,25 +0,0 @@
|
|||
# An Ingress with 2 hosts and 3 endpoints
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: echomap
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
||||
- host: bar.baz.com
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: echoheaders-y
|
||||
servicePort: 80
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
|
@ -1,94 +0,0 @@
|
|||
# Multi TLS certificate termination
|
||||
|
||||
This examples uses 2 different certificates to terminate SSL for 2 hostnames.
|
||||
|
||||
1. Deploy the controller by creating the rc in the parent dir
|
||||
2. Create tls secrets for foo.bar.com and bar.baz.com as indicated in the yaml
|
||||
3. Create multi-tls.yaml
|
||||
|
||||
This should generate a segment like:
|
||||
```console
|
||||
$ kubectl exec -it nginx-ingress-controller-6vwd1 -- cat /etc/nginx/nginx.conf | grep "foo.bar.com" -B 7 -A 35
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl http2;
|
||||
ssl_certificate /etc/nginx-ssl/default-foobar.pem;
|
||||
ssl_certificate_key /etc/nginx-ssl/default-foobar.pem;
|
||||
|
||||
|
||||
server_name foo.bar.com;
|
||||
|
||||
|
||||
if ($scheme = http) {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
|
||||
# Pass Real IP
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
||||
# Allow websocket connections
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $pass_access_scheme;
|
||||
|
||||
proxy_connect_timeout 5s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_pass http://default-echoheaders-80;
|
||||
}
|
||||
```
|
||||
|
||||
And you should be able to reach your nginx service or echoheaders service using a hostname switch:
|
||||
```console
|
||||
$ kubectl get ing
|
||||
NAME RULE BACKEND ADDRESS AGE
|
||||
foo-tls - 104.154.30.67 13m
|
||||
foo.bar.com
|
||||
/ echoheaders:80
|
||||
bar.baz.com
|
||||
/ nginx:80
|
||||
|
||||
$ curl https://104.154.30.67 -H 'Host:foo.bar.com' -k
|
||||
CLIENT VALUES:
|
||||
client_address=10.245.0.6
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://foo.bar.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.11 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
host=foo.bar.com
|
||||
user-agent=curl/7.35.0
|
||||
x-forwarded-for=10.245.0.1
|
||||
x-forwarded-host=foo.bar.com
|
||||
x-forwarded-proto=https
|
||||
|
||||
$ curl https://104.154.30.67 -H 'Host:bar.baz.com' -k
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to nginx on Debian!</title>
|
||||
|
||||
$ curl 104.154.30.67
|
||||
default backend - 404
|
||||
```
|
|
@ -1,102 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: gcr.io/google_containers/nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: echoheaders
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: echoheaders
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: echoheaders
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
containers:
|
||||
- name: echoheaders
|
||||
image: gcr.io/google_containers/echoserver:1.4
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: foo-tls
|
||||
namespace: default
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- foo.bar.com
|
||||
# This secret must exist beforehand
|
||||
# The cert must also contain the subj-name foo.bar.com
|
||||
# You can create it via:
|
||||
# make keys secret SECRET=/tmp/foobar.json HOST=foo.bar.com NAME=foobar
|
||||
# https://github.com/kubernetes/contrib/tree/master/ingress/controllers/gce/https_example
|
||||
secretName: foobar
|
||||
- hosts:
|
||||
- bar.baz.com
|
||||
# This secret must exist beforehand
|
||||
# The cert must also contain the subj-name bar.baz.com
|
||||
# You can create it via:
|
||||
# make keys secret SECRET=/tmp/barbaz.json HOST=bar.baz.com NAME=barbaz
|
||||
# https://github.com/kubernetes/contrib/tree/master/ingress/controllers/gce/https_example
|
||||
secretName: barbaz
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
path: /
|
||||
- host: bar.baz.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: nginx
|
||||
servicePort: 80
|
||||
path: /
|
|
@ -1,34 +0,0 @@
|
|||
# Nginx ingress controller using Proxy Protocol
|
||||
|
||||
For using the Proxy Protocol in a load balancing solution, both the load balancer and its backend need to enable Proxy Protocol.
|
||||
|
||||
To enable it for NGINX you have to setup a [configmap](nginx-configmap.yaml) option.
|
||||
|
||||
## HAProxy
|
||||
|
||||
This HAProxy snippet would forward HTTP(S) traffic to a two worker kubernetes cluster, with NGINX running on the node ports, like defined in this example's [service](nginx-svc.yaml).
|
||||
|
||||
|
||||
```
|
||||
listen kube-nginx-http
|
||||
bind :::80 v6only
|
||||
bind 0.0.0.0:80
|
||||
mode tcp
|
||||
option tcplog
|
||||
balance leastconn
|
||||
server node1 <node-ip1>:32080 check-send-proxy inter 10s send-proxy
|
||||
server node2 <node-ip2>:32080 check-send-proxy inter 10s send-proxy
|
||||
|
||||
listen kube-nginx-https
|
||||
bind :::443 v6only
|
||||
bind 0.0.0.0:443
|
||||
mode tcp
|
||||
option tcplog
|
||||
balance leastconn
|
||||
server node1 <node-ip1>:32443 check-send-proxy inter 10s send-proxy
|
||||
server node2 <node-ip2>:32443 check-send-proxy inter 10s send-proxy
|
||||
```
|
||||
|
||||
## ELBs in AWS
|
||||
|
||||
See this [documentation](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html) how to enable Proxy Protocol in ELBs
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v1
|
||||
metadata:
|
||||
name: nginx-ingress-controller
|
||||
data:
|
||||
use-proxy-protocol: "true"
|
||||
kind: ConfigMap
|
|
@ -1,50 +0,0 @@
|
|||
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
|
||||
- containerPort: 443
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --nginx-configmap=$(POD_NAMESPACE)/nginx-ingress-controller
|
|
@ -1,19 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-ingress-controller
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
nodePort: 32080
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
nodePort: 32443
|
||||
protocol: TCP
|
||||
name: https
|
||||
selector:
|
||||
k8s-app: nginx-ingress-lb
|
|
@ -1,67 +0,0 @@
|
|||
|
||||
Create an Ingress rule with a rewrite annotation:
|
||||
```
|
||||
$ echo "
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
name: rewrite
|
||||
namespace: default
|
||||
spec:
|
||||
rules:
|
||||
- host: rewrite.bar.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
path: /something
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
Check the rewrite is working
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/something -H 'Host: rewrite.bar.com'
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET /something HTTP/1.1
|
||||
> Host: rewrite.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: nginx/1.11.0
|
||||
< Date: Tue, 31 May 2016 16:07:31 GMT
|
||||
< Content-Type: text/plain
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
<
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.56.9
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://rewrite.bar.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.11 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
host=rewrite.bar.com
|
||||
user-agent=curl/7.43.0
|
||||
x-forwarded-for=10.2.56.1
|
||||
x-forwarded-host=rewrite.bar.com
|
||||
x-forwarded-port=80
|
||||
x-forwarded-proto=http
|
||||
x-real-ip=10.2.56.1
|
||||
BODY:
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
-no body in request-
|
||||
```
|
||||
|
|
@ -1,128 +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: alpine:3.4
|
||||
name: sysctl-buddy
|
||||
# using kubectl exec you can check which other parameters is possible to change
|
||||
# IPC Namespace: kernel.msgmax, kernel.msgmnb, kernel.msgmni, kernel.sem, kernel.shmall,
|
||||
# kernel.shmmax, kernel.shmmni, kernel.shm_rmid_forced and Sysctls
|
||||
# beginning with fs.mqueue.*
|
||||
# Network Namespace: Sysctls beginning with net.*
|
||||
#
|
||||
# kubectl <podname> -c sysctl-buddy -- sysctl -A | grep net
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
while true; do
|
||||
sysctl -w net.core.somaxconn=32768
|
||||
sysctl -w net.ipv4.ip_local_port_range='1024 65535'
|
||||
sleep 10
|
||||
done
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
privileged: true
|
||||
- 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 8080 to access nginx stats in url /nginx-status
|
||||
# this is optional
|
||||
- containerPort: 8080
|
||||
hostPort: 8080
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -1,74 +0,0 @@
|
|||
|
||||
To configure which services and ports will be exposed
|
||||
```
|
||||
kubectl create -f tcp-configmap-example.yaml
|
||||
```
|
||||
|
||||
The file `tcp-configmap-example.yaml` uses a ConfigMap 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.
|
||||
|
||||
```
|
||||
kubectl create -f rc-tcp.yaml
|
||||
```
|
||||
|
||||
Now we can test the new service:
|
||||
```
|
||||
$ (sleep 1; echo "GET / HTTP/1.1"; echo "Host: 172.17.4.99:9000"; echo;echo;sleep 2) | telnet 172.17.4.99 9000
|
||||
|
||||
Trying 172.17.4.99...
|
||||
Connected to 172.17.4.99.
|
||||
Escape character is '^]'.
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.7
|
||||
Date: Tue, 15 Dec 2015 14:46:28 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
|
||||
f
|
||||
CLIENT VALUES:
|
||||
|
||||
1a
|
||||
client_address=10.2.84.45
|
||||
|
||||
c
|
||||
command=GET
|
||||
|
||||
c
|
||||
real path=/
|
||||
|
||||
a
|
||||
query=nil
|
||||
|
||||
14
|
||||
request_version=1.1
|
||||
|
||||
25
|
||||
request_uri=http://172.17.4.99:8080/
|
||||
|
||||
1
|
||||
|
||||
|
||||
f
|
||||
SERVER VALUES:
|
||||
|
||||
28
|
||||
server_version=nginx: 1.9.7 - lua: 9019
|
||||
|
||||
1
|
||||
|
||||
|
||||
12
|
||||
HEADERS RECEIVED:
|
||||
|
||||
16
|
||||
host=172.17.4.99:9000
|
||||
|
||||
6
|
||||
BODY:
|
||||
|
||||
14
|
||||
-no body in request-
|
||||
0
|
||||
```
|
|
@ -1,56 +0,0 @@
|
|||
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
|
||||
# service echoheaders as TCP service default/echoheaders:9000
|
||||
# 9000 indicates the port used to expose the service
|
||||
- containerPort: 9000
|
||||
hostPort: 9000
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-configmap-example
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tcp-configmap-example
|
||||
data:
|
||||
9000: "default/example-go:8080"
|
|
@ -1,90 +0,0 @@
|
|||
This is an example to use a TLS Ingress rule to use SSL in NGINX
|
||||
|
||||
# TLS certificate termination
|
||||
|
||||
This examples uses 2 different certificates to terminate SSL for 2 hostnames.
|
||||
|
||||
1. Deploy the controller by creating the rc in the parent dir
|
||||
2. Create tls secret for foo.bar.com
|
||||
3. Create rc-ssl.yaml
|
||||
|
||||
*Next create a SSL certificate for `foo.bar.com` host:*
|
||||
|
||||
```
|
||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com"
|
||||
```
|
||||
|
||||
*Now store the SSL certificate in a secret:*
|
||||
|
||||
```
|
||||
echo "
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: foo-secret
|
||||
data:
|
||||
tls.crt: `base64 /tmp/tls.crt`
|
||||
tls.key: `base64 /tmp/tls.key`
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
*Finally create a tls Ingress rule:*
|
||||
|
||||
```
|
||||
echo "
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: default
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- foo.bar.com
|
||||
secretName: foo-secret
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
||||
path: /
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
You should be able to reach your nginx service or echoheaders service using a hostname:
|
||||
```
|
||||
$ kubectl get ing
|
||||
NAME RULE BACKEND ADDRESS
|
||||
foo - 10.4.0.3
|
||||
foo.bar.com
|
||||
/ echoheaders-x:80
|
||||
```
|
||||
|
||||
```
|
||||
$ curl https://10.4.0.3 -H 'Host:foo.bar.com' -k
|
||||
old-mbp:contrib aledbf$ curl https://10.4.0.3 -H 'Host:foo.bar.com' -k
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.48.4
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://foo.bar.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.7 - lua: 9019
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
host=foo.bar.com
|
||||
user-agent=curl/7.43.0
|
||||
x-forwarded-for=10.2.48.1
|
||||
x-forwarded-host=foo.bar.com
|
||||
x-forwarded-proto=https
|
||||
x-real-ip=10.2.48.1
|
||||
BODY:
|
||||
-no body in request-
|
||||
```
|
|
@ -1,35 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# https://www.openssl.org/docs/manmaster/apps/dhparam.html
|
||||
# this command generates a key used to get "Perfect Forward Secrecy" in nginx
|
||||
# https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_handshake_and_dhparam
|
||||
openssl dhparam -out dhparam.pem 4096
|
||||
|
||||
cat <<EOF > dhparam-example.yaml
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "dhparam-example"
|
||||
},
|
||||
"data": {
|
||||
"dhparam.pem": "$(cat ./dhparam.pem | base64)"
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
|
@ -1,51 +0,0 @@
|
|||
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
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
To configure which services and ports will be exposed
|
||||
```
|
||||
kubectl create -f udp-configmap-example.yaml
|
||||
```
|
||||
|
||||
The file `udp-configmap-example.yaml` uses a ConfigMap 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.
|
||||
|
||||
```
|
||||
kubectl create -f rc-udp.yaml
|
||||
```
|
|
@ -1,54 +0,0 @@
|
|||
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
|
||||
- containerPort: 53
|
||||
hostPort: 53
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-configmap-example
|
|
@ -1,6 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: udp-configmap-example
|
||||
data:
|
||||
53: "kube-system/kube-dns:53"
|
|
@ -1,123 +0,0 @@
|
|||
|
||||
This example shows how is possible to restrict access
|
||||
|
||||
```
|
||||
echo "
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: whitelist
|
||||
annotations:
|
||||
ingress.kubernetes.io/whitelist-source-range: "1.1.1.1/24"
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
" | kubectl create -f -
|
||||
```
|
||||
|
||||
Check the annotation is present in the Ingress rule:
|
||||
```
|
||||
$ kubectl get ingress whitelist -o yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
ingress.kubernetes.io/whitelist-source-range: 1.1.1.1/24
|
||||
creationTimestamp: 2016-06-09T21:39:06Z
|
||||
generation: 2
|
||||
name: whitelist
|
||||
namespace: default
|
||||
resourceVersion: "419363"
|
||||
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/whitelist
|
||||
uid: 97b74737-2e8a-11e6-90db-080027d2dc94
|
||||
spec:
|
||||
rules:
|
||||
- host: whitelist.bar.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders
|
||||
servicePort: 80
|
||||
path: /
|
||||
status:
|
||||
loadBalancer:
|
||||
ingress:
|
||||
- ip: 172.17.4.99
|
||||
```
|
||||
|
||||
Finally test is not possible to access the URL
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/ -H 'Host: whitelist.bar.com'
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: whitelist.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 403 Forbidden
|
||||
< Server: nginx/1.11.1
|
||||
< Date: Thu, 09 Jun 2016 21:56:17 GMT
|
||||
< Content-Type: text/html
|
||||
< Content-Length: 169
|
||||
< Connection: keep-alive
|
||||
<
|
||||
<html>
|
||||
<head><title>403 Forbidden</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>403 Forbidden</h1></center>
|
||||
<hr><center>nginx/1.11.1</center>
|
||||
</body>
|
||||
</html>
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
Removing the annotation removes the restriction
|
||||
|
||||
```
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: whitelist.bar.com
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Server: nginx/1.11.1
|
||||
< Date: Thu, 09 Jun 2016 21:57:44 GMT
|
||||
< Content-Type: text/plain
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
<
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.89.7
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://whitelist.bar.com:8080/
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.9.11 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
host=whitelist.bar.com
|
||||
user-agent=curl/7.43.0
|
||||
x-forwarded-for=10.2.89.1
|
||||
x-forwarded-host=whitelist.bar.com
|
||||
x-forwarded-port=80
|
||||
x-forwarded-proto=http
|
||||
x-real-ip=10.2.89.1
|
||||
BODY:
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
Loading…
Reference in a new issue