Sunday, July 15, 2012

WSO2 Autoscaler Service - Part I




What is WSO2 Autoscaler Service?


Autoscaler Service API provides a way for a service consumer, to communicate with an underlying Infrastructure which are supported by JClouds. As of first implementation of Autoscaler Service, WSO2 supports infrastructures, namely Amazon EC2 and Openstack-nova LXC.

Main purpose of writing WSO2 Autoscaler Service is to support autoscaling of WSO2 products/services via WSO2 Elastic Load Balancer's autoscaler task. If I am to brief about WSO2 Elastic Load Balancer's autoscaler task, you could think it as a simple task which runs periodically and decides whether it needs to scale up/down, products'/services' instances based on some algorithm. When the autoscaler task decides that it wants to scale up/down, it will call WSO2 Autoscaler Service.

Following image depicts the high level architecture of WSO2 Autoscaler Service.




ServiceProcessor: Here lies the main control unit of the Autoscaler Service. It is responsible for handling implementation of each service operation.

Parser: This unit is responsible for parsing the “elastic-scaler-config.xml” file and creating an object model of the configuration file.

IaaSContextBuilder: This unit make use of the object model built by the Parser and create a list of IaaSContext objects. An IaaSContext object holds all the run-time data, as well as objects needed to communicate with the JClouds API.

Persister: This unit is responsible for serializing IaaSContext objects, persisting them and also de-serializing them when needed.

JClouds API: ServiceProcessor will call Jclouds API for different service operations, using IaaSContext objects.

Abbreviations:

IaaS: Infrastructure as a Service

How to use WSO2 Autoscaler Service?


WSO2 Autoscaler Service API provides few useful methods for you to get use of. Before going to details on those methods, I would like to present you with a sample configuration file, used by Autoscaler Service, named as “elastic-scaler-config.xml” in this part-I post.

<elasticScalerConfig xmlns:svns="http://org.wso2.securevault/configuration">

<svns:secureVault provider="org.wso2.securevault.secret.handler.SecretManagerSecretCallbackHandler"/>

  <!-- default directory would be ${CARBON_HOME}/tmp -->
  <serializationDir>/xx/y</serializationDir>

 <iaasProviders>
 <!-- List all IaaS Providers here.-->

  <iaasProvider type="ec2">
   <provider>aws-ec2</provider>
   <identity svns:secretAlias="elastic.scaler.ec2.identity"/>
   <credential svns:secretAlias="elastic.scaler.ec2.credential"/>
   <scaleUpOrder>1</scaleUpOrder>
   <scaleDownOrder>2</scaleDownOrder>
   <imageId>us-east-1/ami-abc</imageId> 
   <property name="jclouds.ec2.ami-query" value="owner-id=xxxx-xxxx-xxxx;state=available;image-type=machine"/>
   <property name="jclouds.endpoint" value="http://a.b.c.d/"/>
  </iaasProvider>
  
  <iaasProvider>...... </iaasProvider>

 </iaasProviders>
 
 <services>
 <!-- List details specific to service domains. -->

  <default>
   <property name="availabilityZone" value="us-east-1c"/>
   <property name="securityGroups" value="manager,cep,mb,default"/>
   <property name="instanceType.ec2" value="m1.large"/>
   <property name="instanceType.openstack" value="1"/>
   <property name="keyPair" value="xxxx-key"/>
  </default>

  <service domain="wso2.as.domain">
   <property name="securityGroups" value="default"/>
   <property name="availabilityZone" value="us-east-1c"/>
   <property name="payload" value="resources/payload.zip"/>
  </service>
  <service domain="ec2-image">
   <property name="securityGroups" value="default"/>
   <property name="availabilityZone" value="us-east-1c"/>
   <property name="payload" value="resources/payload.zip"/>
  </service>
 </services>

</elasticScalerConfig>

Now, let's go through each element in elastic-scaler-config.xml and understand what they mean.

<elasticScalerConfig xmlns:svns="http://org.wso2.securevault/configuration">

This is the root element of the file, and since this file contains some secure information, we have used secure-vault, hence the name-space attribute.

<svns:secureVault provider="org.wso2.securevault.secret.handler.SecretManagerSecretCallbackHandler"/>

This element is necessary. This specifies the secure-vault provider class. For more information on Secure-vault, please refer to [1].

<serializationDir>/xx/y</serializationDir>

This element is not mandatory (0..1). If you specified a value, it will be used as the directory where we serialize the runtime data. If this element is not specified, ${CARBON_HOME}/tmp directory will be used to store serialized data objects.

<iaasProviders>

This element contains 1..n iaasProvider elements, as its children.

<iaasProvider type="ec2">

This element is responsible for describing details which are specific to an IaaS. Element has an essential attribute, called 'type', which should be an unique identifier to recognize the IaaS, described. This element can also has an attribute called 'name', which can be any string. 1..n child elements can be there for this element.

Child elements of iaasProvider element.

<provider>aws-ec2</provider>

This element is essential (1..1) and specify the standard name of the provider. In openstack case it's 'openstack-nova'.

<identity svns:secretAlias="elastic.scaler.ec2.identity"/>

This element is essential (1..1) and specify the identity key which is unique to your account and provided by the IaaS provider. In AWS EC2 case, this is called as 'AWS Access Key ID'. Note that this element is not containing a value and also it is using a secret alias. In openstack case, corresponding secret alias is 'elastic.scaler.openstack.identity'. This is because this element's value is confidential, hence should not expose in plain text.

<credential svns:secretAlias="elastic.scaler.ec2.credential"/>

This element is essential (1..1) and specify the credential key which is unique to your account and provided by the IaaS provider. In AWS EC2 case, this is called as 'AWS Secret Access Key'. Note that this element is not containing a value and also it is using a secret alias. In openstack case, corresponding secret alias is 'elastic.scaler.openstack.credential'. This is because this element's value is confidential, hence should not expose in plain text.

<scaleUpOrder>1</scaleUpOrder>

This element is essential (1..1) and has an impact on the instance start up order, when there are multiple IaaSes. When starting up a new instance, autoscaler service first goes through a scaleUpOrderList and find the IaaS which is first in the list (ascending ordered). And then try to spawn the instance there, if it failed, it will try to spawn the instance in the IaaS next in order and so on. If two IaaSes has the same value, an IaaS will be picked randomly.

<scaleDownOrder>2</scaleDownOrder>

This element is essential (1..1) and has an impact on the instance termination order, when there are multiple IaaSes. When terminating an instance, autoscaler service first goes through a scaleDownOrderList and find the IaaS which is first in the list (ascending ordered). And then try to terminate an appropriate instance there, if it failed, it will try to terminate an instance in the IaaS next in order and so on. If two IaaSes has the same value, an IaaS will be picked randomly.

<imageId>us-east-1/ami-abc</imageId>  

This is a mandatory element (1..1) which contains the information regarding the image that this instance should start upon. This image id should be a valid one which is created and stored in the relevant IaaS providers' repository. The format of this value is usually <region>/<img id=".." />. In openstack case this value usually starts with “nova/”.

<property name=".." value="..">

There can be 0..m property elements. Sample property names would be "jclouds.ec2.ami-query", “jclouds.endpoint" etc. For more information on property names, please refer to JClouds docs [2].

<services>

This element lists the service domains which you want to autoscale and the properties of them. These properties will be passed to the underline IaaS providers. Then the newly spawned instance will be in compliance with those properties.

Child elements of services element

<default>

You could use this element to specify properties that are common to multiple if not all service domains.

<service domain="...">

This element represents a particular service domain that you want to autoscale. Properties specified under a service element gets the precedence over the default values. That is if you have specify a property, called “abc”, with a value of “x”, under default element, and you have again specified the same property “abc” with a value of “y”, under a service element (Z), at the run-time the value of the property “abc” under the service element Z is “y”.

Properties

These properties are not IaaS specific, other than the property “instanceType”. Following table shows the properties that are used by different IaaSes that are supported by us. Table content depicts the names of the properties and their usage in each IaaS. Dash (-) means, that property is not used in corresponding IaaS.


Availability Zone
Security Groups
Instance Type
Key Pair
User Data
AWS EC2
availabilityZone
securityGroups
instanceType.ec2
keyPair
payload
Openstack- LXC
-
securityGroups
instanceType.openstack
keyPair
payload

You can specify multiple securityGroups, each should be separated by a comma. As the value of user data property, you could specify a relative path to your ZIPed data file.


As part-II of this series of posts on WSO2 Autoscaler Service, I'll present you on how to use WSO2 Secure Vault, to secure the confidential information we have in this elastic-scaler-config.xml file.



2 comments:

Nikos Maravitsas said...

Hi Nimal,

Very nice blog! Is there an email address I can contact you in private?

Nirmal Fernando said...

Hi Nikos,

Thanks for the comment, I've sent you a LinkedIn invitation.