Heartbeatでクラスターを組む

プライマリノードの設定

Heartbeatを使ってクラスターを組んでみました。
クラスターと言っても単に仮想IPアドレスをフェールオーバーさせるだけの簡単なものです。
仮想IPアドレスをフェールオーバーすることで、プライマリサーバーがダウンしても、
セカンダリサーバーが同じIPアドレスを引き継ぐので、このサーバーに接続している他のマシンは、
何も影響を受けることが有りません。



使用したのは2台のOragepi Zeroで、OSはArmbianのDebian12(bookworm)です。
Raspberry Piを使うとModelAでも2台で$60ぐらいかかりますが、Oragepi Zeroなら2台で$40で済むので、懐にやさしいです。

最初にプライマリノードを構築します。

end0をeth0に変更する

Ethernetのネットワーク名は伝統的にeth0でしたが、いつからかend0に変わりました。
これはdebianだけかもしれません。
今回使用するheartbeatパッケージはeth0を前提としているので、end0になっているときはeth0に変更します。
$ sudo ifconfig -a
end0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.127  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::7e46:8681:35e5:197a  prefixlen 64  scopeid 0x20<link>
        ether 02:42:0e:95:0f:93  txqueuelen 1000  (イーサネット)
        RX packets 22922  bytes 24180833 (23.0 MiB)
        RX errors 0  dropped 718  overruns 0  frame 0
        TX packets 4954  bytes 378167 (369.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

「/boot/armbianEnv.txt」に、以下の1行を追加してリブートすると、見慣れたインタフェース名になります。
$ cat /boot/armbianEnv.txt
verbosity=1
bootlogo=false
console=both
disp_mode=1920x1080p60
overlay_prefix=sun8i-h3
overlays=usbhost2 usbhost3 tve
rootdev=UUID=ba2bba4f-ddd9-4bba-83d8-cbe61613e4eb
rootfstype=ext4
extraargs=net.ifnames=0
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

$ sudo ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.127  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::a637:13f2:9308:8405  prefixlen 64  scopeid 0x20<link>
        ether 02:42:0e:95:0f:93  txqueuelen 1000  (イーサネット)
        RX packets 122  bytes 9348 (9.1 KiB)
        RX errors 0  dropped 11  overruns 0  frame 0
        TX packets 50  bytes 4564 (4.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 37


ホスト名を設定する

ホスト名は以下の様にしました。
プライマリノード:orange-node1
セカンダリノード:orange-node2

以下のコマンドでプライマリノードのホスト名を設定します。
$ sudo hostnamectl set-hostname orange-node1


IPアドレスを固定にする

IPアドレスは以下の様にしました。
プライマリノード:192.168.10.51
セカンダリノード:192.168.10.52

こちらの手順でStaticな IPアドレスに変更します。


/etc/hsostを設定する

/etc/hostsにプライマリとセカンダリの両方のホスト名を登録します。
$ cat /etc/hosts
127.0.0.1   localhost orangepizero
::1         localhost orangepizero ip6-localhost ip6-loopback
fe00::0     ip6-localnet
ff00::0     ip6-mcastprefix
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters
orange-node1 192.168.10.51
orange-node2 192.168.10.52


パッケージをインストールする

今回はheartbeat+pacemakerの組み合わせでクラスターを構築します。
heartbeatはノード状態を監視する機能を提供し、pacemakerはクラスタリソースを管理する機能(CRM)を持っています。
V3以前のheartbeatはCRM機能も持っていて、これだけでクラスタを構築することができましたが、V3からはCRM機能は pacemakerとして分離独立しました。
ノード状態を監視するツールにはCorosyncもあり、Corosync+pacemakerの組み合わせでも使うことができます。
$ sudo apt install heartbeat cluster-glue
$ sudo apt install pacemaker

heartbeatはV1系とV2系が有り、設定の仕方が少し違います。
今回インストールしたバージョンはV1系です。
$ dpkg -l | grep heartbeat
ii  heartbeat                            1:3.0.6-13+b2                  armhf        Subsystem for High-Availability Linux
ii  libheartbeat2                        1:3.0.6-13+b2                  armhf        Subsystem for High-Availability Linux (libraries)

$ dpkg -l | grep cluster-glue
ii  cluster-glue                         1.0.12-21+b2                   armhf        Reusable cluster components for Linux HA

$ dpkg -l | grep pacemaker
ii  libpacemaker1:armhf                  2.1.5-1+deb12u1                armhf        cluster resource manager utility library
ii  pacemaker                            2.1.5-1+deb12u1                armhf        cluster resource manager
ii  pacemaker-common                     2.1.5-1+deb12u1                all          cluster resource manager common files
ii  pacemaker-resource-agents            2.1.5-1+deb12u1                all          cluster resource manager general resource agents


設定ファイルを作成する

設定ファイルについては、以下のページを参考にさせていただきました。
https://thinkit.co.jp/cert/compare/17/9/4.htm
http://unixservermemo.web.fc2.com/sv/pacemaker-hacf.htm

以下の3つのファイルを作成します。

/etc/ha.d/ha.cf
[uuidfrom nodename]を指定しないと、/var/lib/heartbeat/hb_uuid をマシンのUUIDとして使います。
プライマリーマシンのイメージをコピーして、セカンダリーマシンに使用する場合に、uuidの重複エラーが延々と出るのを防ぎます。
$ cat /etc/ha.d/ha.cf
logfile /var/log/ha-log
keepalive 2
deadtime 30
warntime 10
initdead 60
udpport 694
bcast eth0
auto_failback on
node orange-node1 orange-node2
uuidfrom nodename

/etc/ha.d/haresources
今回のリソースは仮想IPアドレスだけです。
$ cat /etc/ha.d/haresources
orange-node1 IPADDR::192.168.10.50/24

/etc/ha.d/authkeys
このファイルだけはパーミッションを600に変更しておく必要が有ります。
$ sudo cat /etc/ha.d/authkeys
auth 1
1 crc

$ sudo chmod 600 /etc/ha.d/authkeys


サービス定義ファイルを一部変更する

heartbeatはサービスとして起動しますが、orangepiの場合、Ethernetの初期化とIPアドレス取得に時間がかかるので、少 し変更が必要でし た。
この変更により、Ethernetの初期化とIPアドレス取得を待つことができます。
$ sudo vi /lib/systemd/system/heartbeat.service
[Unit]
Description=Heartbeat High Availability Cluster Communication and Membership
# partially copied and adapted from the pacemaker.service file

#After=basic.target
#After=network.target

#Requires=basic.target
#Requires=network.target

#After=drbd.service

After=NetworkManager-wait-online.service

(後略)


サービスの起動

NetworkManager-wait-online.serviceが無効になっているときは、以下の手順で起動しておきます。
$ sudo systemctl list-unit-files --type=service | grep NetworkManager-wait-online.service
NetworkManager-wait-online.service         disabled        enabled

$ sudo systemctl enable NetworkManager-wait-online.service
Created symlink /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service → /lib/systemd/system/NetworkManager-wait-online.service.

$ sudo systemctl list-unit-files --type=service | grep NetworkManager-wait-online.service
NetworkManager-wait-online.service         enabled         enabled

$ sudo systemctl restart NetworkManager-wait-online.service

$ sudo systemctl -l --no-pager status NetworkManager-wait-online.service
● NetworkManager-wait-online.service - Network Manager Wait Online
     Loaded: loaded (/lib/systemd/system/NetworkManager-wait-online.service; enabled; preset: enabled)
     Active: active (exited) since Fri 2025-02-07 07:04:11 JST; 59s ago
       Docs: man:nm-online(1)
    Process: 2894 ExecStart=/usr/bin/nm-online -s -q (code=exited, status=0/SUCCESS)
   Main PID: 2894 (code=exited, status=0/SUCCESS)
        CPU: 106ms

haartbeatはインストールと同時に起動されますので、一旦disableにしたのち再起動します。
$ sudo systemctl list-unit-files --type=service | grep heartbeat
heartbeat.service                          enabled         enabled

$ sudo systemctl disable heartbeat
Synchronizing state of heartbeat.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable heartbeat

$ sudo systemctl list-unit-files --type=service | grep heartbeat
heartbeat.service                          disabled        enabled

$ sudo systemctl enable heartbeat
Synchronizing state of heartbeat.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable heartbeat

$ sudo systemctl restart heartbeat

$ sudo systemctl -l --no-pager status heartbeat
● heartbeat.service - Heartbeat High Availability Cluster Communication and Membership
   Loaded: loaded (/lib/systemd/system/heartbeat.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-02-19 22:44:46 JST; 12min ago
 Main PID: 1168 (heartbeat)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/heartbeat.service
           tq1168 heartbeat: master control process
           tq1181 heartbeat: FIFO reader
           tq1184 heartbeat: write: bcast eth0
           mq1185 heartbeat: read: bcast eth0

起動が失敗するときは、ログファイル(/var/log/ha-log)を見れば原因が分かります。


仮想IPアドレスの確認

セカンダリノードと同期をとるために、60秒の待ち時間を設定しています。
セカンダリノードが60秒以内に起動しないときは、非クラスター環境で起動します。
60秒後に確認すると192.168.10.50の仮想IPアドレスが現れます。


他のマシンから192.168.10.50の仮想IPでログインできることを確認します。
正常にログイン出来たら、セカンダリノードを設定します。

続く....