e911f3f2d2
The HTTP keepalive mode is currently hardcoded to "http-server-close" for all HTTP services. This disables keepalive for HAProxy to backend connections, but leaves it enabled for client connections to HAProxy. This is problematic especially for service to service calls (e.g. nova-api to neutron). If a request is made at the same time the HAProxy keepalive timeout expires, the result of the request is undefined. This leads to code 500 error responses from the nova-api because the request from nova-api to neutron failed. "Connection aborted" error messages in the logs are an indication of this issue. There is also a bug report[1] about the same issue in devstack which was solved by disabling keepalive and a script[2] to reproduce the issue in devstack. This adds a default and per service variables to set the HTTP keepalive mode used by HAProxy. The default value is changed to "forceclose" to disable HTTP keepalive on the server and client side. With HTTP keepalive disabled the issue can no longer be reproduced. [1] https://bugs.launchpad.net/devstack/+bug/1630664 [2] https://github.com/JordanP/openstack-snippets/blob/master/keepalive-race/keep-alive-race.py Change-Id: If819912873270f0568974925490023310f9cbd66
169 lines
6.8 KiB
Django/Jinja
169 lines
6.8 KiB
Django/Jinja
# {{ ansible_managed }}
|
|
|
|
{% set request_option = item.service.haproxy_balance_type | default("http") -%}
|
|
{% if item.service.haproxy_backend_port is not defined %}
|
|
{% set haproxy_backend_port = item.service.haproxy_port %}
|
|
{% else %}
|
|
{% set haproxy_backend_port = item.service.haproxy_backend_port %}
|
|
{% endif -%}
|
|
{% if item.service.haproxy_check_port is not defined %}
|
|
{% set haproxy_check_port = haproxy_backend_port %}
|
|
{% else %}
|
|
{% set haproxy_check_port = item.service.haproxy_check_port %}
|
|
{% endif -%}
|
|
|
|
{% set vip_binds = [external_lb_vip_address] -%}
|
|
{%- if internal_lb_vip_address not in vip_binds %}
|
|
{% set _ = vip_binds.append(internal_lb_vip_address) %}
|
|
{% endif -%}
|
|
|
|
{%- if extra_lb_vip_addresses is defined %}
|
|
{% for vip_address in extra_lb_vip_addresses %}
|
|
{% set _ = vip_binds.append(vip_address) %}
|
|
{% endfor %}
|
|
{% endif -%}
|
|
|
|
{%- if item.service.haproxy_bind is defined %}
|
|
{% set vip_binds = item.service.haproxy_bind %}
|
|
{% endif -%}
|
|
|
|
{% for vip_bind in vip_binds %}
|
|
{% if item.service.haproxy_redirect_http_port is defined and item.service.haproxy_ssl %}
|
|
{% if (loop.index == 1 or item.service.haproxy_ssl_all_vips | default(false) | bool) %}
|
|
|
|
frontend {{ item.service.haproxy_service_name }}-redirect-front-{{ loop.index }}
|
|
bind {{ vip_bind }}:{{ item.service.haproxy_redirect_http_port }}
|
|
mode http
|
|
redirect scheme https if !{ ssl_fc }
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
frontend {{ item.service.haproxy_service_name }}-front-{{ loop.index }}
|
|
bind {{ vip_bind }}:{{ item.service.haproxy_port }} {% if (item.service.haproxy_ssl | default(false) | bool) and (loop.index == 1 or item.service.haproxy_ssl_all_vips | default(false) | bool) %}ssl crt {{ haproxy_ssl_pem }} ciphers {{ haproxy_ssl_cipher_suite }}{% endif %}
|
|
|
|
{% if request_option == "http" %}
|
|
option httplog
|
|
option forwardfor except 127.0.0.0/8
|
|
{% if item.service.haproxy_http_keepalive_mode is defined %}
|
|
option {{ item.service.haproxy_http_keepalive_mode }}
|
|
{% endif %}
|
|
{% elif request_option == "tcp" %}
|
|
option tcplog
|
|
{% endif %}
|
|
{% if item.service.haproxy_timeout_client is defined %}
|
|
timeout client {{ item.service.haproxy_timeout_client }}
|
|
{% endif %}
|
|
{% if item.service.haproxy_whitelist_networks is defined %}
|
|
acl white_list src 127.0.0.1/8 {{ item.service.haproxy_whitelist_networks | join(' ') }}
|
|
tcp-request content accept if white_list
|
|
tcp-request content reject
|
|
{% endif %}
|
|
{% if item.service.haproxy_acls is defined %}
|
|
{% for key, value in item.service.haproxy_acls.items() %}
|
|
acl {{ key }} {{ value.rule }}
|
|
use_backend {{ value.backend_name | default(item.service.haproxy_service_name) }}-back if {{ key }}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% if (item.service.haproxy_ssl | default(false) | bool) and request_option == 'http' and (loop.index == 1 or item.service.haproxy_ssl_all_vips | default(false) | bool) %}
|
|
reqadd X-Forwarded-Proto:\ https
|
|
{% endif %}
|
|
mode {{ item.service.haproxy_balance_type }}
|
|
default_backend {{ item.service.haproxy_service_name }}-back
|
|
{% endfor %}
|
|
|
|
{% set backend_options = item.service.haproxy_backend_options|default([]) %}
|
|
{% set backend_arguments = item.service.haproxy_backend_arguments|default([]) %}
|
|
|
|
backend {{ item.service.haproxy_service_name }}-back
|
|
mode {{ item.service.haproxy_balance_type }}
|
|
balance {{ item.service.haproxy_balance_alg|default("leastconn") }}
|
|
{% if item.service.haproxy_timeout_server is defined %}
|
|
timeout server {{ item.service.haproxy_timeout_server }}
|
|
{% endif %}
|
|
stick store-request src
|
|
stick-table type ip size 256k expire 30m
|
|
{% if request_option == "http" %}
|
|
option forwardfor
|
|
option httplog
|
|
{% elif request_option == "tcp" %}
|
|
option tcplog
|
|
{% endif %}
|
|
{% for option in backend_options %}
|
|
option {{ option }}
|
|
{% endfor %}
|
|
{% for argument in backend_arguments %}
|
|
{{ argument }}
|
|
{% endfor %}
|
|
{% set backend_httpcheck_options = item.service.haproxy_backend_httpcheck_options|default([]) %}
|
|
{% for option in backend_httpcheck_options %}
|
|
http-check {{ option }}
|
|
{% endfor %}
|
|
|
|
|
|
{% for host_name in item.service.haproxy_backend_nodes %}
|
|
{% if hostvars[host_name] is defined %}
|
|
{% set ip_addr = hostvars[host_name]['ansible_host'] %}
|
|
{% endif %}
|
|
{% set entry = [] %}
|
|
{% set _ = entry.append("server") %}
|
|
{% set _ = entry.append((host_name.name | default(host_name)) | string) %}
|
|
{% set _ = entry.append((host_name.ip_addr | default(ip_addr)) + ":" + haproxy_backend_port | string) %}
|
|
{% set _ = entry.append("check") %}
|
|
{% set _ = entry.append("port") %}
|
|
{% set _ = entry.append(haproxy_check_port | string) %}
|
|
{% set _ = entry.append("inter") %}
|
|
{% set _ = entry.append(haproxy_interval | string) %}
|
|
{% set _ = entry.append("rise") %}
|
|
{% set _ = entry.append(item.service.backend_rise|default(item.service.haproxy_backend_nodes | count | string)) %}
|
|
{% set _ = entry.append("fall") %}
|
|
{% set _ = entry.append(item.service.backend_fall|default(item.service.haproxy_backend_nodes | count | string)) %}
|
|
{% if item.service.haproxy_backend_ssl | default(False) %}
|
|
{% set _ = entry.append("ssl") %}
|
|
{% if item.service.haproxy_backend_ca %}
|
|
{% set _ = entry.append("ca-file") %}
|
|
{% set _ = entry.append(item.service.haproxy_backend_ca) %}
|
|
{% else %}
|
|
{% set _ = entry.append("verify none") %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% set backend_server_options = item.service.haproxy_backend_server_options|default([]) %}
|
|
{% for option in backend_server_options %}
|
|
{% set _ = entry.append(option) %}
|
|
{% endfor %}
|
|
{{ entry | join(' ') }}
|
|
{% endfor %}
|
|
|
|
{% for host_name in item.service.haproxy_backup_nodes|default([]) %}
|
|
{% if hostvars[host_name] is defined %}
|
|
{% set ip_addr = hostvars[host_name]['ansible_host'] %}
|
|
{% endif %}
|
|
{% set entry = [] %}
|
|
{% set _ = entry.append("server") %}
|
|
{% set _ = entry.append((host_name.name | default(host_name)) | string) %}
|
|
{% set _ = entry.append((host_name.ip_addr | default(ip_addr)) + ":" + haproxy_backend_port | string) %}
|
|
{% set _ = entry.append("check") %}
|
|
{% set _ = entry.append("port") %}
|
|
{% set _ = entry.append(haproxy_check_port | string) %}
|
|
{% set _ = entry.append("inter") %}
|
|
{% set _ = entry.append(haproxy_interval | string) %}
|
|
{% set _ = entry.append("rise") %}
|
|
{% set _ = entry.append(item.service.backup_rise|default(item.service.haproxy_backup_nodes | count | string)) %}
|
|
{% set _ = entry.append("fall") %}
|
|
{% set _ = entry.append(item.service.backup_fall|default(item.service.haproxy_backup_nodes | count | string)) %}
|
|
{% set _ = entry.append("backup") %}
|
|
{% if item.service.haproxy_backend_ssl | default(False) %}
|
|
{% set _ = entry.append("ssl") %}
|
|
{% if item.service.haproxy_backend_ca %}
|
|
{% set _ = entry.append("ca-file") %}
|
|
{% set _ = entry.append(item.service.haproxy_backend_ca) %}
|
|
{% else %}
|
|
{% set _ = entry.append("verify none") %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% set backend_server_options = item.service.haproxy_backend_server_options|default([]) %}
|
|
{% for option in backend_server_options %}
|
|
{% set _ = entry.append(option) %}
|
|
{% endfor %}
|
|
{{ entry | join(' ') }}
|
|
{% endfor %}
|