[openstack-dev] [Neutron][LBaaS]L7 conent switching APIs

Stephen Balukoff sbalukoff at bluebox.net
Fri May 2 22:32:54 UTC 2014


Hi Adam and Samuel!

Thanks for the questions / comments! Reactions in-line:


On Thu, May 1, 2014 at 8:14 PM, Adam Harwell <adam.harwell at rackspace.com>wrote:
>
>     Stephen, the way I understood your API proposal, I thought you could
> essentially combine L7Rules in an L7Policy, and have multiple L7Policies,
> implying that the L7Rules would use AND style combination, while the
> L7Policies themselves would use OR combination (I think I said that right,
> almost seems like a tongue-twister while I'm running on pure caffeine). So,
> if I said:
>

Well, my goal wasn't to create a whole DSL for this (or anything much
resembling this) because:

   1. Real-world usage of the L7 stuff is generally pretty primitive. Most
   L7Policies will consist of 1 rule. Those that consist of more than one rule
   are almost always the sort that need a simple sort. This is based off the
   usage data collected here (which admittedly only has Blue Box's data--
   because apparently nobody else even offers L7 right now?)
   https://docs.google.com/spreadsheet/ccc?key=0Ar1FuMFYRhgadDVXZ25NM2NfbGtLTkR0TDFNUWJQUWc&usp=sharing
   2. I was trying to keep things as simple as possible to make it easier
   for load balancer vendors to support. (That is to say, I wouldn't expect
   all vendors to provide the same kind of functionality as HAProxy ACLs, for
   example.)

Having said this, I think yours and Sam's clarification that different
L7Policies can be used to effective "OR" conditions together makes sense,
and therefore assuming all the Rules in a given policy are ANDed together
makes sense.

If we do this, it therefore also might make sense to expose other criteria
on which L7Rules can be made, like HTTP method used for the request and
whatnot.

Also, should we introduce a flag to say whether a given Rule's condition
should be negated?  (eg. "HTTP method is GET and URL is *not* "/api") This
would get us closer to being able to use more sophisticated logic for L7
routing.

Does anyone foresee the need to offer this kind of functionality?

  * The policy { rules: [ rule1: match path REGEX ".*index.*", rule2: match
> path REGEX "hello/.*" ] } directs to Pool A
>  * The policy { rules: [ rule1: match hostname EQ "mysite.com" ] }
> directs to Pool B
> then order would matter for the policies themselves. In this case, if they
> ran in the order I listed, it would match "mysite.com/hello/index.htm"
> and direct it to Pool A, while "mysite.com/hello/nope.htm" would not
> match BOTH rules in the first policy, and would be caught by the second
> policy, directing it to Pool B. If I had wanted the first policy to use OR
> logic, I would have just specified two separate policies both pointing to
> Pool A:
>

Clarification on this: There is an 'order' attribute to L7Policies. :) But
again, if all the L7Rules in a given policy are ANDed together, then order
doesn't matter within the rules that make up an L7Policy.


>   * The policy { rules: [ rule1: match path REGEX ".*index.*" ] } directs
> to Pool A
>  * The policy { rules: [ rule1: match path REGEX "hello/.*" ] } directs to
> Pool A
>  * The policy { rules: [ rule1: match hostname EQ "mysite.com" ] }
> directs to Pool B
>  In that case, it would match "mysite.com/hello/nope.htm" on the second
> policy, still directing to Pool A.
> In both cases, "mysite.com/hi/" would only be caught by the last policy,
> directing to Pool B.
> Maybe I was making some crazy jumps of logic, and that's not how you
> intended it? That said, even if that wasn't your intention, could it work
> that way? It seems like that allows a decent amount of options… :)
>
>       --Adam
>



 On Fri, May 2, 2014 at 4:59 AM, Samuel Bercovici <SamuelB at radware.com>
 wrote:

> Adam, you are correct to show why order matters in policies.
> It is a good point to consider AND between rules.
> If you really want to OR rules you can use different policies.
>
> Stephen, the need for order contradicts using content modification with
> the same API since for modification you would really want to evaluate the
> whole list.
>

Hi Sam, I was a bit confused on this point since we don't see users often
using both content modification and content switching in the same
configuration. However, checking the haproxy manual regarding content
modification rules:

  - req* statements are applied after "block" statements, so that "block" is
    always the first one, but before "use_backend" in order to permit rewriting
    before switching.

And this in the 'use_backend' definition having to do with switching based
on L7 content:

There may be as many "use_backend" rules as desired. All of these rules are
  evaluated in their declaration order, and the first one which matches will
  assign the backend.


If this is true, this seem to imply that for HAProxy at least, order only
really matters for policies which switch back-ends. That is to say, all the
'block' policies get processed first, followed by all the content
modification policies, followed by the switching policies. If you have two
conflicting content modification policies, what actually happens isn't
defined in the manual (though again-- why would anyone do this? Seems like
a scenario in which users shoot themselves in the foot.)

Given this, it may make sense to enforce this order in our model somehow,
assuming other load balancer vendors would want to duplicate this behavior.
Otherwise, users might be confused why (for example) a modification rule is
applying a header to a request when that policy comes after a switching
policy in the overall list of policies. (One could do this by always
inserting new 'block' policies in order before any 'modification' policies,
and 'modification' policies before any 'redirect' policies, and not
allowing any API updates to move any rules in a way that would violate this
order.) Or, we could make that 'order' attribute only allowed (and
necessary) for 'redirect' policies-- the implication being no order applies
to block or content modification policies because they always get processed
first.

We could do this by splitting modification, block, and switching L7 policy
types into their own separate objects (all of which would have similar
'rule' semantics), but I'm really not seeing a compelling reason to do so.
 (Again, I'm usually in favor of introducing fewer new objects.)

What seems like the least confusing thing to do for the user?  What are
others' thoughts on this?

Thanks,
Stephen


-- 
Stephen Balukoff
Blue Box Group, LLC
(800)613-4305 x807
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140502/caa922af/attachment.html>


More information about the OpenStack-dev mailing list