From 4343aabba862d179928240548164f803b33da571 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Thu, 2 Feb 2017 19:41:02 -0300 Subject: [PATCH 01/13] Simplify code to obtain TCP or UDP services --- core/pkg/ingress/controller/controller.go | 47 ++++++----------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 408c729e8..be747de0d 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -390,8 +390,8 @@ func (ic *GenericController) sync(key interface{}) error { data, err := ic.cfg.Backend.OnUpdate(ingress.Configuration{ Backends: upstreams, Servers: servers, - TCPEndpoints: ic.getTCPServices(), - UPDEndpoints: ic.getUDPServices(), + TCPEndpoints: ic.getStreamServices(ic.cfg.TCPConfigMapName, api.ProtocolTCP), + UPDEndpoints: ic.getStreamServices(ic.cfg.UDPConfigMapName, api.ProtocolUDP), PassthroughBackends: passUpstreams, }) if err != nil { @@ -411,54 +411,31 @@ func (ic *GenericController) sync(key interface{}) error { return nil } -func (ic *GenericController) getTCPServices() []*ingress.Location { - if ic.cfg.TCPConfigMapName == "" { - // no configmap for TCP services +func (ic *GenericController) getStreamServices(configmapName string, proto api.Protocol) []*ingress.Location { + if configmapName == "" { + // no configmap configured return []*ingress.Location{} } - ns, name, err := k8s.ParseNameNS(ic.cfg.TCPConfigMapName) + ns, name, err := k8s.ParseNameNS(configmapName) if err != nil { - glog.Warningf("%v", err) + glog.Errorf("unexpected error reading configmap %v: %v", name, err) return []*ingress.Location{} } - tcpMap, err := ic.getConfigMap(ns, name) + + configmap, err := ic.getConfigMap(ns, name) if err != nil { - glog.V(5).Infof("no configured tcp services found: %v", err) + glog.Errorf("unexpected error reading configmap %v: %v", name, err) return []*ingress.Location{} } - return ic.getStreamServices(tcpMap.Data, api.ProtocolTCP) -} - -func (ic *GenericController) getUDPServices() []*ingress.Location { - if ic.cfg.UDPConfigMapName == "" { - // no configmap for TCP services - return []*ingress.Location{} - } - - ns, name, err := k8s.ParseNameNS(ic.cfg.UDPConfigMapName) - if err != nil { - glog.Warningf("%v", err) - return []*ingress.Location{} - } - tcpMap, err := ic.getConfigMap(ns, name) - if err != nil { - glog.V(3).Infof("no configured tcp services found: %v", err) - return []*ingress.Location{} - } - - return ic.getStreamServices(tcpMap.Data, api.ProtocolUDP) -} - -func (ic *GenericController) getStreamServices(data map[string]string, proto api.Protocol) []*ingress.Location { var svcs []*ingress.Location // k -> port to expose // v -> /: - for k, v := range data { + for k, v := range configmap.Data { _, err := strconv.Atoi(k) if err != nil { - glog.Warningf("%v is not valid as a TCP port", k) + glog.Warningf("%v is not valid as a TCP/UDP port", k) continue } From 008c47c2d30934e2fdd6c83ac1ac125a6b66c54d Mon Sep 17 00:00:00 2001 From: Tang Le Date: Sat, 4 Feb 2017 15:37:06 +0800 Subject: [PATCH 02/13] Fix worker check issue Signed-off-by: Tang Le --- controllers/nginx/pkg/cmd/controller/nginx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index 9e2bb64d2..302063a2f 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -132,10 +132,10 @@ NGINX master process died (%v): %v // we wait until the workers are killed for { conn, err := net.DialTimeout("tcp", "127.0.0.1:80", 1*time.Second) - if err == nil { - conn.Close() + if err != nil { break } + conn.Close() time.Sleep(1 * time.Second) } // start a new nginx master process From 6fa461c2a7891b4f20fffd1c9f7fe2fce5085cd3 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Sat, 4 Feb 2017 02:13:24 -0500 Subject: [PATCH 03/13] proxy_protocol on ssl_passthrough listener Move proxy_protocol to listener. Fix #207 --- controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 2c4d3cc2e..fa1aa5273 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -434,8 +434,7 @@ stream { {{ buildSSPassthroughUpstreams $backends .PassthroughBackends }} server { - listen [::]:443 ipv6only=off; - {{ if $cfg.UseProxyProtocol }}proxy_protocol on;{{ end }} + listen [::]:443 ipv6only=off{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}; proxy_pass $stream_upstream; ssl_preread on; } From 8d71557b13c98696894fa0b59c994ba3c369b50f Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Sat, 4 Feb 2017 19:01:49 -0500 Subject: [PATCH 04/13] Remove proxy_protocol from 442 listener The proxy_protocol processing should only happen once, on the "external-facing" listeners. --- controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index fa1aa5273..4bbc90c69 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -203,7 +203,7 @@ http { server_name {{ $server.Hostname }}; listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $index 0 }} ipv6only=off{{end}}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}}; {{/* Listen on 442 because port 443 is used in the stream section */}} - {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if $cfg.UseProxyProtocol }}proxy_protocol{{ end }} {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }}; + {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }}; {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} # PEM sha: {{ $server.SSLPemChecksum }} ssl_certificate {{ $server.SSLCertificate }}; From 36f842c011e403ca454434f95c81e32f18b46c61 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 4 Feb 2017 21:26:32 -0300 Subject: [PATCH 05/13] Add information about proxy_protocol in port 442 --- controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 4bbc90c69..c4f4c497f 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -203,6 +203,7 @@ http { server_name {{ $server.Hostname }}; listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $index 0 }} ipv6only=off{{end}}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}}; {{/* Listen on 442 because port 443 is used in the stream section */}} + {{/* This listen cannot contains proxy_protocol directive because port 443 is in charge of decoding the protocol */}} {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }}; {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} # PEM sha: {{ $server.SSLPemChecksum }} From 80a0481550794f26fbc3d20e6181924638d5646b Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sun, 5 Feb 2017 19:41:05 -0300 Subject: [PATCH 06/13] Change searchs with searches --- core/pkg/ingress/controller/controller.go | 2 +- core/pkg/ingress/resolver/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 145c3501a..0fecef961 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -330,7 +330,7 @@ func (ic GenericController) GetDefaultBackend() defaults.Backend { return ic.cfg.Backend.BackendDefaults() } -// GetSecret searchs for a secret in the local secrets Store +// GetSecret searches for a secret in the local secrets Store func (ic GenericController) GetSecret(name string) (*api.Secret, error) { s, exists, err := ic.secrLister.Store.GetByKey(name) if err != nil { diff --git a/core/pkg/ingress/resolver/main.go b/core/pkg/ingress/resolver/main.go index 1e122e236..6017c8cb5 100644 --- a/core/pkg/ingress/resolver/main.go +++ b/core/pkg/ingress/resolver/main.go @@ -28,7 +28,7 @@ type DefaultBackend interface { GetDefaultBackend() defaults.Backend } -// Secret has a method that searchs for secrets contenating +// Secret has a method that searches for secrets contenating // the namespace and name using a the character / type Secret interface { GetSecret(string) (*api.Secret, error) From 61954a0bafde0f06bc8ad011ebca3e647e2da6d8 Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Mon, 6 Feb 2017 21:40:03 -0200 Subject: [PATCH 07/13] Add HAProxy Ingress to the catalog --- docs/catalog.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/catalog.md b/docs/catalog.md index 6c1ccd43f..2612790c7 100644 --- a/docs/catalog.md +++ b/docs/catalog.md @@ -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) From 51ead1ce73e014bc7bf5f0edb9cf0e69e4525b29 Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Mon, 6 Feb 2017 21:25:38 -0200 Subject: [PATCH 08/13] Docs - deploying HAProxy Ingress Controller --- examples/deployment/haproxy/README.md | 107 ++++++++++++++++++ .../deployment/haproxy/haproxy-ingress.yaml | 39 +++++++ 2 files changed, 146 insertions(+) create mode 100644 examples/deployment/haproxy/README.md create mode 100644 examples/deployment/haproxy/haproxy-ingress.yaml diff --git a/examples/deployment/haproxy/README.md b/examples/deployment/haproxy/README.md new file mode 100644 index 000000000..61f2660d1 --- /dev/null +++ b/examples/deployment/haproxy/README.md @@ -0,0 +1,107 @@ +# Deploying HAProxy Ingress Controller + +Don't have a Kubernetes cluster? Single-node of [CoreOS Kubernetes](https://github.com/coreos/coreos-kubernetes/) is a good starting point. + +Deploy a default backend used to serve `404 Not Found` pages: + + 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: + + kubectl get pod + NAME READY STATUS RESTARTS AGE + ingress-default-backend-1110790216-gqr61 1/1 Running 0 10s + +Deploy certificate and private key used to serve https on ingress that doesn't provide it's own certificate. For testing purposes a self signed certificate is ok: + + openssl req \ + -x509 -newkey rsa:2048 -nodes -days 365 \ + -keyout tls.key -out tls.crt -subj '/CN=localhost' + kubectl create secret tls ingress-default-ssl --cert=tls.crt --key=tls.key + rm -v tls.crt tls.key + +Deploy HAProxy Ingress. Note that `hostNetwork: true` could be uncommented if your cluster has IPs that doesn't use ports 80, 443 and 1936. + + kubectl create -f haproxy-ingress.yaml + +Check if the controller was successfully deployed: + + 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 + +Problem? Check logs and events of the POD: + + kubectl logs haproxy-ingress-2556761959-tv20k + kubectl describe haproxy-ingress-2556761959-tv20k + +Deploy some web application and it's ingress resource: + + kubectl run nginx --image=nginx:alpine --port=80 --expose + kubectl create -f - < + + + Welcome to nginx! + ... + +Not what you were looking for? Have a look at controller's logs: + + kubectl get pod + NAME READY STATUS RESTARTS AGE + haproxy-ingress-2556761959-tv20k 1/1 Running 0 9m + ... + + kubectl logs haproxy-ingress-2556761959-tv20k | less -S diff --git a/examples/deployment/haproxy/haproxy-ingress.yaml b/examples/deployment/haproxy/haproxy-ingress.yaml new file mode 100644 index 000000000..5dffb9aa0 --- /dev/null +++ b/examples/deployment/haproxy/haproxy-ingress.yaml @@ -0,0 +1,39 @@ +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: + # hostNetwork: true + containers: + - name: haproxy-ingress + image: quay.io/jcmoraisjr/haproxy-ingress + args: + - --default-backend-service=default/ingress-default-backend + - --default-ssl-certificate=default/ingress-default-ssl + 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 From b579cbba7412bc6999bbfd168c60c80c4da1be75 Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Mon, 6 Feb 2017 22:28:45 -0200 Subject: [PATCH 09/13] Docs - TLS termination of HAProxy Ingress --- examples/tls-termination/haproxy/README.md | 71 +++++++++++++++++++ .../haproxy/ingress-tls-default.yaml | 16 +++++ .../haproxy/ingress-tls-foobar.yaml | 17 +++++ 3 files changed, 104 insertions(+) create mode 100644 examples/tls-termination/haproxy/README.md create mode 100644 examples/tls-termination/haproxy/ingress-tls-default.yaml create mode 100644 examples/tls-termination/haproxy/ingress-tls-foobar.yaml diff --git a/examples/tls-termination/haproxy/README.md b/examples/tls-termination/haproxy/README.md new file mode 100644 index 000000000..26a76e9ce --- /dev/null +++ b/examples/tls-termination/haproxy/README.md @@ -0,0 +1,71 @@ +# TLS termination + +Before continue, follow [deploying HAProxy Ingress](/examples/deployment/haproxy) in order to have a functional ingress controller. + +Update ingress resource in order to add tls termination to host `foo.bar`: + + kubectl replace -f ingress-tls-default.yaml + +Trying default backend: + + 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`: + + 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: + + openssl s_client -connect 172.17.4.99:31692 + ... + subject=/CN=localhost + issuer=/CN=localhost + --- + +... and `foo.bar` certificate: + + openssl s_client -connect 172.17.4.99:31692 -servername foo.bar + ... + subject=/CN=localhost + issuer=/CN=localhost + --- + +Let's create a new certificate to our domain: + + openssl req \ + -x509 -newkey rsa:2048 -nodes -days 365 \ + -keyout tls.key -out tls.crt -subj '/CN=foo.bar' + kubectl create secret tls foobar-ssl --cert=tls.crt --key=tls.key + rm -v tls.crt tls.key + +... and reference in the ingress resource: + + kubectl replace -f ingress-tls-foobar.yaml + +Now `foo.bar` certificate should be used to terminate tls: + + 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 + --- diff --git a/examples/tls-termination/haproxy/ingress-tls-default.yaml b/examples/tls-termination/haproxy/ingress-tls-default.yaml new file mode 100644 index 000000000..8afdaff52 --- /dev/null +++ b/examples/tls-termination/haproxy/ingress-tls-default.yaml @@ -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: nginx + servicePort: 80 diff --git a/examples/tls-termination/haproxy/ingress-tls-foobar.yaml b/examples/tls-termination/haproxy/ingress-tls-foobar.yaml new file mode 100644 index 000000000..e004822f5 --- /dev/null +++ b/examples/tls-termination/haproxy/ingress-tls-foobar.yaml @@ -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: nginx + servicePort: 80 From 229250f419d50f212d19d24d9c9926bb07f41755 Mon Sep 17 00:00:00 2001 From: caiyixiang Date: Tue, 7 Feb 2017 14:35:39 +0800 Subject: [PATCH 10/13] changeUDP --- controllers/nginx/pkg/cmd/controller/nginx.go | 2 +- core/pkg/ingress/controller/controller.go | 2 +- core/pkg/ingress/types.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index 9e2bb64d2..456ffacf0 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -331,7 +331,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er PassthroughBackends: ingressCfg.PassthroughBackends, Servers: ingressCfg.Servers, TCPBackends: ingressCfg.TCPEndpoints, - UDPBackends: ingressCfg.UPDEndpoints, + UDPBackends: ingressCfg.UDPEndpoints, HealthzURI: ngxHealthPath, CustomErrors: len(cfg.CustomHTTPErrors) > 0, Cfg: cfg, diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 0fecef961..5c979dcce 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -391,7 +391,7 @@ func (ic *GenericController) sync(key interface{}) error { Backends: upstreams, Servers: servers, TCPEndpoints: ic.getStreamServices(ic.cfg.TCPConfigMapName, api.ProtocolTCP), - UPDEndpoints: ic.getStreamServices(ic.cfg.UDPConfigMapName, api.ProtocolUDP), + UDPEndpoints: ic.getStreamServices(ic.cfg.UDPConfigMapName, api.ProtocolUDP), PassthroughBackends: passUpstreams, }) if err != nil { diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go index 4891995e7..49f849a57 100644 --- a/core/pkg/ingress/types.go +++ b/core/pkg/ingress/types.go @@ -113,9 +113,9 @@ type Configuration struct { // TCPEndpoints contain endpoints for tcp streams handled by this backend // +optional TCPEndpoints []*Location `json:"tcpEndpoints,omitempty"` - // UPDEndpoints contain endpoints for udp streams handled by this backend + // UDPEndpoints contain endpoints for udp streams handled by this backend // +optional - UPDEndpoints []*Location `json:"udpEndpoints,omitempty"` + UDPEndpoints []*Location `json:"udpEndpoints,omitempty"` // PassthroughBackend contains the backends used for SSL passthrough. // It contains information about the associated Server Name Indication (SNI). // +optional From ee484aa19f47264d956c2cf5d6e0963503272a10 Mon Sep 17 00:00:00 2001 From: Leszek Charkiewicz Date: Tue, 7 Feb 2017 20:26:11 +0100 Subject: [PATCH 11/13] Fix wrong URL in nginx ingress configuration --- controllers/nginx/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/nginx/configuration.md b/controllers/nginx/configuration.md index 776644b6f..c494d1aab 100644 --- a/controllers/nginx/configuration.md +++ b/controllers/nginx/configuration.md @@ -66,7 +66,7 @@ In addition to the built-in functions provided by the Go package the following f - empty: returns true if the specified parameter (string) is empty - contains: [strings.Contains](https://golang.org/pkg/strings/#Contains) - - hasPrefix: [strings.HasPrefix](https://golang.org/pkg/strings/#Contains) + - hasPrefix: [strings.HasPrefix](https://golang.org/pkg/strings/#HasPrefix) - hasSuffix: [strings.HasSuffix](https://golang.org/pkg/strings/#HasSuffix) - toUpper: [strings.ToUpper](https://golang.org/pkg/strings/#ToUpper) - toLower: [strings.ToLower](https://golang.org/pkg/strings/#ToLower) From 8d19531b261c333f05c936ab97103d969748dd8f Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Tue, 7 Feb 2017 21:45:12 -0200 Subject: [PATCH 12/13] Consistency editing of HAProxy Ingress docs --- docs/dev/setup.md | 8 + examples/deployment/haproxy/README.md | 194 +++++++++++------- .../deployment/haproxy/haproxy-ingress.yaml | 3 +- examples/tls-termination/haproxy/README.md | 135 ++++++++---- 4 files changed, 218 insertions(+), 122 deletions(-) diff --git a/docs/dev/setup.md b/docs/dev/setup.md index b41810e1b..f61695293 100644 --- a/docs/dev/setup.md +++ b/docs/dev/setup.md @@ -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 diff --git a/examples/deployment/haproxy/README.md b/examples/deployment/haproxy/README.md index 61f2660d1..f33769362 100644 --- a/examples/deployment/haproxy/README.md +++ b/examples/deployment/haproxy/README.md @@ -1,107 +1,151 @@ # Deploying HAProxy Ingress Controller -Don't have a Kubernetes cluster? Single-node of [CoreOS Kubernetes](https://github.com/coreos/coreos-kubernetes/) is a good starting point. +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: - kubectl run ingress-default-backend \ - --image=gcr.io/google_containers/defaultbackend:1.0 \ - --port=8080 \ - --limits=cpu=10m,memory=20Mi \ - --expose +```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: - kubectl get pod - NAME READY STATUS RESTARTS AGE - ingress-default-backend-1110790216-gqr61 1/1 Running 0 10s +```console +$ kubectl get pod +NAME READY STATUS RESTARTS AGE +ingress-default-backend-1110790216-gqr61 1/1 Running 0 10s +``` -Deploy certificate and private key used to serve https on ingress that doesn't provide it's own certificate. For testing purposes a self signed certificate is ok: +## Controller - openssl req \ - -x509 -newkey rsa:2048 -nodes -days 365 \ - -keyout tls.key -out tls.crt -subj '/CN=localhost' - kubectl create secret tls ingress-default-ssl --cert=tls.crt --key=tls.key - rm -v tls.crt tls.key +Deploy HAProxy Ingress: -Deploy HAProxy Ingress. Note that `hostNetwork: true` could be uncommented if your cluster has IPs that doesn't use ports 80, 443 and 1936. - - kubectl create -f haproxy-ingress.yaml +```console +$ kubectl create -f haproxy-ingress.yaml +``` Check if the controller was successfully deployed: - 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 +```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 +``` -Problem? Check logs and events of the POD: +Deploy the ingress resource of our already deployed web app: - kubectl logs haproxy-ingress-2556761959-tv20k - kubectl describe haproxy-ingress-2556761959-tv20k +```console +$ kubectl create -f - < - - - Welcome to nginx! - ... +CLIENT VALUES: +client_address=10.2.18.5 +command=GET +real path=/ +query=nil +request_version=1.1 +request_uri=http://foo.bar:8080/ +... +``` -Not what you were looking for? Have a look at controller's logs: +## Troubleshooting - kubectl get pod - NAME READY STATUS RESTARTS AGE - haproxy-ingress-2556761959-tv20k 1/1 Running 0 9m - ... +If you have any problem, check logs and events of HAProxy Ingress POD: - kubectl logs haproxy-ingress-2556761959-tv20k | less -S +```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 +``` diff --git a/examples/deployment/haproxy/haproxy-ingress.yaml b/examples/deployment/haproxy/haproxy-ingress.yaml index 5dffb9aa0..619b2d9cc 100644 --- a/examples/deployment/haproxy/haproxy-ingress.yaml +++ b/examples/deployment/haproxy/haproxy-ingress.yaml @@ -14,13 +14,12 @@ spec: labels: run: haproxy-ingress spec: - # hostNetwork: true containers: - name: haproxy-ingress image: quay.io/jcmoraisjr/haproxy-ingress args: - --default-backend-service=default/ingress-default-backend - - --default-ssl-certificate=default/ingress-default-ssl + - --default-ssl-certificate=default/tls-secret ports: - name: http containerPort: 80 diff --git a/examples/tls-termination/haproxy/README.md b/examples/tls-termination/haproxy/README.md index 26a76e9ce..2393ef2c2 100644 --- a/examples/tls-termination/haproxy/README.md +++ b/examples/tls-termination/haproxy/README.md @@ -1,71 +1,116 @@ # TLS termination -Before continue, follow [deploying HAProxy Ingress](/examples/deployment/haproxy) in order to have a functional ingress controller. +## Prerequisites -Update ingress resource in order to add tls termination to host `foo.bar`: +This document has the following prerequisites: - kubectl replace -f ingress-tls-default.yaml +* 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: - 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 +```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 +default backend - 404 +``` Now telling the controller we are `foo.bar`: - 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 +```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: - openssl s_client -connect 172.17.4.99:31692 - ... - subject=/CN=localhost - issuer=/CN=localhost - --- +```console +$ openssl s_client -connect 172.17.4.99:31692 +... +subject=/CN=localhost +issuer=/CN=localhost +--- +``` ... and `foo.bar` certificate: - openssl s_client -connect 172.17.4.99:31692 -servername foo.bar - ... - subject=/CN=localhost - issuer=/CN=localhost - --- +```console +$ openssl s_client -connect 172.17.4.99:31692 -servername foo.bar +... +subject=/CN=localhost +issuer=/CN=localhost +--- +``` -Let's create a new certificate to our domain: +## Using a new TLS certificate - openssl req \ - -x509 -newkey rsa:2048 -nodes -days 365 \ - -keyout tls.key -out tls.crt -subj '/CN=foo.bar' - kubectl create secret tls foobar-ssl --cert=tls.crt --key=tls.key - rm -v tls.crt tls.key +Now let's reference the new certificate to our domain. Note that secret +`foobar-ssl` should be created as described in the [prerequisites](#prerequisites) -... and reference in the ingress resource: +```console +$ kubectl replace -f ingress-tls-foobar.yaml +``` - kubectl replace -f ingress-tls-foobar.yaml +Here is the difference: -Now `foo.bar` certificate should be used to terminate tls: +```console + tls: + - hosts: + - foo.bar ++ secretName: foobar-ssl + rules: + - host: foo.bar + http: +``` - openssl s_client -connect 172.17.4.99:31692 - ... - subject=/CN=localhost - issuer=/CN=localhost - --- +Now `foo.bar` certificate should be used to terminate TLS: - openssl s_client -connect 172.17.4.99:31692 -servername foo.bar - ... - subject=/CN=foo.bar - issuer=/CN=foo.bar - --- +```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 +--- +``` From cccd1476f91adfda40a4841a368e07426c6882b3 Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Tue, 7 Feb 2017 21:47:45 -0200 Subject: [PATCH 13/13] Fix service names of HAProxy Ingress docs --- examples/tls-termination/haproxy/ingress-tls-default.yaml | 2 +- examples/tls-termination/haproxy/ingress-tls-foobar.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/tls-termination/haproxy/ingress-tls-default.yaml b/examples/tls-termination/haproxy/ingress-tls-default.yaml index 8afdaff52..f546fbd83 100644 --- a/examples/tls-termination/haproxy/ingress-tls-default.yaml +++ b/examples/tls-termination/haproxy/ingress-tls-default.yaml @@ -12,5 +12,5 @@ spec: paths: - path: / backend: - serviceName: nginx + serviceName: http-svc servicePort: 80 diff --git a/examples/tls-termination/haproxy/ingress-tls-foobar.yaml b/examples/tls-termination/haproxy/ingress-tls-foobar.yaml index e004822f5..24cb527c7 100644 --- a/examples/tls-termination/haproxy/ingress-tls-foobar.yaml +++ b/examples/tls-termination/haproxy/ingress-tls-foobar.yaml @@ -13,5 +13,5 @@ spec: paths: - path: / backend: - serviceName: nginx + serviceName: http-svc servicePort: 80