Merge pull request #240 from jcmoraisjr/jm-docs-haproxy

HAProxy Ingress docs
This commit is contained in:
Prashanth B 2017-02-08 06:00:54 +05:30 committed by GitHub
commit 1eaea7576c
7 changed files with 347 additions and 2 deletions

View file

@ -3,5 +3,4 @@
This is a non-comprehensive list of existing ingress controllers.
* [Dummy controller backend](/examples/custom-controller)
* [HAProxy Ingress controller](https://github.com/jcmoraisjr/haproxy-ingress)

View file

@ -81,6 +81,14 @@ You may want to consider [using the VM's docker
daemon](https://github.com/kubernetes/minikube/blob/master/README.md#reusing-the-docker-daemon)
when developing.
### CoreOS Kubernetes
[CoreOS Kubernetes](https://github.com/coreos/coreos-kubernetes/) repository has `Vagrantfile`
scripts to easily create a new Kubernetes cluster on VirtualBox, VMware or AWS.
Follow the CoreOS [doc](https://coreos.com/kubernetes/docs/latest/kubernetes-on-vagrant-single.html)
for detailed instructions.
## Deploy the ingress controller
You can deploy an ingress controller on the cluster setup in the previous step

View file

@ -0,0 +1,151 @@
# Deploying HAProxy Ingress Controller
If you don't have a Kubernetes cluster, please refer to [setup](/docs/dev/setup.md)
for instructions on how to create a new one.
## Prerequisites
This ingress controller doesn't yet have support for
[ingress classes](/examples/PREREQUISITES.md#ingress-class). You MUST turn
down any existing ingress controllers before running HAProxy Ingress controller or
they will fight for Ingresses. This includes any cloudprovider controller.
This document has also the following prerequisites:
* Deploy a [web app](/examples/PREREQUISITES.md#test-http-service) for testing
* Create a [TLS secret](/examples/PREREQUISITES.md#tls-certificates) named `tls-secret` to be used as default TLS certificate
The web app can be created as follow:
```console
$ kubectl run http-svc \
--image=gcr.io/google_containers/echoserver:1.3 \
--port=8080 \
--replicas=2 \
--expose
```
Creating the TLS secret:
```console
$ openssl req \
-x509 -newkey rsa:2048 -nodes -days 365 \
-keyout tls.key -out tls.crt -subj '/CN=localhost'
$ kubectl create secret tls tls-secret --cert=tls.crt --key=tls.key
$ rm -v tls.crt tls.key
```
## Default backend
Deploy a default backend used to serve `404 Not Found` pages:
```console
$ kubectl run ingress-default-backend \
--image=gcr.io/google_containers/defaultbackend:1.0 \
--port=8080 \
--limits=cpu=10m,memory=20Mi \
--expose
```
Check if the default backend is up and running:
```console
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
ingress-default-backend-1110790216-gqr61 1/1 Running 0 10s
```
## Controller
Deploy HAProxy Ingress:
```console
$ kubectl create -f haproxy-ingress.yaml
```
Check if the controller was successfully deployed:
```console
$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
haproxy-ingress-2556761959-tv20k 1/1 Running 0 12s
ingress-default-backend-1110790216-gqr61 1/1 Running 0 3m
^C
```
Deploy the ingress resource of our already deployed web app:
```console
$ kubectl create -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app
spec:
rules:
- host: foo.bar
http:
paths:
- path: /
backend:
serviceName: http-svc
servicePort: 80
EOF
```
Exposing the controller as a `type=NodePort` service:
```console
$ kubectl expose deploy/haproxy-ingress --type=NodePort
$ kubectl get svc/haproxy-ingress -oyaml
```
Look for `nodePort` field next to `port: 80`.
Change below `172.17.4.99` to the host's IP and `30876` to the `nodePort`:
```console
$ curl -i 172.17.4.99:30876
HTTP/1.1 404 Not Found
Date: Mon, 05 Feb 2017 22:59:36 GMT
Content-Length: 21
Content-Type: text/plain; charset=utf-8
default backend - 404
```
Using default backend because host was not found.
Now try to send a header:
```console
$ curl -i 172.17.4.99:30876 -H 'Host: foo.bar'
HTTP/1.1 200 OK
Server: nginx/1.9.11
Date: Mon, 05 Feb 2017 23:00:33 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
CLIENT VALUES:
client_address=10.2.18.5
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://foo.bar:8080/
...
```
## Troubleshooting
If you have any problem, check logs and events of HAProxy Ingress POD:
```console
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
haproxy-ingress-2556761959-tv20k 1/1 Running 0 9m
...
$ kubectl logs haproxy-ingress-2556761959-tv20k
$ kubectl describe haproxy-ingress-2556761959-tv20k
```

View file

@ -0,0 +1,38 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: haproxy-ingress
name: haproxy-ingress
spec:
replicas: 1
selector:
matchLabels:
run: haproxy-ingress
template:
metadata:
labels:
run: haproxy-ingress
spec:
containers:
- name: haproxy-ingress
image: quay.io/jcmoraisjr/haproxy-ingress
args:
- --default-backend-service=default/ingress-default-backend
- --default-ssl-certificate=default/tls-secret
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: stat
containerPort: 1936
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace

View file

@ -0,0 +1,116 @@
# TLS termination
## Prerequisites
This document has the following prerequisites:
* Deploy [HAProxy Ingress controller](/examples/deployment/haproxy), you should end up with controller, a sample web app and default TLS secret
* Create [*another* secret](/examples/PREREQUISITES.md#tls-certificates) named `foobar-ssl` and subject `'/CN=foo.bar'`
As mentioned in the deployment instructions, you MUST turn down any existing
ingress controllers before running HAProxy Ingress.
## Using default TLS certificate
Update ingress resource in order to add TLS termination to host `foo.bar`:
```console
$ kubectl replace -f ingress-tls-default.yaml
```
The difference from the starting ingress resource:
```console
metadata:
name: app
spec:
+ tls:
+ - hosts:
+ - foo.bar
rules:
- host: foo.bar
http:
```
Trying default backend:
```console
$ curl -iL 172.17.4.99:30876
HTTP/1.1 404 Not Found
Date: Tue, 07 Feb 2017 00:06:07 GMT
Content-Length: 21
Content-Type: text/plain; charset=utf-8
default backend - 404
```
Now telling the controller we are `foo.bar`:
```console
$ curl -iL 172.17.4.99:30876 -H 'Host: foo.bar'
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: https://foo.bar/
Connection: close
^C
```
Note the `Location` header - this would redirect us to the correct server.
Checking the default certificate - change below `31692` to the TLS port:
```console
$ openssl s_client -connect 172.17.4.99:31692
...
subject=/CN=localhost
issuer=/CN=localhost
---
```
... and `foo.bar` certificate:
```console
$ openssl s_client -connect 172.17.4.99:31692 -servername foo.bar
...
subject=/CN=localhost
issuer=/CN=localhost
---
```
## Using a new TLS certificate
Now let's reference the new certificate to our domain. Note that secret
`foobar-ssl` should be created as described in the [prerequisites](#prerequisites)
```console
$ kubectl replace -f ingress-tls-foobar.yaml
```
Here is the difference:
```console
tls:
- hosts:
- foo.bar
+ secretName: foobar-ssl
rules:
- host: foo.bar
http:
```
Now `foo.bar` certificate should be used to terminate TLS:
```console
openssl s_client -connect 172.17.4.99:31692
...
subject=/CN=localhost
issuer=/CN=localhost
---
openssl s_client -connect 172.17.4.99:31692 -servername foo.bar
...
subject=/CN=foo.bar
issuer=/CN=foo.bar
---
```

View file

@ -0,0 +1,16 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app
spec:
tls:
- hosts:
- foo.bar
rules:
- host: foo.bar
http:
paths:
- path: /
backend:
serviceName: http-svc
servicePort: 80

View file

@ -0,0 +1,17 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app
spec:
tls:
- hosts:
- foo.bar
secretName: foobar-ssl
rules:
- host: foo.bar
http:
paths:
- path: /
backend:
serviceName: http-svc
servicePort: 80