Neutron/LBaaS/l7
Contents
L7 Switching
Background
Layer 7 switching takes its name from the OSI model, indicating that the device switches requests based on layer 7 (application) data. Layer 7 switching is also known as "request switching", "application switching", and "content based routing". A layer 7 switch presents to the outside world a "virtual server" that accepts requests on behalf of a number of servers and distributes those requests based on policies that use application data to determine which server should service which request. This allows for the application infrastructure to be specifically tuned/optimized to serve specific types of content. For example, one server can be tuned to serve only images, another for execution of server-side scripting languages like PHP and ASP, and another for static content such as HTML , CSS , and JavaScript. Unlike load balancing, layer 7 switching does not require that all servers in the pool (farm/cluster) have the same content. In fact, layer 7 switching expects that servers will have different content, thus the need to more deeply inspect requests before determining where they should be directed. Layer 7 switches are capable of directing requests based on URI, host, HTTP headers, and anything in the application message.
API Changes
CLI Example
- neutron --policy policy1 create-lb-l7policy (Create l7 policy named 'policy1' )
- neutron create-lb-l7rule rule1 --attribute-type header --attribute-name "myheader" --attribute-value "transaction[1-9]{1,4}" --action SELECT-POOL --policy policy1 (Create l7 rule named 'rule1' and associate it with the policy 'policy1' )
- neutron create-lb-l7rule rule2 --attribute-type path --attribute-value "/shopping/.*" --action SELECT-POOL --policy p1 Create l7 rule named 'rule2' and associate it with the policy 'policy1' )
- neutron create-lb-pool pool1 ..... ( Create pool)
- neutron create-lb-vip .vip1 ...... ( Create vip )
- neutron associate-lb-vip-pool --vip vip1 --pool pool1 --l7policy policy1 ( Associate the vip and the pool to 'policy1' )
Model
class L7Rule { enum Type [Hostname, Path, File Type, Header, Cookie], String Name, enum Compare Type [regext], String Value, String SelectedPool }
Example: L7Rule(Type=Hostname,Name='finance_rule',CompareType=regext,value='.*finance.* ', SelectedPool='FinancePool')
class L7Policy { collection of L7Rule }
SQLAlchemy
class L7Policy (Base): __tablename__ = 'l7policy' id = Column(Integer, primary_key=True) rules = relationship("L7Rule")
class L7Rule(Base): id = Column(Integer, primary_key=True) policy_id = Column(Integer, ForeignKey('l7policy.id')) # Question - Can a rule be shared among policies?
DB Migration
Implementation Plan
- neutron-server change
- db models and logic change
- lbaas plugin change
- lbaas driver change
- python-neutronclient
- horizon
HAProxy L7 Switching
HAProxy L7 Switching is based on HAProxy ACL engine.
Example 1 (blocking):
# ... some HTTP content smugling and other various things acl forbidden_hdrs hdr_cnt(host) gt 1 acl forbidden_hdrs hdr_cnt(content-length) gt 1 acl forbidden_hdrs hdr_val(content-length) lt 0 acl forbidden_hdrs hdr_cnt(proxy-authorization) gt 0 block if forbidden_hdrs
Example 2 (switching - switch to the pool(backend) named 'www2' if 'host_www2' is true ):
acl host_www2 hdr_beg(host) -i www2. use_backend www2 if host_www2