Cleanup examples directory
|
|
@ -6,91 +6,89 @@ trying them.
|
|||
|
||||
## Basic cross platform
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Deployment | basic deployment of controllers | * | Beginner
|
||||
TLS termination | terminate TLS at the ingress controller | * | Beginner
|
||||
Name based virtual hosting | `Host` header routing | * | Beginner
|
||||
Path routing | URL regex routing | * | Beginner
|
||||
Health checking | configure/optimize health checks | * | Intermediate
|
||||
Pipeline | pipeline cloud and nginx | * | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Deployment | basic deployment of controllers | Beginner
|
||||
TLS termination | terminate TLS at the ingress controller | Beginner
|
||||
Name based virtual hosting | `Host` header routing | Beginner
|
||||
Path routing | URL regex routing | Beginner
|
||||
Health checking | configure/optimize health checks | Intermediate
|
||||
Pipeline | pipeline cloud and nginx | Advanced
|
||||
|
||||
## AWS
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
AWS | basic deployment | nginx | Intermediate
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
AWS | basic deployment | Intermediate
|
||||
|
||||
|
||||
## TLS
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
LetsEncrypt | acquire certs via ACME protocol | * | Intermediate
|
||||
Intermediate certs | terminate TLS with intermediate certs | * | Advanced
|
||||
Client certs | client cert authentication | nginx | Advanced
|
||||
Re-encrypty | terminate, apply routing rules, re-encrypt | nginx | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
LetsEncrypt | acquire certs via ACME protocol | Intermediate
|
||||
Intermediate certs | terminate TLS with intermediate certs | Advanced
|
||||
Client certs | client cert authentication | Advanced
|
||||
Re-encrypty | terminate, apply routing rules, re-encrypt | Advanced
|
||||
|
||||
## Scaling
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Daemonset | run multiple controllers in a daemonset | nginx/haproxy | Intermediate
|
||||
Deployment | run multiple controllers as a deployment | nginx/haproxy | Intermediate
|
||||
Multi-zone | bridge different zones in a single cluster | gce | Intermediate
|
||||
Static-ip | a single ingress gets a single static ip | * | Intermediate
|
||||
Geo-routing | route to geographically closest endpoint | nginx | Advanced
|
||||
Multi-cluster | bridge Kubernetes clusters with Ingress | gce | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Daemonset | run multiple controllers in a daemonset | Intermediate
|
||||
Deployment | run multiple controllers as a deployment | Intermediate
|
||||
Static-ip | a single ingress gets a single static ip | Intermediate
|
||||
Geo-routing | route to geographically closest endpoint | Advanced
|
||||
|
||||
## Algorithms
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Session stickyness | route requests consistently to the same endpoint | nginx | Advanced
|
||||
Least connections | route requests based on least connections | on-prem | Advanced
|
||||
Weights | route requests to backends based on weights | nginx | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Session stickyness | route requests consistently to the same endpoint | Advanced
|
||||
Least connections | route requests based on least connections | Advanced
|
||||
Weights | route requests to backends based on weights | Advanced
|
||||
|
||||
## Routing
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Redirects | send a 301 re-direct | nginx | Intermediate
|
||||
URL-rewriting | re-write path | nginx | Intermediate
|
||||
SNI + HTTP | HTTP routing based on SNI hostname | nginx | Advanced
|
||||
SNI + TCP | TLS routing based on SNI hostname | nginx | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Redirects | send a 301 re-direct | Intermediate
|
||||
URL-rewriting | re-write path | Intermediate
|
||||
SNI + HTTP | HTTP routing based on SNI hostname | Advanced
|
||||
SNI + TCP | TLS routing based on SNI hostname | Advanced
|
||||
|
||||
## Auth
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Basic auth | password protect your website | nginx | Intermediate
|
||||
[External auth plugin](external-auth/nginx/README.md) | defer to an external auth service | nginx | Intermediate
|
||||
[External auth plugin](external-auth/README.md) | defer to an external auth service | Intermediate
|
||||
|
||||
## Protocols
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
TCP | TCP loadbalancing | nginx | Intermediate
|
||||
UDP | UDP loadbalancing | nginx | Intermediate
|
||||
Websockets | websockets loadbalancing | nginx | Intermediate
|
||||
HTTP/2 | HTTP/2 loadbalancing | * | Intermediate
|
||||
Proxy protocol | leverage the proxy protocol for source IP | nginx | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
TCP | TCP loadbalancing | Intermediate
|
||||
UDP | UDP loadbalancing | Intermediate
|
||||
Websockets | websockets loadbalancing | Intermediate
|
||||
HTTP/2 | HTTP/2 loadbalancing | Intermediate
|
||||
Proxy protocol | leverage the proxy protocol for source IP | Advanced
|
||||
|
||||
## Custom controllers
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
Dummy | A simple dummy controller that logs updates | * | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
Dummy | A simple dummy controller that logs updates | Advanced
|
||||
|
||||
## Customization
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
custom-headers | set custom headers before send traffic to backends | nginx | Advanced
|
||||
configuration-snippets | customize nginx location configuration using annotations | nginx | Advanced
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
custom-headers | set custom headers before send traffic to backends | Advanced
|
||||
configuration-snippets | customize nginx location configuration using annotations | Advanced
|
||||
|
||||
## RBAC
|
||||
|
||||
Name | Description | Platform | Complexity Level
|
||||
-----| ----------- | ---------- | ----------------
|
||||
rbac | Configuring Role Base Access Control | nginx | intermediate
|
||||
Name | Description | Complexity Level
|
||||
-----| ----------- | ----------------
|
||||
rbac | Configuring Role Base Access Control | intermediate
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
# HAProxy Ingress Basic Authentication
|
||||
|
||||
This example demonstrates how to configure
|
||||
[Basic Authentication](https://tools.ietf.org/html/rfc2617) on
|
||||
HAProxy Ingress controller.
|
||||
|
||||
## 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 an ingress resource to the `foo.bar`
|
||||
domain
|
||||
|
||||
## Using Basic Authentication
|
||||
|
||||
HAProxy Ingress read user and password from `auth` file stored on secrets, one user
|
||||
and password per line. Secret name, realm and type are configured with annotations
|
||||
in the ingress resource:
|
||||
|
||||
* `ingress.kubernetes.io/auth-type`: the only supported type is `basic`
|
||||
* `ingress.kubernetes.io/auth-realm`: an optional string with authentication realm
|
||||
* `ingress.kubernetes.io/auth-secret`: name of the secret
|
||||
|
||||
Each line of the `auth` file should have:
|
||||
|
||||
* user and insecure password separated with a pair of colons: `<username>::<plain-text-passwd>`; or
|
||||
* user and an encrypted password separated with colons: `<username>:<encrypted-passwd>`
|
||||
|
||||
HAProxy evaluates encrypted passwords with
|
||||
[crypt](http://man7.org/linux/man-pages/man3/crypt.3.html) function. Use `mkpasswd` or
|
||||
`makepasswd` to create it. `mkpasswd` can be found on Alpine Linux container.
|
||||
|
||||
## Configure
|
||||
|
||||
Create a secret to our users:
|
||||
|
||||
* `john` and password `admin` using insecure plain text password
|
||||
* `jane` and password `guest` using encrypted password
|
||||
|
||||
```console
|
||||
$ mkpasswd -m des ## a short, des encryption, syntax from Busybox on Alpine Linux
|
||||
Password: (type 'guest' and press Enter)
|
||||
E5BrlrQ5IXYK2
|
||||
|
||||
$ cat >auth <<EOF
|
||||
john::admin
|
||||
jane:E5BrlrQ5IXYK2
|
||||
EOF
|
||||
|
||||
$ kubectl create secret generic mypasswd --from-file auth
|
||||
$ rm -fv auth
|
||||
```
|
||||
|
||||
Annotate the ingress resource created on a [previous step](/examples/deployment/haproxy):
|
||||
|
||||
```console
|
||||
$ kubectl annotate ingress/app \
|
||||
ingress.kubernetes.io/auth-type=basic \
|
||||
ingress.kubernetes.io/auth-realm="My Server" \
|
||||
ingress.kubernetes.io/auth-secret=mypasswd
|
||||
```
|
||||
|
||||
Test without user and password:
|
||||
|
||||
```console
|
||||
$ curl -i 172.17.4.99:30876 -H 'Host: foo.bar'
|
||||
HTTP/1.0 401 Unauthorized
|
||||
Cache-Control: no-cache
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
WWW-Authenticate: Basic realm="My Server"
|
||||
|
||||
<html><body><h1>401 Unauthorized</h1>
|
||||
You need a valid user and password to access this content.
|
||||
</body></html>
|
||||
```
|
||||
|
||||
Send a valid user:
|
||||
|
||||
```console
|
||||
$ curl -i -u 'john:admin' 172.17.4.99:30876 -H 'Host: foo.bar'
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Sun, 05 Mar 2017 19:22: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/
|
||||
```
|
||||
|
||||
Using `jane:guest` user/passwd should have the same output.
|
||||
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
# HAProxy Ingress Client Certificate Authentication
|
||||
|
||||
This example demonstrates how to configure client certificate
|
||||
authentication on HAProxy Ingress controller.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This document has the following prerequisites:
|
||||
|
||||
* Deploy [HAProxy Ingress](/examples/deployment/haproxy) controller, you should
|
||||
end up with controller, a sample web app and an ingress resource named `app` to
|
||||
the `foo.bar` domain
|
||||
* Configure [TLS termination](/examples/tls-termination/haproxy)
|
||||
* Create a [CA, certificate and private key](/examples/PREREQUISITES.md#ca-authentication),
|
||||
following these steps you should have a secret named `caingress`, a certificate file
|
||||
`client.crt` and it's private key `client.key`
|
||||
* Use these same steps and create another CA and generate another certificate and private
|
||||
key `fake.crt` and `fake.key` just for testing
|
||||
|
||||
Secret, certificates and keys can be created using these shortcuts:
|
||||
|
||||
CA and it's secret:
|
||||
|
||||
```console
|
||||
$ openssl req -x509 -newkey rsa:2048 -nodes -subj '/CN=example-ca' -keyout ca.key -out ca.crt
|
||||
$ kubectl create secret generic caingress --from-file=ca.crt
|
||||
```
|
||||
|
||||
Valid certificate and private key:
|
||||
|
||||
```console
|
||||
$ openssl req -new -newkey rsa:2048 -nodes -subj '/CN=client' -keyout client.key | \
|
||||
openssl x509 -req -CA ca.crt -CAkey ca.key -set_serial 1 -out client.crt
|
||||
```
|
||||
|
||||
Another CA, certificate and private key that should be refused by ingress:
|
||||
|
||||
```console
|
||||
$ openssl req -x509 -newkey rsa:2048 -nodes -subj '/CN=example-ca' -keyout ca-fake.key -out ca-fake.crt
|
||||
$ openssl req -new -newkey rsa:2048 -nodes -subj '/CN=client' -keyout fake.key | \
|
||||
openssl x509 -req -CA ca-fake.crt -CAkey ca-fake.key -set_serial 1 -out fake.crt
|
||||
```
|
||||
|
||||
## Using Client Certificate Authentication
|
||||
|
||||
HAProxy Ingress read one or a bundle of certificate authorities from a secret.
|
||||
Only client certificates signed by one of these certificate authorities should be
|
||||
allowed to make requests.
|
||||
|
||||
Annotate the ingress resource to use our valid certificate authority. The ingress resource and the
|
||||
secret `caingress` were created on the prerequisites.
|
||||
|
||||
```console
|
||||
$ kubectl annotate ingress/app ingress.kubernetes.io/auth-tls-secret=default/caingress
|
||||
```
|
||||
|
||||
Make some SSL requests against domain `foo.bar`. Change `31692:172.17.4.99` below to the IP and
|
||||
port of HAProxy Ingress controller.
|
||||
|
||||
Note: `curl`'s `--cert` and `-k` options on macOS (since 10.9 Mavericks) doesn't work as
|
||||
expected, see troubleshooting below if using macOS.
|
||||
|
||||
Connect without a certificate:
|
||||
|
||||
```console
|
||||
$ curl -ik https://foo.bar:31692 --resolve 'foo.bar:31692:172.17.4.99'
|
||||
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
|
||||
```
|
||||
|
||||
Connect using the correct certificate and private key:
|
||||
|
||||
```console
|
||||
$ curl -ik https://foo.bar:31692 --resolve 'foo.bar:31692:172.17.4.99' --cert client.crt --key client.key
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Fri, 26 Mar 2017 13:41:26 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Strict-Transport-Security: max-age=15768000
|
||||
|
||||
CLIENT VALUES:
|
||||
...
|
||||
```
|
||||
|
||||
Now connect using a private key and certificate signed by another CA:
|
||||
|
||||
```console
|
||||
$ curl -ik https://foo.bar:31692 --resolve 'foo.bar:31692:172.17.4.99' --cert fake.crt --key fake.key
|
||||
curl: (35) error:1409441B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
`curl` on macOS since 10.9 Mavericks has some issues regarding certificate on command line
|
||||
parameters:
|
||||
|
||||
* [sni](https://en.wikipedia.org/wiki/Server_Name_Indication) TLS extension isn't used
|
||||
if `-k` (unsecure connection) is provided. The sni extension is used by HAProxy to identify
|
||||
the host of the request. Without sni, the default backend will be used. The TLS
|
||||
certificate should be added to Keychain instead and `-k` should be avoided.
|
||||
|
||||
* `--cert` option is broken.
|
||||
|
||||
These issues and it's workarounds are described on
|
||||
[this message](https://curl.haxx.se/mail/archive-2013-10/0036.html) from curl mailing list.
|
||||
In short, in order to test client auth use a Linux VM or the options below on macOS.
|
||||
|
||||
### Using wget
|
||||
|
||||
Add `foo.bar` to `/etc/hosts` and change `31692` below to the
|
||||
port of HAProxy Ingress controller:
|
||||
|
||||
```console
|
||||
$ wget https://foo.bar:31692 -S -nv -O- --no-check-certificate
|
||||
OpenSSL: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
|
||||
Unable to establish SSL connection.
|
||||
```
|
||||
|
||||
Now with certificate and private key:
|
||||
|
||||
```console
|
||||
$ wget https://foo.bar:31692 -S -nv -O- --no-check-certificate --certificate client.crt --private-key client.key
|
||||
WARNING: cannot verify foo.bar's certificate, issued by ‘/CN=foo.bar’:
|
||||
Self-signed certificate encountered.
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Sun, 26 Mar 2017 13:57:53 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Strict-Transport-Security: max-age=15768000
|
||||
CLIENT VALUES:
|
||||
```
|
||||
|
||||
### Using openssl
|
||||
|
||||
Change `31692` below to the port of HAProxy Ingress controller:
|
||||
|
||||
```console
|
||||
$ openssl s_client -connect 172.17.4.99:31692 -servername foo.bar
|
||||
CONNECTED(00000003)
|
||||
depth=0 /CN=foo.bar
|
||||
verify error:num=18:self signed certificate
|
||||
verify return:1
|
||||
depth=0 /CN=foo.bar
|
||||
verify return:1
|
||||
91929:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/ssl/s3_pkt.c:1145:SSL alert number 40
|
||||
91929:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/ssl/s23_lib.c:185:
|
||||
```
|
||||
|
||||
Now with certificate and private key - copy these two lines to the clipboard
|
||||
(HAProxy will timeout after 5 seconds waiting a http request):
|
||||
|
||||
```
|
||||
GET / HTTP/1.0
|
||||
Host: foo.bar
|
||||
```
|
||||
|
||||
Type the command below, paste the http request (two lines above) and send a blank line
|
||||
pressing enter twice:
|
||||
|
||||
```console
|
||||
$ openssl s_client -connect 172.17.4.99:31692 -servername foo.bar -cert client.crt -key client.key
|
||||
...
|
||||
---
|
||||
GET / HTTP/1.0
|
||||
Host: foo.bar
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Sun, 26 Mar 2017 14:06:30 GMT
|
||||
Content-Type: text/plain
|
||||
Content-Length: 268
|
||||
Connection: close
|
||||
Strict-Transport-Security: max-age=15768000
|
||||
|
||||
CLIENT VALUES:
|
||||
...
|
||||
```
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
# TLS authentication
|
||||
|
||||
This example demonstrates how to enable the TLS Authentication through the nginx Ingress controller.
|
||||
|
||||
## Terminology
|
||||
|
||||
* CA: Certificate authority signing the client cert, in this example we will play the role of a CA.
|
||||
You can generate a CA cert as shown in this doc.
|
||||
|
||||
* CA Certificate(s) - Certificate Authority public key. Client certs must chain back to this cert,
|
||||
meaning the Issuer field of some certificate in the chain leading up to the client cert must contain
|
||||
the name of this CA. For purposes of this example, this is a self signed certificate.
|
||||
|
||||
* CA chains: A chain of certificates where the parent has a Subject field matching the Issuer field of
|
||||
the child, except for the root, which has Issuer == Subject.
|
||||
|
||||
* Client Cert: Certificate used by the clients to authenticate themselves with the loadbalancer/backends.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You need a valid CA File, composed of a group of valid enabled CAs. This MUST be in PEM Format.
|
||||
The instructions are described [here](../../../PREREQUISITES.md)
|
||||
|
||||
Also your ingress must be configured as a HTTPS/TLS Ingress.
|
||||
|
||||
## Deployment
|
||||
|
||||
Certificate Authentication is achieved through 2 annotations on the Ingress, as shown in the [example](nginx-tls-auth.yaml).
|
||||
|
||||
|Name|Description|Values|
|
||||
| --- | --- | --- |
|
||||
|ingress.kubernetes.io/auth-tls-secret|Sets the secret that contains the authorized CA Chain|string|
|
||||
|ingress.kubernetes.io/auth-tls-verify-depth|The verification depth Certificate Authentication will make|number (default to 1)|
|
||||
|ingress.kubernetes.io/auth-tls-verify-client|Enables verification of client certificates|string (default to on)|
|
||||
|ingress.kubernetes.io/auth-tls-error-page|The page that user should be redirected in case of Auth error|string (default to empty|
|
||||
|
||||
The following command instructs the controller to enable TLS authentication using the secret from the ``ingress.kubernetes.io/auth-tls-secret``
|
||||
annotation on the Ingress. Clients must present this cert to the loadbalancer, or they will receive a HTTP 400 response
|
||||
|
||||
```console
|
||||
$ kubectl create -f nginx-tls-auth.yaml
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
You can confirm that the Ingress works.
|
||||
|
||||
```console
|
||||
$ kubectl describe ing nginx-test
|
||||
Name: nginx-test
|
||||
Namespace: default
|
||||
Address: 104.198.183.6
|
||||
Default backend: default-http-backend:80 (10.180.0.4:8080,10.240.0.2:8080)
|
||||
TLS: tls-secret terminates ingress.test.com
|
||||
Rules:
|
||||
Host Path Backends
|
||||
---- ---- --------
|
||||
*
|
||||
http-svc:80 (<none>)
|
||||
Annotations:
|
||||
auth-tls-secret: default/caingress
|
||||
auth-tls-verify-depth: 3
|
||||
auth-tls-error-page: http://www.mysite.com/error-cert.html
|
||||
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
7s 7s 1 {nginx-ingress-controller } Normal CREATE default/nginx-test
|
||||
7s 7s 1 {nginx-ingress-controller } Normal UPDATE default/nginx-test
|
||||
7s 7s 1 {nginx-ingress-controller } Normal CREATE ip: 104.198.183.6
|
||||
7s 7s 1 {nginx-ingress-controller } Warning MAPPING Ingress rule 'default/nginx-test' contains no path definition. Assuming /
|
||||
|
||||
|
||||
$ curl -k https://ingress.test.com
|
||||
HTTP/1.1 400 Bad Request
|
||||
Server: nginx/1.11.9
|
||||
|
||||
$ curl -I -k --key ~/user.key --cert ~/user.cer https://ingress.test.com
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.11.9
|
||||
```
|
||||
|
||||
You must use the full DNS name while testing, as NGINX relies on the Server Name (SNI) to select the correct Ingress to be used.
|
||||
The curl version used here was ``curl 7.47.0``
|
||||
|
||||
## Which certificate was used for authentication?
|
||||
|
||||
In your backend application you might want to know which certificate was used for authentication.
|
||||
For this purpose, we pass the full certificate in PEM format to the backend in the `ssl-client-cert` header.
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Customize the HAProxy configuration
|
||||
|
||||
This example uses a [ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) to customize the HAProxy configuration.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This document has the following prerequisites:
|
||||
|
||||
Deploy only the tls-secret and the default backend from the [deployment instructions](/examples/deployment/haproxy)
|
||||
|
||||
## Customize the HAProxy configuration
|
||||
|
||||
Using a [ConfigMap](https://kubernetes.io/docs/user-guide/configmap/) is possible to customize the HAProxy configuration.
|
||||
|
||||
For example, if we want to change the syslog-endpoint we need to create a ConfigMap:
|
||||
|
||||
```
|
||||
$ kubectl create configmap haproxy-ingress --from-literal=syslog-endpoint=172.17.8.101
|
||||
```
|
||||
|
||||
Create the HAProxy Ingress deployment:
|
||||
|
||||
```
|
||||
$ kubectl create -f haproxy-custom-configuration.yaml
|
||||
```
|
||||
|
||||
The only difference from the deployment instructions is the --configmap parameter:
|
||||
|
||||
```
|
||||
- --configmap=default/haproxy-conf
|
||||
```
|
||||
|
||||
If the Configmap it is updated, HAProxy will be reloaded with the new configuration.
|
||||
|
||||
Check all the config options in the [HAProxy Ingress docs](https://github.com/jcmoraisjr/haproxy-ingress#configmap)
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
run: haproxy-ingress
|
||||
name: haproxy-ingress
|
||||
spec:
|
||||
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=$(POD_NAMESPACE)/ingress-default-backend
|
||||
- --default-ssl-certificate=$(POD_NAMESPACE)/tls-secret
|
||||
- --configmap=$(POD_NAMESPACE)/haproxy-ingress
|
||||
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
|
||||
|
Before Width: | Height: | Size: 969 KiB After Width: | Height: | Size: 969 KiB |
|
Before Width: | Height: | Size: 451 KiB After Width: | Height: | Size: 451 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
|
|
@ -1,67 +0,0 @@
|
|||
# Haproxy Ingress DaemonSet
|
||||
|
||||
In some cases, the Ingress controller will be required to be run at all the nodes in cluster. Using [DaemonSet](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/apps/daemon.md) can achieve this requirement.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
If you have another Ingress controller deployed, you will need to make sure your
|
||||
Ingress resources target exactly one Ingress controller by specifying the
|
||||
[ingress.class](/examples/PREREQUISITES.md#ingress-class) annotation as
|
||||
`haproxy`.
|
||||
|
||||
This document has also the following prerequisites:
|
||||
|
||||
* Create a [TLS secret](/examples/PREREQUISITES.md#tls-certificates) named `tls-secret` to be used as default TLS certificate
|
||||
|
||||
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
|
||||
|
||||
The default backend is a service of handling all url paths and hosts the haproxy controller doesn't understand. Deploy the default-http-backend as follow:
|
||||
|
||||
```console
|
||||
$ kubectl apply -f ../../deployment/nginx/default-backend.yaml
|
||||
deployment "default-http-backend" configured
|
||||
service "default-http-backend" configured
|
||||
|
||||
$ kubectl -n kube-system get svc
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
default-http-backend 192.168.3.4 <none> 80/TCP 30m
|
||||
|
||||
$ kubectl -n kube-system get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
default-http-backend-q5sb6 1/1 Running 0 30m
|
||||
```
|
||||
|
||||
## RBAC Authorization
|
||||
|
||||
Check the [RBAC sample](/examples/rbac/haproxy) if deploying on a cluster with
|
||||
[RBAC authorization](https://kubernetes.io/docs/admin/authorization/rbac/).
|
||||
|
||||
## Ingress DaemonSet
|
||||
|
||||
Deploy the daemonset as follows:
|
||||
|
||||
```console
|
||||
$ kubectl apply -f haproxy-ingress-daemonset.yaml
|
||||
```
|
||||
|
||||
Check if the controller was successfully deployed:
|
||||
```console
|
||||
$ kubectl -n kube-system get ds
|
||||
NAME DESIRED CURRENT READY NODE-SELECTOR AGE
|
||||
haproxy-ingress 2 2 2 <none> 45s
|
||||
|
||||
$ kubectl -n kube-system get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
default-http-backend-q5sb6 1/1 Running 0 45m
|
||||
haproxy-ingress-km32x 1/1 Running 0 1m
|
||||
```
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
labels:
|
||||
run: haproxy-ingress
|
||||
name: haproxy-ingress
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
run: haproxy-ingress
|
||||
spec:
|
||||
containers:
|
||||
- name: haproxy-ingress
|
||||
image: quay.io/jcmoraisjr/haproxy-ingress
|
||||
args:
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --default-ssl-certificate=$(POD_NAMESPACE)/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
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
# Deploying HAProxy Ingress Controller
|
||||
|
||||
If you don't have a Kubernetes cluster, please refer to [Setup cluster](/docs/dev/setup-cluster.md)
|
||||
for instructions on how to create a new one.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
If you have another Ingress controller deployed, you will need to make sure your
|
||||
Ingress resources target exactly one Ingress controller by specifying the
|
||||
[ingress.class](/examples/PREREQUISITES.md#ingress-class) annotation as
|
||||
`haproxy`.
|
||||
|
||||
This document has also the following prerequisites:
|
||||
|
||||
* Create a [TLS secret](/examples/PREREQUISITES.md#tls-certificates) named `tls-secret` to be used as default TLS certificate
|
||||
* Optional: deploy a [web app](/examples/PREREQUISITES.md#test-http-service) for testing
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
The optional web app can be created as follow:
|
||||
|
||||
```console
|
||||
$ kubectl run http-svc \
|
||||
--image=gcr.io/google_containers/echoserver:1.3 \
|
||||
--port=8080 \
|
||||
--replicas=1 \
|
||||
--expose
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## Configmap
|
||||
|
||||
Create a configmap named `haproxy-ingress`:
|
||||
|
||||
```console
|
||||
$ kubectl create configmap haproxy-ingress
|
||||
configmap "haproxy-ingress" created
|
||||
```
|
||||
|
||||
A configmap is used to provide global or default configuration like
|
||||
timeouts, SSL/TLS settings, a syslog service endpoint and so on. The
|
||||
configmap can be edited or replaced later in order to apply new
|
||||
configuration on a running ingress controller. All supported options
|
||||
are [here](https://github.com/jcmoraisjr/haproxy-ingress#configmap).
|
||||
|
||||
## RBAC Authorization
|
||||
|
||||
Check the [RBAC sample](/examples/rbac/haproxy) if deploying on a cluster with
|
||||
[RBAC authorization](https://kubernetes.io/docs/admin/authorization/rbac/).
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
From now the optional web app should be deployed. Deploy an ingress resource to expose this 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: 8080
|
||||
EOF
|
||||
```
|
||||
|
||||
Expose the Ingress 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 pod/haproxy-ingress-2556761959-tv20k
|
||||
```
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
run: haproxy-ingress
|
||||
name: haproxy-ingress
|
||||
spec:
|
||||
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=$(POD_NAMESPACE)/ingress-default-backend
|
||||
- --default-ssl-certificate=$(POD_NAMESPACE)/tls-secret
|
||||
- --configmap=$(POD_NAMESPACE)/haproxy-ingress
|
||||
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
|
||||
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
|
@ -1,70 +0,0 @@
|
|||
# HAProxy Multi TLS certificate termination
|
||||
|
||||
This example uses 2 different certificates to terminate SSL for 2 hostnames.
|
||||
|
||||
## 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 [*two* secrets](/examples/PREREQUISITES.md#tls-certificates) named `foobar-ssl` with subject `'/CN=foo.bar'` and `barfoo-ssl` with subject `'/CN=bar.foo'`
|
||||
|
||||
## Using a new TLS certificate
|
||||
|
||||
Update ingress resource in order to add TLS termination to two hosts:
|
||||
|
||||
```console
|
||||
$ kubectl replace -f ingress-multi-tls.yaml
|
||||
```
|
||||
|
||||
Trying without host:
|
||||
|
||||
```console
|
||||
$ curl -iL 10.129.51.55:30221
|
||||
HTTP/1.1 404 Not Found
|
||||
Date: Tue, 28 Mar 2017 07:32:34 GMT
|
||||
Content-Length: 21
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
|
||||
default backend - 404
|
||||
```
|
||||
|
||||
Telling the controller we are `foo.bar` or `bar.foo`:
|
||||
|
||||
```console
|
||||
$ curl -iL 10.129.51.55:36462 -H 'Host: foo.bar'
|
||||
HTTP/1.1 302 Found
|
||||
Cache-Control: no-cache
|
||||
Content-length: 0
|
||||
Location: https://foo.bar/
|
||||
Connection: close
|
||||
$ curl -iL 10.129.51.55:36462 -H 'Host: bar.foo'
|
||||
HTTP/1.1 302 Found
|
||||
Cache-Control: no-cache
|
||||
Content-length: 0
|
||||
Location: https://bar.foo/
|
||||
Connection: close
|
||||
^C
|
||||
```
|
||||
|
||||
Note the `Location` header - this would redirect us to the correct server.
|
||||
|
||||
Checking the certificate - change below `31578` to the TLS port:
|
||||
|
||||
```console
|
||||
$ openssl s_client -connect 10.129.51.55:31578 -servername foo.bar
|
||||
...
|
||||
subject=/CN=foo.bar
|
||||
issuer=/CN=foo.bar
|
||||
---
|
||||
```
|
||||
|
||||
... and `bar.foo` certificate:
|
||||
|
||||
```console
|
||||
$ openssl s_client -connect 10.129.51.55:31578 -servername bar.foo
|
||||
...
|
||||
subject=/CN=bar.foo
|
||||
issuer=/CN=bar.foo
|
||||
---
|
||||
```
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: app
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- foo.bar
|
||||
secretName: foobar-ssl
|
||||
- hosts:
|
||||
- bar.foo
|
||||
secretName: barfoo-ssl
|
||||
rules:
|
||||
- host: foo.bar
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: back-svc1
|
||||
servicePort: 8080
|
||||
- host: bar.foo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: back-svc2
|
||||
servicePort: 8080
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# Role Based Access Control
|
||||
|
||||
This example demonstrates how to authorize an ingress controller on a cluster
|
||||
with role based access control.
|
||||
|
||||
## Overview
|
||||
|
||||
This example applies to ingress controllers being deployed in an environment with
|
||||
[RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) enabled.
|
||||
|
||||
## Service Account created in this example
|
||||
|
||||
One ServiceAccount is created in this example, `ingress-controller`. See
|
||||
[Using cert based authentication](#using-cert-based-authentication)
|
||||
below if using client cert authentication.
|
||||
|
||||
## Permissions Granted in this example
|
||||
|
||||
There are two sets of permissions defined in this example. Cluster-wide
|
||||
permissions defined by a `ClusterRole` and namespace specific permissions
|
||||
defined by a `Role`, both named `ingress-controller`.
|
||||
|
||||
### Cluster Permissions
|
||||
|
||||
These permissions are granted in order for the ingress-controller to be
|
||||
able to function as an ingress across the cluster. These permissions are
|
||||
granted to the ClusterRole:
|
||||
|
||||
* `configmaps`, `endpoints`, `nodes`, `pods`, `secrets`: list, watch
|
||||
* `nodes`: get
|
||||
* `services`, `ingresses`: get, list, watch
|
||||
* `events`: create, patch
|
||||
* `ingresses/status`: update
|
||||
|
||||
### Namespace Permissions
|
||||
|
||||
These permissions are granted specific to the `ingress-controller` namespace.
|
||||
The Role permissions are:
|
||||
|
||||
* `configmaps`, `pods`, `secrets`: get
|
||||
* `endpoints`: create, get, update
|
||||
|
||||
Furthermore to support leader-election, the ingress controller needs to
|
||||
have access to a `configmap` in the `ingress-controller` namespace:
|
||||
|
||||
* `configmaps`: get, update, create
|
||||
|
||||
## Namespace created in this example
|
||||
|
||||
The `Namespace` named `ingress-controller` is defined in this example. The
|
||||
namespace name can be changed arbitrarily as long as all of the references
|
||||
change as well.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Create the `Namespace`, `Service Account`, `ClusterRole`, `Role`,
|
||||
`ClusterRoleBinding`, and `RoleBinding`:
|
||||
|
||||
```console
|
||||
$ kubectl create -f ingress-controller-rbac.yml
|
||||
```
|
||||
|
||||
2. Deploy the ingress controller. The deployment should be configured to use
|
||||
the `ingress-controller` service account name if not using kubeconfig and
|
||||
client cert based authentication. Add the `serviceAccountName` to the pod
|
||||
template spec:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: ingress-controller
|
||||
```
|
||||
|
||||
## Using cert based authentication
|
||||
|
||||
A client certificate based authentication can also be used with the following changes:
|
||||
|
||||
1. No need to add the `serviceAccountName` to the pod template spec.
|
||||
2. Sign a client certificate using `ingress-controller` as it's common name.
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
namespace: ingress-controller
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- endpoints
|
||||
- nodes
|
||||
- pods
|
||||
- secrets
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
namespace: ingress-controller
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- pods
|
||||
- secrets
|
||||
- namespaces
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- endpoints
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: ingress-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ingress-controller
|
||||
namespace: ingress-controller
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: User
|
||||
name: ingress-controller
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ingress-controller
|
||||
namespace: ingress-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: ingress-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ingress-controller
|
||||
namespace: ingress-controller
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: User
|
||||
name: ingress-controller
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
# HAProxy Ingress rewrite
|
||||
|
||||
This example demonstrates how to use rewrite options on HAProxy Ingress controller.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This document has the following prerequisites:
|
||||
|
||||
* Deploy [HAProxy Ingress](/examples/deployment/haproxy) controller, you should
|
||||
end up with controller, a sample web app and an ingress resource named `app` to
|
||||
the `foo.bar` domain
|
||||
* Configure only the default [TLS termination](/examples/tls-termination/haproxy) -
|
||||
there is no need to create another secret
|
||||
|
||||
## Annotations
|
||||
|
||||
The following annotations are implemented:
|
||||
|
||||
* `ingress.kubernetes.io/ssl-redirect`: Indicates whether a redirect should be
|
||||
done from HTTP to HTTPS. Possible values are `"true"` to redirect to HTTPS,
|
||||
or `"false"` meaning requests may be performed as plain HTTP.
|
||||
* `ingress.kubernetes.io/app-root`: Defines the URL to be redirected when requests
|
||||
are done to the root context `/`.
|
||||
|
||||
### SSL Redirect
|
||||
|
||||
Annotate the `app` ingress resource:
|
||||
|
||||
```console
|
||||
$ kubectl annotate ingress/app --overwrite ingress.kubernetes.io/ssl-redirect=false
|
||||
ingress "app" annotated
|
||||
```
|
||||
|
||||
Try a HTTP request:
|
||||
|
||||
```console
|
||||
$ curl -iL 172.17.4.99:30876 -H 'Host: foo.bar'
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Sat, 15 Apr 2017 19:27:30 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.33.14
|
||||
command=GET
|
||||
real path=/
|
||||
query=nil
|
||||
...
|
||||
```
|
||||
|
||||
Now turn ssl-redirect true:
|
||||
|
||||
```console
|
||||
$ kubectl annotate ingress/app --overwrite ingress.kubernetes.io/ssl-redirect=true
|
||||
ingress "app" annotated
|
||||
|
||||
$ 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/
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
The default value of ssl-redirect annotation is true and can be changed globally
|
||||
using a [ConfigMap](https://github.com/jcmoraisjr/haproxy-ingress#configmap).
|
||||
|
||||
### App root context redirect
|
||||
|
||||
Annotate the `app` ingress resource with `app-root`, and also `ssl-redirect` to `false` for simplicity:
|
||||
|
||||
```console
|
||||
$ kubectl annotate ingress/app --overwrite ingress.kubernetes.io/app-root=/web
|
||||
ingress "app" annotated
|
||||
|
||||
$ kubectl annotate ingress/app --overwrite ingress.kubernetes.io/ssl-redirect=false
|
||||
ingress "app" annotated
|
||||
```
|
||||
|
||||
Try a HTTP request:
|
||||
|
||||
```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: /web
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.9.11
|
||||
Date: Sat, 15 Apr 2017 19:34:49 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
CLIENT VALUES:
|
||||
client_address=10.2.33.14
|
||||
command=GET
|
||||
real path=/web
|
||||
query=nil
|
||||
...
|
||||
```
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
# Deploying multi Haproxy Ingress Controllers
|
||||
|
||||
This example aims to demonstrate the Deployment of multi haproxy ingress controllers.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
If you have another Ingress controller deployed, you will need to make sure your
|
||||
Ingress resources target exactly one Ingress controller by specifying the
|
||||
[ingress.class](/examples/PREREQUISITES.md#ingress-class) annotation as
|
||||
`haproxy`.
|
||||
|
||||
This document has also the following prerequisites:
|
||||
|
||||
* Create a [TLS secret](/examples/PREREQUISITES.md#tls-certificates) named `tls-secret` to be used as default TLS certificate
|
||||
|
||||
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
|
||||
|
||||
The default backend is a service of handling all url paths and hosts the haproxy controller doesn't understand. Deploy the default-http-backend as follow:
|
||||
|
||||
```console
|
||||
$ kubectl create -f default-backend.yaml
|
||||
deployment "default-http-backend" created
|
||||
service "default-http-backend" created
|
||||
|
||||
$ kubectl get svc
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
default-http-backend 192.168.3.4 <none> 80/TCP 30m
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
default-http-backend-q5sb6 1/1 Running 0 30m
|
||||
```
|
||||
|
||||
## RBAC Authorization
|
||||
|
||||
Check the [RBAC sample](/examples/rbac/haproxy) if deploying on a cluster with
|
||||
[RBAC authorization](https://kubernetes.io/docs/admin/authorization/rbac/).
|
||||
|
||||
## Ingress Deployment
|
||||
|
||||
Deploy the Deployment of multi controllers as follows:
|
||||
|
||||
```console
|
||||
$ kubectl apply -f haproxy-ingress-deployment.yaml
|
||||
deployment "haproxy-ingress" created
|
||||
```
|
||||
|
||||
Check if the controller was successfully deployed:
|
||||
```console
|
||||
$ kubectl get deployment
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
default-http-backend 1 1 1 1 30m
|
||||
haproxy-ingress 2 2 2 2 45s
|
||||
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
default-http-backend-q5sb6 1/1 Running 0 35m
|
||||
haproxy-ingress-1779899633-k045t 1/1 Running 0 1m
|
||||
haproxy-ingress-1779899633-mhthv 1/1 Running 0 1m
|
||||
```
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: default-http-backend
|
||||
labels:
|
||||
k8s-app: default-http-backend
|
||||
spec:
|
||||
replicas: 1
|
||||
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: Service
|
||||
metadata:
|
||||
name: default-http-backend
|
||||
labels:
|
||||
k8s-app: default-http-backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
k8s-app: default-http-backend
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
run: haproxy-ingress
|
||||
name: haproxy-ingress
|
||||
spec:
|
||||
replicas: 2
|
||||
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=$(POD_NAMESPACE)/default-http-backend
|
||||
- --default-ssl-certificate=$(POD_NAMESPACE)/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
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
# HAProxy Ingress 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'`
|
||||
|
||||
## 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
|
||||
---
|
||||
```
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
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: 8080
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
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: 8080
|
||||