fence_sshを試してみた
概要
fence_ssh
は、リモートノードをクラスタから安全に隔離するためのフェンシングエージェントです。SSHを利用してノードへのアクセスを行い、再起動や電源オフなどの操作を実行します。このエージェントはSSHを用いるため、対象ノードがハングアップして接続が確立できない場合にはフェンシングが機能しません。そのため、このエージェントは完全なフェンシングエージェントではなく、本番環境よりもテスト用途に適したツールです。
クラスタ環境での信頼性が重要な場合は、他のハードウェアベースのフェンシングエージェントの利用をおすすめします。
公式GitHubリポジトリでさらに詳しい情報を確認できます: リンク
今回はこのfence_ssh
を使ったPacemakerでのフェンシング設定について解説します。
今回の環境
2ノードのLinuxサーバで、OSはRockyLinux 8.10をインストールしています。
ホスト名はnode1とnode2になります。
PacemakerはLINBIT社のデモライセンスで入手したものを利用しています。デモライセンスは デモライセンス申請ページ から申請できます。
パッケージのインストール
まずfence_sshの開発サイト(リンク)からfence_ssh
をダウンロードしてください。
ダウンロードしたファイルを/usr/sbinにコピーして、chmod コマンドで実行権を付与します。
# wget https://raw.githubusercontent.com/nannafudge/fence_ssh/refs/heads/master/fence_ssh
# mv fence_ssh /usr/sbin
# chmod 755 /usr/sbin/fench_ssh
また、fence_ssh
の実行にsshpass
コマンドも必要になるため、これをdnf(yum)でインストールします。
# dnf install sshpass
パッケージのインストールが終わったら、次はアカウントの設定を行います。
アカウントの設定
root
アカウントでfence_sshを動かすことも可能で、設定も簡単ですが、今回はPacemakerをインストールするとシステムに追加されるhacluster
のアカウントを使って設定する例を紹介します。
パスワード設定
管理者アカウントで次のコマンドを実行して、haclusterのパスワードを設定してください。
また、hacluster
アカウントはログインシェルが無効(nologin)になっているため、usermod
コマンドでログインシェルをbash
に変更します。
# echo 'hacluster:Pa55w0rd' | sudo chpasswd
# usermod -s /bin/bash hacluster
sudoersの設定
fence_ssh
ではSSHで相手のノードにログインしてshutdown
コマンドを実行します。
したがってhacluster
アカウントでshutdownコマンドを実行できるようにsuder
の設定を行う必要があります。/etc/sudoers
の最後に次の行を追加してください。
hacluster ALL=(ALL) NOPASSWD: /sbin/shutdown
SSHによる疎通確認
以上でアカウントの設定が終わりました。相手のノードにSSHでログインができるか確認してください。
# sshpass -p 'Pa55w0rd' ssh hacluster@node2
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Wed Nov 6 09:47:46 2024 from 192.168.3.51
[hacluster@node2 ~]$
疎通確認が成功したら、次はパッケージfence_ssh
の試験を行います。
パッケージの単体試験
コマンドとしてfence_ssh
を実行して相手ノードが再起動できるかテストします。
次のように入力します。
# fence_ssh -h node2 -u hacluster -s true -p 'Pa55w0rd' -o reboot
node1から実行して、node2が再起動すれば正常に動作しています。
もし動作しない場合は、次のようにbashのデバッグオプションをつけて実行してエラー箇所を調べて下さい。
# bash -x /usr/sbin/fence_ssh -h ・・・・
Pacemakerの設定
過去に投稿したフェンシングの記事 (リンク) と同じく、Dummyリソースエージェントを使ってfence_ssh
の動作を確認します。Pacemakerの設定は以下のようになります。
node 1: node1
node 2: node2
primitive stonith1 stonith:fence_ssh \
params hostname=node1 user=root pcmk_host_list=node1 \
op monitor interval=60s \
meta provides=unfencing
primitive stonith2 stonith:fence_ssh \
params hostname=node2 user=root pcmk_host_list=node2 \
op monitor interval=60s \
meta provides=unfencing
primitive test Dummy \
op start interval=0s timeout=30s \
op monitor interval=10s timeout=60s \
op stop interval=0s timeout=30s on-fail=fence
location l_stonith1 stonith1 -inf: node1
location l_stonith2 stonith2 -inf: node2
property cib-bootstrap-options: \
stonith-enabled=true \
no-quorum-policy=ignore \
have-watchdog=false \
cluster-infrastructure=corosync \
cluster-name=cluster2 \
dc-version=2.0.5.linbit-2.0.el8-ba59be712
test
リソースのstop
の引数にon-fail=fence
があるので、停止に失敗するとフェンシングが発動して障害が発生したノードを相手ノードが再起動します。
動作確認
フェンシングの動作を確認します。test
リソースに停止のエラーを発生させて、fence_ssh
が起動するか確認します。
test
リソースを定義しているDummyリソースエージェントは/usr/lib/ocf/resource.d/heartbeat/Dummy
にあるシェルスクリプトです。
このファイルの119行目は次のようになっています。
dummy_stop() {
dummy_monitor
if [ $? = $OCF_SUCCESS ]; then
rm ${OCF_RESKEY_state}
fi
return $OCF_SUCCESS
}
dummy_stop()
はtest
リソースが停止の時に呼ばれる定義なので、ここにsleep
命令を入れて30秒以上処理時間が経過するように書き換えると、Pacemakerはtest
リソースの停止が失敗したと判断します。
dummy_stop() {
sleep 32 # ← 追加行
dummy_monitor
if [ $? = $OCF_SUCCESS ]; then
rm ${OCF_RESKEY_state}
fi
return $OCF_SUCCESS
}
node1のDummyリソースエージェントにのみ修正してください。
node1でtestリソースが動いていることを確認して、node1のPacemakerを停止します。Pacemakerの停止でtestリソースも停止しようとしますが、sleep 32の定義ににより停止に失敗します。この結果フェンシングが発動して、node1はnode2から停止されます。