This site best when viewed with a modern standards-compliant browser. We recommend Firefox Get Firefox!.

Linux-HA project logo
Providing Open Source High-Availability Software for Linux and other OSes since 1999.

USA Flag UK Flag

Japanese Flag

ホームページ

サイトについて

コンタクト情報

使用条件

協力方法

セキュリティ

2008.7.18
RHEL用rpm更新
更新情報はこちらから

2008.6.30
パッケージ追加
追加パッケージ集にパッケージを追加しました

2007.12.21
Heartbeat 2.1.3
リリース!
Downloadはこちらから

2007.11.13
Linux-ha-japan日本語ML移植しました

2007.10.5
日本語サイトOPEN
日本語MLも開設しました

2007.10.5
OSC2007 Tokyo/Fall で Heartbeat紹介
発表資料を公開しました

Last site update:
2008-08-20 19:10:10

Contents

  1. Introduction
  2. Extra Options
  3. Simple Example
  4. What if?
  5. FAQ
  6. Writing a Clone Resource Agent
    1. Requirements for ResourceAgents
    2. Extra Operation (notify)
    3. Extra Environment Variables
    4. Proper Interpretation of Clone Environment Variables
  7. Advanced Example
  8. Location Constraints for Clones
  9. Ordering Constraints and Clones
  10. Co-locational Constraints and Clones
  11. Finding Clones in the Status Section
Related Pages v2/Concepts v2/Concepts/MultiState

Introduction

Clones were initially conceived as a convienient way to start N instances of an IP resource and have them distributed throughout the cluster for load balancing. They have turned out to quite useful for a number of purposes including integrating with Red Hat's DLM, the fencing subsystem and OCFS2.

In fact you can clone any resource provided the ResourceAgent supports it. Like regular resources you may even have it configured differently depending on which host it is active on.

Three types of cloned resources exist.

  1. Anonymous Clones.
    • The simplest type of clones, these resources behave completely identically everywhere they are running.
  2. Globally Unique Clones.
    • These resources are distinct entities. An instance of the clone running on one machine is not equivalent to another instance on another node. Nor would any two instances on the same node be equivalent.
  3. Stateful Clones.
    • Active instances of these resources are divided into two states active and passive (aka. primary/secondary, master/slave, choose whichever term suits you). Stateful clones can be either anonymous or globally unique.

      You can read more about them here: v2/Concepts/MultiState

Extra Options

  • ordered (default: FALSE)

    • Start (or stop) each clone only after the operation on the previous clone completed.
  • interleave (default: FALSE)

    • This relates to action ordering... see "Ordering Constraints and Clones" below.
  • notify (default: FALSE)

    • Notify the an instance of the clone before and after stopping/starting its siblings.

      This requires the notify action to be implemented. See "Writing a Clone Resource Agent" for details below.

  • clone_max (default: 1)

    • The maximum number of copies of the resource that should be run in the cluster.
  • clone_node_max (default: 1)

    • The maximum number of copies of the resource that should be run on any given node.
  • globally_unique (default: TRUE)

    • Is this clone a Globally Unique Clone or not.

Simple Example

In the example below we have specified that the WebServerIP resource should be a ClusteredIP. It will be started on at most 3 nodes and at most there can be 2 clone active on any given node. Instance 1 will serve the first "bucket", instance 2 the second and so on.

  • <clone id="MyCorpWWW" ordered="false" interleave="false" notify="false">
      <instance_attributes>
        <attributes>
          <nvpair name="clone_max" value="3"/>
          <nvpair name="clone_node_max" value="2"/>
        </attributes>
      </instance_attributes>
      <primitive id="WebServerIP" class="ocf" type="IPaddr" provider="heartbeat">
        <instance_attributes>
          <attributes>
            <nvpair name="ip" value="127.0.0.26"/>
          </attributes>
        </instance_attributes>
      </primitive>
    </clone>
     

What if?

  • If there are >=3 nodes available:

    • Three nodes will be chosen and each node will run 1 clone
  • If there are 2 nodes available:
    • 1 node will run 2 clones, the other 1
  • If there is 1 nodes available:
    • 1 node will run 2 clones, the clone will not be started

FAQ

  1. Will the active clone instances always be an unbroken sequence?
    • No.
  2. Will the active clone instances always start at 0?
    • No.
  3. Start order (with ordered=false)

    • All clone instances not yet active would be started approximately at the same time.
  4. Stop order (with ordered=false)

    • All clone instances still active would be stopped approximately at the same time.
  5. Start order (with ordered=true)

    • If nothing was yet started, the order would be like this:
      1. Start WebServerIP:0

      2. Start WebServerIP:1

      3. Start WebServerIP:2

  6. Stop order (with ordered=true)

    • If all instances were active, the order would be like this:
      1. Stop WebServerIP:2

      2. Stop WebServerIP:1

      3. Stop WebServerIP:0

Writing a Clone Resource Agent

All OCF variables can normally be found in /usr/lib/ocf/resource.d/heartbeat/ocf-shellfuncs which should be the first thing included by a resource agent.

Requirements for ResourceAgents

    • Only OCF ResourceAgents are supported for cloning. This is due to the extra variables that need to be sent to the agent.

    • ResourceAgents are required to accurately report how many instances are active. In order to recover from possible failures or administrative accidents, the CRM checks for active resources (generally this is done at startup). In CRM terminology, these are called "probes" and one is sent for every possible clone instance. Probes can be recognized in shell scripts with the following code:
      [ "${__OCF_ACTION}" = "monitor" -a "${OCF_RESKEY_CRM_meta_interval}" = "0" ]

    • . For anonymous clones, the ResourceAgent must only respond with ${OCF_SUCCESS} to N of these probes. Where N is the number of active instances of the clone on that node. This is the minimum requirement but it is preferable for the ResourceAgent to act as defined for globally unique clones below.

    • . For globally unique clones, the ResourceAgent must only respond with ${OCF_SUCCESS} if the node has that exact instance active. Clone instances are identified as clone number OCF_RESKEY_CRM_meta_clone of OCF_RESKEY_CRM_meta_clone_max. These variables are available for ResourceAgents to use. All other probes for instances of the clone should result in ${OCF_NOT_RUNNING}. Unless of course they are failed, in which case they should return one of the other OCF error codes.

v2/Concepts/MultiState resources have additional requirements not discussed here.

Extra Operation (notify)

A Clone Resource Agent can optionally implement the notify operation.

Notification can be enabled by adding notify="true" to the resource's definition.

Once enabled, your resource will receive pre and post notification events telling the resource what is or did just take place. Currently these are informational updates only and are not permitted to fail. Future version may allow notify actions to fail.

Extra Environment Variables

  • OCF_RESKEY_globally_unique (default: true)

These variables are available to notify actions.

  • OCF_RESKEY_CRM_meta_notify_type (pre|post)

  • OCF_RESKEY_CRM_meta_notify_operation (start|stop)

  • OCF_RESKEY_CRM_meta_notify_{x}_resource

  • OCF_RESKEY_CRM_meta_notify_ {x}_uname

  • {x} : start, stop, active, inactive

Starting with 2.0.4, they will also be available to start and stop actions if notify="true" is set; notify_type and notify_operation is not provided there.

Proper Interpretation of Clone Environment Variables

  1. Pre-notification
    • Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource
    • Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource
    • Resources to be started: $OCF_RESKEY_CRM_meta_notify_start_resource
    • Resources to be stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource
  2. Post-notification (stop)
    • Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource
      • minus $OCF_RESKEY_notify_stop_resource

    • Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource
      • plus $OCF_RESKEY_CRM_meta_notify_stop_resource

    • Resources that were started: $OCF_RESKEY_CRM_meta_notify_start_resource
    • Resources that were stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource
  3. Post-notification (start)
    • Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource
      • minus $OCF_RESKEY_CRM_meta_notify_stop_resource
        plus $OCF_RESKEY_CRM_meta_notify_start_resource

    • Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource
      • plus $OCF_RESKEY_CRM_meta_notify_stop_resource
        minus $OCF_RESKEY_CRM_meta_notify_start_resource

    • Resources that were started: $OCF_RESKEY_CRM_meta_notify_start_resource
    • Resources that were stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource

Advanced Example

An IP address on its own isnt much use. More than likely we'd like something like an apache instance to be started as well. What we can do is define the target of the clone to be a resource group.

  • <clone id="MyCorpWWW">
      <instance_attributes>
        <attributes>
          <nvpair name="clone_max" value="3"/>
          <nvpair name="clone_node_max" value="1"/>
        </attributes>
      </instance_attributes>
      <group id="MyCorpWWW_group">
        <primitive id="WebServerIP" class="ocf" type="IPaddr" provider="heartbeat">
          <instance_attributes>
            <attributes>
              <nvpair name="ip" value="127.0.0.26"/>
            </attributes>
          </instance_attributes>
        </primitive>
        <primitive id="WebServerApache" class="ocf" type="Apache" provider="heartbeat">
          <instance_attributes>
            <attributes>
              <nvpair name="apache_config" value="/home/www.mycorp.com/conf/apache.conf"/>
            </attributes>
          </instance_attributes>
        </primitive>
      </group>
    </clone>
     

This will allocate one bucket and one apache instance to up to three nodes. If nothing was yet started and ordered=true, interleave=true, the startup order would be like this:

  1. Start WebServerIP:0

  2. Start WebServerApache:0

  3. Start WebServerIP:1

  4. Start WebServerApache:1

  5. Start WebServerIP:2

  6. Start WebServerApache:2

If instead ordered=true, interleave=false, the startup order would be like this:

  1. Start WebServerIP:0

  2. Start WebServerIP:1

  3. Start WebServerIP:2

  4. Start WebServerApache:0

  5. Start WebServerApache:1

  6. Start WebServerApache:2

Location Constraints for Clones

Using constraints for the clone as a whole is no different to a native resource... you just use the id of the group.

  • <rsc_location id="run_MyCorpWWW" rsc="MyCorpWWW">
        <rule id="pref_run_WebServerIP" score="100" boolean_op="or">
            <expression attribute="#uname" operation="eq" value="c001n01"/>
            <expression attribute="#uname" operation="eq" value="c001n02"/>
            <expression attribute="#uname" operation="eq" value="c001n03"/>
        </rule>
    </rsc_location>
     
    We specify 3 nodes since we will effectivly have 3 resources to place.

Ordering Constraints and Clones

If we defined two more resources and had one start before MyCorpWWW and one after, the results are pretty much what you would expect.

  • Example:
    <primitive id="Oracle" class="lsb" type="oracle"/>
    <primitive id="WwwStats" class="lsb" type="apache_stats"/>
    <rsc_order id="order_oracle_www" from="MyCorpWWW" action="start" type="after" to="Oracle"/>
    <rsc_order id="order_stats_www" from="MyCorpWWW" action="start" type="before" to="WwwStats"/>
     

If nothing was yet started, the order would be like this:

  1. Start Oracle

  2. Start WebServerIP:0

  3. Start WebServerApache:0

  4. Start WebServerIP:1

  5. Start WebServerApache:1

  6. Start WebServerIP:2

  7. Start WebServerApache:2

  8. Start WwwStats

and the reverse for stop.

If however, the "Oracle" resource was also a clone,

  • <clone id="Oracle">
      <instance_attributes>
        <attributes>
          <nvpair name="clone_max" value="3"/>
          <nvpair name="clone_node_max" value="1"/>
        </attributes>
      </instance_attributes>
      <primitive id="Oracle_clone" class="lsb" type="oracle"/>
    </clone>
     

the orders would be:

  1. Start Oracle_clone:0

  2. Start Oracle_clone:1

  3. Start Oracle_clone:2

  4. Start WebServerIP:0

  5. Start WebServerApache:0

  6. Start WebServerIP:1

  7. Start WebServerApache:1

  8. Start WebServerIP:2

  9. Start WebServerApache:2

  10. Start WwwStats

and the reverse for stop.

And if interleave=true was specified,

  • <clone id="Oracle_clones" interleave="true">
      <instance_attributes>
        <attributes>
          <nvpair name="clone_max" value="3"/>
          <nvpair name="clone_node_max" value="1"/>
        </attributes>
      </instance_attributes>
      <primitive id="Oracle" class="lsb" type="oracle"/>
    </clone>
     

then it would be:

  1. Start Oracle:0

  2. Start WebServerIP:0

  3. Start WebServerApache:0

  4. Start Oracle:1

  5. Start WebServerIP:1

  6. Start WebServerApache:1

  7. Start Oracle:2

  8. Start WebServerIP:2

  9. Start WebServerApache:2

  10. Start WwwStats

and the reverse for stop.

Co-locational Constraints and Clones

Co-locational -INFINITY constraints (ie. the resources must not be co-located) are the same as for any other resource.

  • <rsc_colocation id="not_same" from="www_prod_clones" to="www_test_clones" score="-INFINITY"/>
     
    Dont run production and test environments on the same machine.

Co-locational INFINITY constraints (ie. the resources must be co-located) for clones only make sense when the other resource is also a clone. Even then you are better off adding the resource to the resource group. All other cases are ignored.

Finding Clones in the Status Section

to be filled in...