Load balancing Abiquo 3.x UI and API using Apache
Abiquo version
This configuration is valid for Abiquo 3.x
The Abiquo API can be balanced amongst several servers to spread load and increase service capacity. As you know, Abiquo provides an HTML5 client application that runs on your browser that interacts with the API to operate the cloud.
As the UI is a regular HTML app, there may be several options to balance both the UI and the API.
Disclaimer
This document covers a setup sample for an Abiquo UI and Abiquo API balanced cluster.
- It is the user's responsibility to choose the best setup and optimize LoadBalancer configurations.
API plus UI cluster
In this setup, we are spreading the load amongst a cluster of nodes running both API and UI. Please note that any API clustered setup REQUIRES Zookeeper.
For the sake of simplicity, we are using a two node setup, but this is easily scalable to several nodes and using Apache web server as a load balancer.
Assume the following IP addressing for our cluster nodes.
Node | IP addressing | Port / Protocol |
---|---|---|
Apache LB | 10.60.13.10 | 443 |
ZooKeeper node | 10.60.13.10 | 2181 |
API node1 | 192.168.2.100 | 8010 |
UI node1 | 192.168.2.100 | 80 |
API node2 | 192.168.2.101 | 8010 |
UI node2 | 192.168.2.101 | 80 |
Installation
Start by installing backend severs using the Server profile of the Abiquo ISO installer. This profile will install API and UI webapps, as well as the Zookeeper daemon needed for API to work in a clustered configuration.
Follow instructions in Distributed Install of Abiquo Server 3.0 or Distributed Install of Abiquo Server v3.1 to get the Server profile installed.
Once you have both servers with the Server profile installed, keep in mind that you need to keep the abiquo.properties file synchronized on every node in the API cluster.
API consensus
First, for the API to function as a clustered API, you need to setup Zookeeper. You can run Zookeeper on the LoadBalancer node or on a separate box, as preferred.
Zookeeper requires JVM to run, ensure that JVM (Oracle or OpenJDK) is installed.
# java -v
The zookeeper package is installed using the "Server" profile of the Abiquo installer ISO. But if you need to install it manually, use:
# yum -y install zookeeper
Then add the following line in the [server] section of the abiquo.properties file on all Abiquo API server nodes:
abiquo.api.zk.serverConnection = <zookeeper_ip>:2181
Replace <zookeeper_ip> to match your environment. Also add or modify the abiquo.server.api.location property to match the load balancer URL for the API service (shown below):
abiquo.server.api.location = https://abiquo.example.com/api
Edit the files /opt/abiquo/tomcat/conf/Catalina/localhost/api.xml and /opt/abiquo/tomcat/conf/Catalina/localhost/m.xml and set the values for the MySQL kinton database connection. Change the url, username and password attributes to match your environment.
<Resource name="jdbc/abiquoDB" auth="Container" type="javax.sql.DataSource" initialSize="10" suspectTimeout="60" timeBetweenEvictionRunsMillis="30000" minEvictableIdleTimeMillis="60000" maxActive="100" minIdle="10" maxIdle="50" maxWait="10000" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" username="mysql_user" password="user_password" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://mysql.example.com:3306/kinton?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"/>
UI configuration
In a clustered UI setup, you will need to configure the LB as the API endpoint for each UI node. Edit /var/www/html/ui/config/client-config.json file and set the same config.endpoint property for each UI node. For example:
"config.endpoint": "https://abiquo.example.com/api"
LoadBalancer Apache node configuration
To ensure that Apache's required modules are loaded, add the following lines to your Apache config file:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
On the LoadBalancer node running Apache, create a new config file in /etc/httpd/conf.d/api-balancer.conf with the following contents:
<VirtualHost *:443> ServerName abiquo.example.com SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW SSLCertificateFile /etc/pki/tls/certs/abiquo.example.com.crt SSLCertificateKeyFile /etc/pki/tls/private/abiquo.example.com.key # Enable the balancer manager console in the server root <Location /> SetHandler balancer-manager </Location> # Configure the API AJP cluster nodes <Proxy balancer://api-cluster> BalancerMember ajp://192.168.2.100:8010 route=node1 ping=1 BalancerMember ajp://192.168.2.101:8010 route=node2 ping=1 </Proxy> # Configure the UI HTTP cluster nodes <Proxy balancer://ui-cluster> BalancerMember http://192.168.2.100 route=node1 ping=1 BalancerMember http://192.168.2.101 route=node2 ping=1 </Proxy> # Configure the modules we want to load balance ProxyPass /api/ balancer://api-cluster/api/ ProxyPass /ui/ balancer://ui-cluster/ui/ stickysession=JSESSIONID|jsessionid </VirtualHost>
Restart or reload your Apache server to apply the new configuration.
Note that this config enables Apache's balancer-manager to get information on the balancer cluster and perform basic operations on it. If you want to disable it, just comment or remove the <Location /> mark.
LoadBalancing setup
In the Apache configuration sample shown above, the LoadBalancer node also provides the SSL layer and hence, the Proxy balancing rule should be done without SSL against the UI nodes.
Abiquo API Tomcat configuration
Ensure the jvmRoute parameter is different on each host because this parameter will be used by Apache tomcat to route requests to each host.
To do this, edit the /opt/abiquo/tomcat/conf/server.xml file in the tomcat directory and modify the following values:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
You need to import the LoadBalancer's Apache SSL certificate and CA into the Java truststore to enable the API to complete SSL connections to API endpoints. If you are using a self-signed certificate for testing purposes, importing the SSL certificate will suffice. This should be done on every node running the API webapp:
# echo -n | openssl s_client -connect abiquo.example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > abiquo.example.com.cert # /usr/java/default/bin/keytool -import -file abiquo.example.com.cert -keystore /path/to/cacerts # /usr/java/default/bin/keytool -import -trustcacerts -file /path/to/ca/ca.pem -alias CA_ALIAS -keystore /path/to/cacerts
Tips
- You can easily find cacerts files by simple executing:
# find / -iname cacerts - It's highly recommended that you make a copy/backup of the cacerts file before adding/removing certificates
- Note that default password for a JVM truststore is changeit. Also note that you may need to adjust paths for both keytool command and cacerts truststore depending on your java version.
Restart tomcat after the change to apply the new configuration.
Now, access your balancer at https://abiquo.example.com/ui/ or https://abiquo.example.com/api/ . Requests between the two backend nodes will be adequately balanced.
Check the API balancing with the following curl command:
# curl -k -u admin:xabiquo --silent -X GET https://abiquo.example.com/api/login {"links":[{"title":"Abiquo","rel":"enterprise","type":"application/vnd.abiquo.enterprise+json","href":"https://abiquo.example.com:443/api/admin/enterprises/1"}, {"title":"CLOUD_ADMIN","rel":"role","type":"application/vnd.abiquo.role+json","href":"https://abiquo.example.com:443/api/admin/roles/1"}, {"title":"CLOUD_ADMIN","rel":"edit","type":"application/vnd.abiquo.user+json","href":"https://abiquo.example.com:443/api/admin/enterprises/1/users/1"}, {"title":"virtualmachines","rel":"virtualmachines","type":"application/vnd.abiquo.virtualmachines+json","href":"https://abiquo.example.com:443/api/admin/enterprises/1/users/1/action/virtualmachines"}, {"title":"pending tasks","rel":"pendingtasks","type":"application/vnd.abiquo.tasks+json","href":"https://abiquo.example.com:443/api/admin/enterprises/1/users/1/action/pendingtasks"},{"title":"applications","rel":"applications","type":"application/vnd.abiquo.applications+json","href":"https://abiquo.example.com:443/api/admin/enterprises/1/users/1/applications"}], "id":1,"name":"Cloud","nick":"admin","locale":"en_US","surname":"Administrator","active":true,"email":"","description":"Main administrator","authType":"ABIQUO"}
Make sure the href links returned by the API call point to the correct location. Otherwise, check your configuration again.
Other setups
The sample configuration described in this document covers the setup of a balanced Abiquo API and Abiquo UI cluster but you can change node distribution and LoadBalancer configuration to provide different setups depending on your requirements. For example, you may want to provide separate nodes for Abiquo UI and Abiquo API or maybe you may want just to cluster Abiquo UI and provide a single and shared Abiquo API node, etc.
Also, this sample uses Apache to provide the Load Balancing functionality but this can be achieved with other HA / Load Balancing solutions such as HAProxy or other vendor hardware / software tools.