単ノードのフェンシング

某社の送別会で、Ａ氏から質問されたのですが、「出来ないはず」(Pacemaker1.0系では出来なかったはず）と答えてしまい・・・気になって確認してみました。

Pacemaker1.1系では、自ノードのフェンシング(セルフフェンシング:ACT/STB構成ではなくてもフェンシングが単ノードで可能）が可能で、単一ノードとなった場合に動作します。
これにより、リソース故障時(on-fail="fence)のフェンシングで自ノードがフェンシング（再起動や電源ＯＦＦ）が可能となります。
当然ですが、リソース構成には、自ノードがフェンシング可能なSTONITHエージェントを含める必要があります。

#前提する環境
Pacemaker1.1系で単一ノードでのサービス提供とします。
ACT/STB構成などは取らない為、リソース故障以外の故障に関しては、watchdogなどに頼ることになります。
(vSphere環境などであれば、ゲストハングなどではVMWare HA機能に頼る必要があるという意味です）

#設定
sshを利用した自ノードのフェンシング設定を行って、リソース故障時に自ノードをSTONITHさせて再起動します。
なお、注意点として、実際にセルフフェンシングで実行できるのは、単一コマンドで自ノードを制御出来るSTONITHエージェントと、動作に限られる為、STONITHエージェントで、一旦、offして、onするような動作は出来ません。（自ノード内で実行するので当たり前といえば当たり前ですが..rebootなど単発の動作コマンドの範囲で可能です）
よって、sshエージェントではrebootを実行させるものとします。
なお、パスワード接続無しで設定していますので、事前に、sshでパスワード無しで自ノードに接続可能なようにauthozed_keysに設定しておいてください。

```
primitive prmStonith stonith:external/ssh \
  params \
    pcmk_reboot_timeout="60s" \
    hostlist="ct72-01" \
  op start interval="0s" timeout="60s" on-fail="restart" \
  op stop interval="0s" timeout="60s" on-fail="ignore"

primitive dummy Dummy \
        op start interval=0s timeout=60s on-fail="restart"  \
        op monitor interval=5s timeout=60s on-fail="restart" \
        op stop interval=0s timeout=60s on-fail="fence"

location loc2 prmStonith \
        rule inf: #uname eq ct72-01 \

property cib-bootstrap-options: \
        stonith-enabled=true \
        startup-fencing=false \
        no-quorum-policy=ignore
```
#結果
リソース故障を疑似的に発生させると、自ノードがSTONITHリソースによって再起動されます。
なお、くどいようですが、OSハングなどでは再起動されませんので、注意してください。
あくまでも、Pacemakerが動作可能な状態でのリソース故障です。

##起動

```
[root@ct72-01 ~]# crm_mon -1 -Af
Last updated: Mon Apr  4 16:02:55 2016          Last change: Mon Apr  4 16:02:50 2016 by root via cibadmin on ct72-01
Stack: corosync
Current DC: ct72-01 (version 1.1.14-70404b0) - partition with quorum
1 node and 2 resources configured

Online: [ ct72-01 ]

 dummy  (ocf::heartbeat:Dummy): Started ct72-01
 prmStonith     (stonith:external/ssh): Started ct72-01

(snip)
```
##リソース故障
疑似的にdummyリソースに故障を起こして、stopでエラーを発生させます

``` /usr/lib/ocf/resource.d/heartbeat/Dummy
dummy_stop() {
    return $OCF_ERR_GENERIC #追加
    dummy_monitor
    if [ $? =  $OCF_SUCCESS ]; then
        rm ${OCF_RESKEY_state}
    fi
    return $OCF_SUCCESS
}
#stateファイルを削除して、stopを発生させる。
[root@ct72-01 ~]# rm -rf /var/run/resource-agents/Dummy-dummy.state 

```
##ノードが再起動
自ノードのリソース故障を検知して、external/sshで再起動がかかります。

#注意
確認していませんが、STONITHエージェントはそのノードで配置不可（通常、実行不可となる）に設定しても実行することが出来るようです。
単一ノード構成時のみなのか？設定などによって、セルフフェンシングを抑止出来るのかは確認していません。

#追記(2019/05/02)
気になったのでもう少し調べてみました。(Pacemakerは1.1.20です)
セルフフェンシングですが、自ノードを落とす事の出来るSTONITHリソースがそのノードで配置不可制約(locaionで-INF制約)となっている場合には、実行出来ません。
また、配置不可となっていなければ、fencing_topologyに記載されていなくても、実行することが出来ます。
セルフフェンシングが発動するのは、実行可能なSTONITHリソースが存在して、かつ、単ノード構成の場合と、クラスタを構成するノード数が減って単ノード構成となった後のフェンシング動作です。

実際に処理のセルフフェンシングを指示しているのはcrmdでstonithプロセスへの依頼時に、現在の構成ノード数を考慮してst_opt_allow_suicideフラグをセットしています。
stonithプロセスでは、このフラグを元にセルフフェンシングの実行を行います。

```
@crmd/te_actions.c

static gboolean
te_fence_node(crm_graph_t * graph, crm_action_t * action)
{
(snip)
    crm_notice("Requesting fencing (%s) of node %s "
               CRM_XS " action=%s timeout=%d",
               type, target, id, transition_graph->stonith_timeout);

    /* Passing NULL means block until we can connect... */
    te_connect_stonith(NULL);

    if (crmd_join_phase_count(crm_join_confirmed) == 1) {
//構成ノード数が１（単ノードもしくは、縮退して単ノード）なら、フラグセット
        options |= st_opt_allow_suicide;
    }

//stonithプロセスへのフェンシングの依頼
    rc = stonith_api->cmds->fence(stonith_api, options, target, type,
                                  transition_graph->stonith_timeout / 1000, 0);
```