
This document will describe a simple and common resource configuration. We'll configure a Active/Passive configuration that makes an apache2 service highly available on a shared IP. The configuration will also monitor these resources. For simplicity, the resources will be in a group. We will also try to explain our configuration and other possibilities in a short and clear way.
The configuration below excluded you also need to configure your authkeys[1] and ha.cf[2] to have a complete heartbeat configuration. There is a screencast describing doing this.
mars and venus will be the two nodes I'll be using in this example. mars being the primary (preferred) node for running Apache and venus the secondary or backup node.
As I said before this file only explains the resource configuration in heartbeat v2. The config file is located at /var/lib/heartbeat/crm/cib.xml. Basically this file specifies the resource(s) for the cluster and where this resource should be executed.
There are 4 ways you can create this file:
Create it using admintools[3], found in /usr/lib/heartbeat.
Create it using the GUI[4]
In this example we will create the configuration file using the python-convert script, since this is the fastest way. So first we need to make an haresources file.
vi /root/haresources.temp
mars 10.0.200.30/16/eth0 apache2
convert the file to HAv2 style:
Version 2.0.2 and earlier:
python /usr/lib/heartbeat/cts/haresources2cib.py /root/haresources.temp > /var/lib/heartbeat/crm/cib.xml
Later releases:
python /usr/lib/heartbeat/haresources2cib.py /root/haresources.temp # (this will create the /var/lib/heartbeat/crm/cib.xml file)
This is what the python script will generate for us:
<?xml version="1.0" ?>
<cib>
<configuration>
<crm_config>
<nvpair id="transition_idle_timeout" name="transition_idle_timeout" value="120s"/>
<nvpair id="symmetric_cluster" name="symmetric_cluster" value="true"/>
<nvpair id="no_quorum_policy" name="no_quorum_policy" value="stop"/>
</crm_config>
<nodes/>
<resources>
<group id="group_1">
<primitive class="ocf" id="IPaddr_1" provider="heartbeat" type="IPaddr">
<operations>
<op id="1" interval="5s" name="monitor" timeout="5s"/>
</operations>
<instance_attributes>u
<attributes>
<nvpair name="ip" value="10.0.200.30"/>
<nvpair name="netmask" value="16"/>
<nvpair name="nic" value="eth0"/>
</attributes>
</instance_attributes>
</primitive>
<primitive class="ocf" id="apache2id" provider="heartbeat" type="apache2">
<operations>
<op id="3" name="monitor" interval="10s" timeout="10s"/>
</operations>
</primitive>
</group>
</resources>
<constraints>
<rsc_location id="rsc_location_group_1" rsc="group_1">
<rule id="prefered_location_group_1" score="100">
<expression attribute="#uname" operation="eq" value="mars"/>
</rule>
</rsc_location>
</constraints>
</configuration>
<status/>
</cib>
<cib>
<configuration>
<crm_config/>
<nodes/>
<resources/>
<constraints/>
</configuration>
<status/>
</cib>
As you can see, the CIB[5] is broken primarily into 2 parts:
configuration: Where you configure everything about resources.
status: You should never need to touch the status portion, however you can read more about it here: ClusterInformationBase/UnderstandingStatus[6].
crm_config is where you define general resource options.
The configuration I have in my example was generated by the python convert script[7]. you don't have to configure anything in de crm_config, because the default values are not bad. But If you want to know more, tweak heartbeat or you are using STONITH have a look at this[8].
Defines which nodes are part of the cluster.
The nodes section can be mostly ignored as it will be filled in automatically by the system. It is usually best to allow this to happen automatically as the most important value is the UUID of the node which can be easy to get wrong. I want to know more[9]
Defines the resources you will be using, in this tag you also configure your monitors and give some needed parameters to the resources.
Defining which resources you want to use in heartbeat is an important part of configuring heartbeat. There are 2 way's you can define these resources. you can put several resources in a resourcegroup, and even define more than one resourcegroup. It is also possible to define the resources separate without a group. But if you do, you'll have to define for each resource on which node it has to start. So it will result in a more complicated constrain defenition. This is why we will use a group because it is much easier if you want to start and stop a bunch of resources sequential.
Note: There is also a way to group nodes, this is done using UsingAttributes [10] This is usefull if you have more than 2 nodes.
<resources>
<group id="group_1">
<primitive class="ocf" id="IPaddr_1" provider="heartbeat" type="IPaddr">
<operations>
<op id="1" interval="5s" name="monitor" timeout="5s"/>
</operations>
<instance_attributes>
<attributes>
<nvpair name="ip" value="10.0.200.30"/>
<nvpair name="netmask" value="16"/>
<nvpair name="nic" value="eth0"/>
</attributes>
</instance_attributes>
</primitive>
<primitive class="ocf" id="apache2id" provider="heartbeat" type="apache">
<operations>
<op id="3" name="monitor" interval="10s" timeout="10s"/>
</operations>
</primitive>
</group>
</resources>
resource |
Here you define your resources ofcourse. |
group |
Can be the child of the resource tag. |
primitive |
Defines a resource, if you want to use groups put this tag as a child of the group, otherwise as a child of a resource. |
operations |
Optional child tag of primitive, here you define start, stop timeouts and monitors. more info[11] |
attribute |
Child of primitive tag, defines optional or required settings of the resource. |
The attributes:
the resource part in my example explained:
Basicly, this is where you define which resource should start on which node.
In our example this is simple:
<constraints>
<rsc_location id="rsc_location_group_1" rsc="group_1">
<rule id="prefered_location_group_1" score="100">
<expression attribute="#uname" operation="eq" value="mars"/>
</rule>
</rsc_location>
</constraints>
In rsc_location you say with rsc "this group(group_1)". And in expression you define on wich node it should start first.
If you have only two node this is very simple then it runs on one node and if it fails it runs on the other. But if you have al large cluster it is better to specify where a resource should be running.
Constraints has much more possibilities, These however will be explained in other documents.
A Basic Single IP Address Configuration[15] (newbies start here)
Two Apache Web Servers in an Active/Active Configuration[18]
Other simple examples[19] are also available.
| [1] | http://www.linux-ha.org/authkeys |
| [2] | http://www.linux-ha.org/ha.cf |
| [3] | http://www.linux-ha.org/v2/AdminTools |
| [4] | http://www.linux-ha.org/GuiGuide |
| [5] | http://www.linux-ha.org/CIB |
| [6] | http://www.linux-ha.org/ClusterInformationBase/UnderstandingStatus |
| [7] | http://www.linux-ha.org/ClusterInformationBase/Conversion |
| [8] | http://www.linux-ha.org/ClusterResourceManager/DTD1.0/Annotated#crm_config |
| [9] | http://www.linux-ha.org/ClusterResourceManager/DTD1.0/Annotated#node |
| [10] | http://www.linux-ha.org/ClusterInformationBase/UsingAttributes |
| [11] | http://www.linux-ha.org/ClusterInformationBase/Actions |
| [12] | http://www.linux-ha.org/ClusterResourceManager/DTD1.0/Annotated#resource |
| [13] | http://www.linux-ha.org/ClusterResourceManager/DTD1.0/Annotated#constraint |
| [14] | http://www.linux-ha.org/v2/Examples/Advanced |
| [15] | http://www.linux-ha.org/GettingStartedV2/OneIPAddress |
| [16] | http://www.linux-ha.org/GettingStartedV2/TwoIPaddresses |
| [17] | http://www.linux-ha.org/GettingStartedV2/Apache |
| [18] | http://www.linux-ha.org/GettingStartedV2/TwoApaches |
| [19] | http://www.linux-ha.org/ClusterInformationBase/SimpleExamples |
This information provided courtesy of the Linux-HA project at http://linux-ha.org/