Starting from the Q4‘18 MCP version, Horizon works in the load balancing mode by default. All requests to Horizon are terminated and forwarded to the Horizon back end by HAProxy bound on a virtual IP address. HAProxy serves as a balancer and manages requests according to the defined policy, which is round-robin by default, among proxy nodes. This approach allows for load reduction on one proxy node and spreading the load among all proxy nodes.
Note
If the node, which the user is connected to, has failed and the
user is reconnected to another node, the user will be logged out
from the dashboard. As a result, the The user is not authorized
page
opens, which is the expected behavior in this use case. To continue
working with the dashboard, the user has to sign in to Horizon again from
the Log In page.
This section provides the instruction on how to manually configure Horizon load balancing for the existing OpenStack deployments that are based on earlier MCP release versions.
To enable active-active mode for Horizon:
Log in to the Salt Master node.
Update to the 2019.2.0 Build ID MCP version or higher.
Verify that the system.apache.server.site.horizon
class has been added
to your Reclass model. By default, the class is defined in the
./system/apache/server/site/horizon.yml
file
on the Reclass system level as follows:
parameters:
_param:
apache_ssl:
enabled: false
apache_horizon_ssl: ${_param:apache_ssl}
apache_horizon_api_address: ${_param:horizon_server_bind_address}
apache_horizon_api_host: ${linux:network:fqdn}
apache:
server:
bind:
listen_default_ports: false
enabled: true
default_mpm: event
modules:
- wsgi
site:
horizon:
enabled: false
available: true
type: wsgi
name: openstack_web
ssl: ${_param:apache_horizon_ssl}
wsgi:
daemon_process: horizon
processes: 3
threads: 10
user: horizon
group: horizon
display_name: '%{GROUP}'
script_alias: '/ /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi'
application_group: '%{GLOBAL}'
authorization: 'On'
limits:
request_body: 0
host:
address: ${_param:apache_horizon_api_address}
name: ${_param:apache_horizon_api_host}
port: 8078
locations:
- uri: /static
path: /usr/share/openstack-dashboard/static
directories:
dashboard_static:
path: /usr/share/openstack-dashboard/static
order: 'allow,deny'
allow: 'from all'
modules:
mod_expires.c:
ExpiresActive: 'On'
ExpiresDefault: '"access 6 month"'
mod_deflate.c:
SetOutputFilter: 'DEFLATE'
dashboard_wsgi:
path: /usr/share/openstack-dashboard/openstack_dashboard/wsgi
order: 'allow,deny'
allow: 'from all'
log:
custom:
format: >-
%v:%p %{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %D %O \"%{Referer}i\" \"%{User-Agent}i\"
error:
enabled: true
level: debug
format: '%M'
file: '/var/log/apache2/openstack_dashboard_error.log'
Verify that the system.apache.server.site.horizon
has been added to the
Reclass system level in the ./system/horizon/server/single.yml
file
as follows:
classes:
- service.horizon.server.single
- system.horizon.upgrade
- system.horizon.server.iptables
- system.apache.server.single
- system.memcached.server.single
- system.apache.server.site.horizon
Verify that the definition for the
system.haproxy.proxy.listen.openstack.openstack_web
class has been
added to the Reclass cluster level in the in the proxy nodes configuration
file:
parameters:
_param:
haproxy_openstack_web_check_params: check
haproxy:
proxy:
listen:
openstack_web:
type: custom
check: false
sticks: ${_param:haproxy_openstack_web_sticks_params}
binds:
- address: ${_param:cluster_vip_address}
port: ${_param:haproxy_openstack_web_bind_port}
servers:
- name: ${_param:cluster_node01_hostname}
host: ${_param:cluster_node01_address}
port: 8078
params: ${_param:haproxy_openstack_web_check_params}
- name: ${_param:cluster_node02_hostname}
host: ${_param:cluster_node02_address}
port: 8078
params: ${_param:haproxy_openstack_web_check_params}
Add the system.haproxy.proxy.listen.openstack.openstack_web
class to
the Horizon node configuration file, for example,
cluster/<cluster_name>/openstack/dashboard.yml
:
classes:
- system.haproxy.proxy.listen.openstack.openstack_web
In the Horizon node configuration file (edited in the previous step), define the host names and IP addresses for all proxy nodes used in the deployment for the dashboard node and verify that the HAProxy checks the availability of Horizon.
Congifuration example for two proxy nodes:
parameters:
_param:
cluster_node01_hostname: ${_param:openstack_proxy_node01_hostname}
cluster_node01_address: ${_param:openstack_proxy_node01_address}
cluster_node02_hostname: ${_param:openstack_proxy_node02_hostname}
cluster_node02_address: ${_param:openstack_proxy_node02_address}
haproxy_openstack_web_bind_port: ${_param:horizon_public_port}
haproxy_openstack_web_check_params: check inter 10s fastinter 2s downinter 3s rise 3 fall 3 check-ssl verify none
horizon:
server:
cache:
~members:
- host: ${_param:openstack_proxy_node01_address}
port: 11211
- host: ${_param:openstack_proxy_node02_address}
port: 11211
If the HTTP to HTTPS redirection will be used, add the following configuration to the Horizon node configuration file:
parameters:
haproxy:
proxy:
listen:
openstack_web_proxy:
mode: http
format: end
force_ssl: true
binds:
- address: ${_param:cluster_vip_address}
port: 80
Disable the NGINX servers requests for Horizon by replacing the NGINX class with the HAProxy class in the proxy node configuration file.
Replace:
- system.nginx.server.proxy.openstack_web
with
- system.haproxy.proxy.single
Remove the nginx_redirect_openstack_web_redirect.conf
and
nginx_proxy_openstack_web.conf
Horizon sites from
/etc/nginx/sites-enabled/
.
Restart the NGINX service on the proxy nodes:
salt 'prx*' cmd.run 'systemctl restart nginx'
Verify that Keepalived keeps track on HAProxy by adding the haproxy
variable for the keepalived_vrrp_script_check_multiple_processes
parameter:
parameters:
_param:
keepalived_vrrp_script_check_multiple_processes: 'nginx haproxy'
Enable SSL for Horizon:
parameters:
_param:
apache_ssl:
enabled: true
authority: ${_param:salt_minion_ca_authority}
engine: salt
key_file: /srv/salt/pki/${_param:cluster_name}/${salt:minion:cert:proxy:common_name}.key
cert_file: /srv/salt/pki/${_param:cluster_name}/${salt:minion:cert:proxy:common_name}.crt
chain_file: /srv/salt/pki/${_param:cluster_name}/${salt:minion:cert:proxy:common_name}-with-chain.crt
Define the address to be bound by Memcached in the
cluster/<cluster_name>/openstack/proxy.yml
file:
parameters:
_param:
openstack_memcached_server_bind_address: ${_param:single_address}
Verify that the Horizon Salt formula is updated to the the version higher
than 2016.12.1+201812072002.e40b950
and the Apache Salt formula is
updated to the version higher than 0.2+201811301717.acb3391
.
Delete the NGINX sites from the proxy nodes that proxy Horizon requests and possible redirection from HTTP to HTTPS.
Apply the haproxy and horizon states on the proxy nodes:
salt -C 'I@horizon:server' state.sls horizon
salt -C 'I@horizon:server' state.sls haproxy