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

Rework haproxy config for stickiness and balance strategy #179

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions chef/cookbooks/crowbar-pacemaker/recipes/haproxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
#FIXME: delete group when it's not needed anymore
#FIXME: need to find/write OCF for haproxy

# Recommendation from the OpenStack HA guide is to use "source" as balance
# algorithm. This obviously is less useful for load balancing, but we care more
# about HA and things working than about load balancing.
node.default["haproxy"]["defaults"]["balance"] = "source"

# With the default bufsize, getting a keystone PKI token from its ID doesn't
# work, because the URI path is too long for haproxy
node.default["haproxy"]["global"]["bufsize"] = 32768
Expand Down
7 changes: 7 additions & 0 deletions chef/cookbooks/haproxy/providers/loadbalancer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
else
section["mode"] = new_resource.mode
end
unless new_resource.balance.empty?
section["balance"] = new_resource.balance
end

section["stick"] = new_resource.stick
section["stick"]["expire"] ||= "30m"

section["options"] = new_resource.options || []
if section["options"].empty? || section["options"].include?("defaults")
section["options"].delete("defaults")
Expand Down
2 changes: 2 additions & 0 deletions chef/cookbooks/haproxy/resources/loadbalancer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
attribute :address, kind_of: String, default: "0.0.0.0"
attribute :port, kind_of: Integer, default: 0
attribute :mode, kind_of: String, default: "http", equal_to: ["http", "tcp", "health"]
attribute :balance, kind_of: String, default: "", equal_to: ["", "roundrobin", "static-rr", "leastconn", "first", "source"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [124/100] (https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricslinelength)

attribute :use_ssl, kind_of: [TrueClass, FalseClass], default: false
attribute :stick, kind_of: Hash, default: {}
attribute :options, kind_of: Array, default: []
attribute :servers, kind_of: Array, default: []
44 changes: 40 additions & 4 deletions chef/cookbooks/haproxy/templates/default/haproxy.cfg.erb
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,47 @@ listen admin-stats <%= node[:haproxy][:stats][:enabled] ? node[:haproxy][:stats
<% content = node[:haproxy][:sections][type][name] -%>
<%= type %> <%= name %>
bind <%= content[:address] %>:<%= content[:port] %>
<% if content[:use_ssl] -%>
mode tcp
balance source
<% else -%>
mode <%= content[:mode] %>
<% unless content[:balance].nil? -%>
balance <%= content[:balance] %>
<% end -%>

<% if content[:use_ssl] # http://blog.exceliance.fr/2011/07/04/maintain-affinity-based-on-ssl-session-id/ -%>
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 30k expire <%= content[:stick][:expire] %>

acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2

# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello

# no timeout on response inspect delay by default.
tcp-response content accept if serverhello

# SSL session ID (SSLID) may be present on a client or server hello.
# Its length is coded on 1 byte at offset 43 and its value starts
# at offset 44.
# Match and learn on request if client hello.
stick on payload_lv(43,1) if clienthello

# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
<% elsif content[:mode] == "http" && content[:stick] &&
content[:stick][:cookies] && !content[:stick][:cookies].empty?
# There are various options here, described in:
# http://stackoverflow.com/questions/27094501/haproxy-1-5-8-how-do-i-configure-cookie-based-stickiness
# We go with the stick-table to avoid no-cache and exposing backends
# through cookies.
# Note that appsession is easier, but deprecated:
# http://serverfault.com/questions/550910/haproxy-appsession-vs-cookie-precedence
-%>
stick-table type string len 64 size 100k expire <%= content[:stick][:expire] %>
<% content[:stick][:cookies].each do |cookie| -%>
stick store-response res.cook(<%= cookie %>)
stick match req.cook(<%= cookie %>)
<% end -%>
<% end -%>

<% content[:options].each do |option| -%>
Expand Down