
他の言語と同様に、CIBにも、特定の表現に適した方法があります。この表現方法については、適切に機能すること、最小限の副作用に抑えられることが確認されています。
これらはCIBのレシピ、つまりCIB HOWTOと言えるでしょう。考え方は、ほぼ同じです。
ここでは、それらをCIBイディオム[1]と呼び、最も一般的なイディオムのカタログを作成します。
リソースを特定のノードのみで実行し、ほかの場所では実行しないように制限をかけなければならない場合があります。以下は、そういった制限例です。
<rsc_location id="rloc_unique_id">
<rule score="-INFINITY" boolean_op="and" resource="my_resource"
id="rcloc_rule_unique_id">
<expression attribute="#uname" operation="ne" value="host1" id="expr:h1">
<expression attribute="#uname" operation="ne" value="host2" id="expr:h2">
<expression attribute="#uname" operation="ne" value="host3" id="expr:h3">
</rule>
</rsc_location>
上記コマンドの翻訳:ノードがhost1, host2, または host3のいずれにも該当しない場合は、リソースmy_resourceをノード上で実行するようにはスケジュールしません。これは以下の式に相当します。
if ($uname != host1 && $uname != host2 && $uname != host3)
{score=-INFINITY;};
my_resourceに関連するCIBの状態に関係なく、このリソースをほかのノード上で実行することは、完全に禁止されます。
リソースを一定の属性値を持つノードのみで実行し、ほかの場所では実行しないように制限をかけなければならない場合があります。以下は、そういった制限例です
<rsc_location id="rloc_unique_id">
<rule score="-INFINITY" boolean_op="or" resource="my_resource"
id="rcloc_rule_unique_id">
<expression id="expr:hfc:undefined"
attribute="has_fibre_channel" operation="not_defined"/>
<expression id="expr:hfc:false"
attribute="has_fibre_channel" operation="ne" value="true"/>
</rule>
</rsc_location>
上記コマンドの翻訳:ノードの属性"has_fibre_channel"が値"true"をとらない場合は、リソース"my_resource"をノード上で実行するようにはスケジュールしません。これは、以下の式に相当します。
if (!defined($has_fibre_channel) || $has_fibre_channel != true)
my_resourceに関連するCIBの状態に関係なく、このリソースをほかのノード上で実行することは、完全に禁止されます。has_fibre_channel をfalseに設定したエージェントがある場合には、ファイバーチャンネル接続に障害が発生すると、このノードはmy_resourceは実行できません。
指定されたリソースのマスターであるノードでのみ特定のリソースを実行することは、ごく一般的なことです。以下は、CIBに制限を表現する適切な方法です。
<rsc_colocation id="fs_on_drbd0" to="drbd0-partition"
to_role="stopped"
from="mount-drbd0" score="-infinity"/>
<rsc_colocation id="fs_on_drbd0" to="drbd0-partition"
to_role="slave"
from="mount-drbd0" score="-infinity"/>
<rsc_order id="drbd_before_fs" from="mount-drbd0" action="start"
to="drbd0-partition" to_action="promote" />
翻訳:
drbd0-partitionnが停止している場合は、fs_on_drbd0は実行しません。
drbd0-partitionがスレーブとして動作している場合は、fs_on_drbd0は実行しません。
drbd0-partitionをマスターに昇格した後にのみ、fs_on_drbd0 を実行します。
マスター/スレーブリソースの状態は、{stopped, slave, master}であるため、マスターとして動作するノードのみで、リソースの実行が許可できます。
スレーブノードで実行するリソースがある場合、使用イディオムは、 マスターと同じ場所に配置する[2]ケースと似ています。
<rsc_colocation id="fs_on_drbd0" to="drbd0-partition" to_role="stopped" from="mount-drbd0" score="-infinity"/> <rsc_colocation id="fs_on_drbd0" to="drbd0-partition" to_role="master" from="mount-drbd0" score="-infinity"/>
翻訳:
drbd0-partitionが停止している場合は、fs_on_drbd0は実行しません。
drbd0-partitionがマスターとして動作している場合は、fs_on_drbd0は実行しません。
マスター/スレーブリソースの状態は{stopped, slave, master}であるため、スレーブとして動作するノードのみで、リソースの実行が許可できます。
質問:
このケースに対応する順序のルール作成方法が分かりません。リソースが実行できるのは、リソースが開始された後なのか、それとも、マスターから降格された後なのかが分かりません。これは本当に必要ですか?もし、必要ないのであれば、マスターの場合の命令ルールも不要になります。
マスター/スレーブリソースのマスターインスタンスをクラスタ内の特定のノード、または一連のノード上で実行するように設定し、制限したい場合には、以下のCIBスニペットでは、ノードfredをリソースdrbd1のマスターにして、100ポイントを追加します。
<rsc_location id="loc:drbd1_likes_fred" rsc="drbd1">
<rule id="rule:drbd1_likes_fred" role="master" score="100">
<expression attribute="#uname" operation="eq" value="fred">
</rule>
</rsc_location>
マスター/スレーブリソースのスレーブインスタンスをクラスタ内の特定ノード、または一連のノード上で実行するように設定し、制限したい場合があるかと思います。 しかし、全てのリソースは昇格前にスレーブ状態を経由するため、リソースを制限してマスターになることは回避しなければなりません。 以下のCIBスニペットでは、fred以外のノードをリソースdrbd1のマスターに昇格し、これらのノードに100ポイントを追加します。これは、「fredがマスターにならないようにする」ことと実質的に同じことです。
<rsc_location id="loc:drbd1_likes_fred" rsc="drbd1">
<rule id="rule:drbd1_likes_fred" role="master" score="100">
<expression attribute="#uname" operation="ne" value="fred">
</rule>
</rsc_location>
ルールの中には、score属性またはscore_attribute属性によってスコアを与えられたものがあります。競合が発生するため、scoreとscore_attribute両方のルール設定はエラーとなります。
ほとんどの場合、 が特定のルールのスコアとして直接設定した属性値を許可することが妥当と言えるでしょう。
例えば、pingd[3]の倍率を100に設定し、1つのノードへのアクセスが100に相当する場合、2つのノードは200に相当します。
このように、ほかの全ての条件が同等である場合には、最も高いping接続が確立されたノードが選択されるのです。複数のノードのスコアが同じ場合には、次のルールに従えば、同等の重要性が与えられます。
<rsc_location id="my_resource:connected" rsc="my_resource">
<rule id="my_resource:connected:rule" score_attribute="pingd" >
<expression id="my_resource:connected:expr:defined"
attribute="pingd" operation="defined"/>
</rule>
</rsc_location>
もちろん、デフォルト(pingd)以外の属性名を設定するようにpingd[3]デーモンを構成した場合には、score_attributeの名前をpingdから、pingd[3]デーモン用に構成した名前に変更する必要があります。
ping接続が失われた際、特定のサービスを終了した方がよい場合もあります。このルールでは、外部へのping接続が確立されない場所からサービスを実行することを禁止しています。ある程度の接続が確立された全てのノードは、pingノードにアクセスできる数には関係なく同様に扱われます。
<rsc_location id="my_resource:connected" rsc="my_resource">
<rule id="my_resource:connected:rule" score="-INFINITY" boolean_op="or">
<expression id="my_resource:connected:expr:undefined"
attribute="pingd" operation="not_defined"/>
<expression id="my_resource:connected:expr:zero"
attribute="pingd" operation="lte" value="0"/>
</rule>
</rsc_location>
もちろん、デフォルト(pingd)以外の属性名を設定するようにpingd[3] デーモンを構成した場合は、attributeをpingdからpingd[3]デーモンが使用するように構成した名前に変更する必要があります。
注: pingを送信したノードが停止するか、ハートビートがノードへの接続性を失った場合、あらゆるリソースが停止されてしまいます。代わりに、最高の接続性が確立された、ノードを優先するスコア[4] の使用を検討してください。
時刻によって、異なる操作を実行したい場合があるかと思います。 このセクションでは、このような操作をCIBで実行する方法例をご紹介します。
多くのクラスタの場合、週末にのみフェイルオーバを実行し、平日はフェイルオーバを禁止するポリシーを設定した方が合理的です。
以下は、それを実現するXMLスニペットのcrm_configセクションです。
CRMは、月曜日を週の1日目とする規約に従います。これは、date %u文字列に似ていますが、%w文字列とは異なります。Cronでは、月曜日を最初(0)と最後(7)のどちらにも設定できます。CIBでは、月曜日は週の最終日(7)となります。
<cluster_property_set id="weekend_override" score="100">
<rule id="my_ip:failover" boolean_op="and">
<date_expression id="my_ip:days" operation="date_spec">
<date_spec id="my_ip:days" weekdays="6-7"/>
</date_expression>
</rule>
<attributes>
<nvpair id="weekend-sticky"
name="default_resource_stickiness"
value="0"/>
</attributes>
</cluster_property_set>
<cluster_property_set id="default_cluster_properties" score="10">
<attributes>
<nvpair id="default-sticky"
name="default_resource_stickiness"
value="INFINITY"/>
</attributes>
</cluster_property_set>
Translating this into English: 上記コマンドの翻訳:1つ目のcluster property setに100のスコアを与え、週末(6~7の2日間)にのみ真となる曜日の制限を設定します。
つまり、曜日の式が真である場合には、このルールセットの要素に100の荷重値が与えられます。
2つ目のcluster_propertyは、10の荷重(スコア)を持ち、常にTRUEとなります(常に適用されます)。しかし、この荷重は10でしかなく、上記の条件に応じたルールは100の荷重を持つため、両方のルールセットが適用されると競合が発生し、weekend_override の{{cluster_property_set}}で指定された要素が優先されます。
この最終結果として、曜日が6および7の2日間はdefault_resource_stickinessの値は0になりますが、ほかの曜日にはINFINITYになります。
通常のリソースの監視操作が本稼働時に負荷がかかりすぎる場合には、負荷がかからない監視操作を通常の稼働時間内に頻繁に実行して、負荷のかかる監視操作については夜間にのみ実行します。
カテゴリのないイディオム[5]
特定の操作で停止障害を発生させ、再起動をトリガした方が適切なケースがよくあります。これを行うには、以下のXMLをリソースの<operations/> セクションに追加します。
<op id="dummy-resource-stop-id" name="stop" on_fail="fence"/>
このリソースにタイムアウトなどを指定する場合は、それらも同様にop タグに含めます。
STONITHプラグインは、複数のノードを制御可能なプラグイン(電源スイッチなど)と、1つのノードしか制御できないプラグイン(iLOやDRACなど)の2種類に分類することができます。
どちらの場合も、CIBでSTONITHを構成する標準的な方法は、「クローン」リソースの使用です。これは、クラスタの状態に関係なく、全てのノードでハートビートが1つのSTONITHリソースエージェント(そのノードでSTONITH機能を提供しているプロセス)に到達しなければならないためです。最も簡単な方法としては、各ノードで1つのインスタンスを実行することです。こういった理由からクローンを使用します。STONITH RAを構成すると、Heartbeatによって各ノードでエージェントが実行されます。
各エージェントがそれぞれ1つのノードのみ制御可能なSTONITHデバイスにおいては、動作しているSTONITHリソースの総数は、ノード数の2乗に等しくなります。
外部iLO STONITHモジュール(riloe)の各インスタンスでは、1つのノードの電源しか切ることはできませんので、iLOカードを含む各ノードのクローンが必要となります。
以下の例では、iLOインターフェースはnode01-rm上にあります。
<clone id="CL_stonithset_node01">
<instance_attributes id="CL_stonithset_node01">
<attributes>
<nvpair id="CL_stonithset_node01_clone_node_max" name="clone_node_max" value="1"/>
</attributes>
</instance_attributes>
<primitive id="CL_stonith_node01" class="stonith" type="external/riloe-ng" provider="heartbeat">
<operations>
<op name="monitor" interval="30s" timeout="20s" id="CL_stonith_node01_monitor"/>
<op name="start" timeout="60s" id="CL_stonith_node01_start"/>
</operations>
<instance_attributes id="CL_stonith_node01">
<attributes>
<nvpair id="CL_stonith_node01_hostlist" name="hostlist" value="node01"/>
<nvpair id="CL_stonith_node01_RI_HOST" name="RI_HOST" value="node01"/>
<nvpair id="CL_stonith_node01_RI_HOSTRI" name="RI_HOSTRI" value="node01-rm"/>
<nvpair id="CL_stonith_node01_RI_LOGIN" name="RI_LOGIN" value="Heartbeat"/>
<nvpair id="CL_stonith_node01_RI_PASSWORD" name="RI_PASSWORD" value="password"/>
</attributes>
</instance_attributes>
</primitive>
</clone>
| [1] | http://www.linux-ha.org/ja/CIB/Idioms_ja |
| [2] | http://www.linux-ha.org/ja/CIB/Idioms/ColoWithMaster_ja |
| [3] | http://www.linux-ha.org/ja/pingd_ja |
| [4] | http://www.linux-ha.org/ja/CIB/Idioms/PingdAttrAsScore_ja |
| [5] | http://www.linux-ha.org/ja/CategoryMissingIdiom_ja |
This information provided courtesy of the Linux-HA project at http://linux-ha.org/