Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for binding frontends to specific addresses #602

Closed
deuill opened this issue Oct 8, 2017 · 5 comments

Comments

Projects
None yet
2 participants
@deuill
Copy link
Contributor

commented Oct 8, 2017

This is both a question and a sort of request for help.

I'm running Kubernetes on a single-node cluster (using Minikube) as a means of better orchestrating deployments, and have been trying to integrate Voyager as an ingress for both HTTP and TCP services. My use-case is fairly peculiar since I'm not running behind any kind of load-balancer, and as such am relegated to using type: HostPort (which is fine), but also I wish to segregate services types (web-related, mail, chat, etc) into separate IP addresses, of which I have a small number allocated.

To give you a better picture, I segregate services by type into different namespaces, but use Voyager as a means of handling ingress traffic and terminating TLS for all services that allow communication to the outside world. A sample Ingress deployment might look like:

apiVersion: voyager.appscode.com/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: default
  labels:
    app: voyager
  annotations:
    ingress.appscode.com/type: HostPort
spec:
  rules:
    - host: deuill.org
      http:
        address: 203.0.113.101
        paths:
          - backend:
              serviceName: deuill.web
              servicePort: 80
    - host: mail.deuill.org
      tcp:
        address: 203.0.113.102
        port: 25
        backend:
          serviceName: postfix.mail
          servicePort: 25

What I'm essentially looking for, as alluded by specifying address in the configuration above, is a way of specifying the address to bind on for the underlying HAProxy frontends. Currently, HAProxy is set to bind on all interfaces (i.e. *) and the port number specified (defaulting to 80/443 for HTTP rules).

I've been working on getting a patch here, for my use at least, but cannot seem to find a way of getting the values through.

So, a number of questions:

  • Is this a feature you'd see merging in, i.e. does it make sense as a broader solution?
  • If not, is there a better way you can see this working (network policies etc)?
  • If yes, am I missing something in my patch that would prevent these values passing through?

Thank you in advance!

@tamalsaha

This comment has been minimized.

Copy link
Member

commented Oct 8, 2017

Hi @deuill , thanks for the question. This is a feature no one has requested before. But we can support it if you have a working pr. Your pr seems ok from a quick review.

I think the address should be an array, since HAProxy can bind to multiple IPs. If the array is empty then, you can initialize it to ["*"] in the parser. Then in the templates, you just loop over the addresses. Eg; https://serverfault.com/questions/310493/haproxy-with-multiple-ip-in-one-server

I have one questions regarding validation. If a port has address defined in one Ingress rule, then do all other rules using the same port must specify some address? This needs to validated and also the parser logic needs to take this into account when merging rules (currently only looks at port #). My guess is that HAProxy can't handle 2 frontend like below in same haproxy.conf:

frontend all
  bind *:80

frontend one
  bind x.x.x.x:80
@deuill

This comment has been minimized.

Copy link
Contributor Author

commented Oct 8, 2017

Thank you for the quick reply and assistance, indeed allowing for multiple IPs and defaulting to a sane value in the code rather than relying on the template would work much better.

I initially went with naming the field externalIPs and allow an array of IP addresses, but figured this will complicate the code since HTTP ingress resources would have to be segregated among multiple dimensions. That said, I'll try to incorporate the feedback and get some tests running.

With regards to clashing frontend definitions, that's a very good observation and a case I did not think about. I agree that HAProxy will probably reject configuration like that, but I'll check nevertheless and see what the fix is.

@tamalsaha

This comment has been minimized.

Copy link
Member

commented Oct 12, 2017

@deuill, I might have an idea why the value was not showing up in template. You need to rerun the codegenerator by running the command:

./hack/codegen.sh

It uses a Docker image to generate various files.

@deuill

This comment has been minimized.

Copy link
Contributor Author

commented Oct 12, 2017

Ah, perfect, thank you! I'll check that out and see if it fixes my issues. I'm still working on getting the code in a good enough state for a PR, but will get something together ASAP.

@tamalsaha tamalsaha closed this in 7ef1565 Nov 14, 2017

@deuill

This comment has been minimized.

Copy link
Contributor Author

commented Nov 14, 2017

@tamalsaha thanks again!

tamalsaha added a commit that referenced this issue Dec 13, 2017

Allow for binding HTTP or TCP ingress rules to specific addresses
Currently, Voyager will allow (or enforce, in the case of TCP rules) specifying a specific port to
expose services against, regardless of their internal service port. This commit extends this
functionality by allowing for specifying an optional bind address (IPv4 or IPv6), which defaults to
a wildcard ('*'), which binds to all available addresses.

An example 'Ingress' definition might look like:

	apiVersion: voyager.appscode.com/v1beta1
	kind: Ingress
	metadata:
	  name: ingress
	  namespace: default
	  labels:
		app: voyager
	  annotations:
		ingress.appscode.com/type: HostPort
	spec:
	  rules:
		- host: deuill.org
		  http:
			address: 203.0.113.101
			paths:
			  - backend:
				  serviceName: deuill.web
				  servicePort: 80
		- host: mail.deuill.org
		  tcp:
			address: 203.0.113.102
			port: 25
			backend:
			  serviceName: postfix.mail
			  servicePort: 25

Noted that wildcard and non-wildcard rules cannot be mixed for the same external port number, due to
how the underlying HAProxy configuration is set up. This essentially means that, if you have a
single HTTP host binding to a specific address, all other HTTP hosts must specify an address as
well.

Closes: #602
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.