Pacemakerによる冗長構成を試す
PacemakerはLinuxで使われる冗長化ソフトウェアです。複数ノードでACT/SBY構成などによる冗長を確保したい場合に使用されます。 今回は仮想環境上に3ノードのクラスターを構成し、Apaceh Webサーバを実行します。
VMを下記の通り作成します。
■cluster1.example.net
IP:192.168.11.121/24
■cluster2.example.net
IP:192.168.11.122/24
■cluster3.example.net
IP:192.168.11.123/24
Pacemakerの構築はこのサイトを参考にさせていただきました。今回は複数ノードあるため、構成管理ツールであるansibleで環境を構築します。 作業用の環境にansibleをインストールし、下記のplaybookをcluster_setup.ymlという名前で作成します。
- hosts: cluster_nodes become: yes vars: - CLUSTER_PASS: 'cluster_passw0rd' tasks: - name: Update packages latest yum: name: '*' state: latest - name: Install pacemaker packages yum: name: pacemaker,pcs,fence-agents,httpd state: installed - name: Start services systemd: name: "{{ item }}" enabled: yes state: started with_items: - pcsd - name: Enable Corosync and Pacemaker service systemd: name: "{{ item }}" enabled: yes with_items: - corosync - pacemaker - name: Change hacluster password user: name: hacluster password: "{{ CLUSTER_PASS | password_hash('sha512') }}" - name: Allow Pacemaker Connection firewalld: service: "{{ item }}" permanent: yes immediate: yes state: enabled with_items: - high-availability - http - name: Check hosts file shell: "grep 192.168.11.12 /etc/hosts | wc -l" register: test_hosts - name: Add cluster hosts to /etc/hosts lineinfile: path: "/etc/hosts" state: present line: | 192.168.11.121 cluster1.example.net 192.168.11.122 cluster2.example.net 192.168.11.123 cluster3.example.net when: test_hosts.stdout == "0" - name: Configure HTTPD status page copy: dest: "/etc/httpd/conf.d/status.conf" content: | ExtendedStatus On <Location /server-status> SetHandler server-status Require local </Location> - name: Make sure Apache server disable by default systemd: name: httpd enabled: no state: stopped - name: Add Test content shell: "echo \"running on `hostname`\" > /var/www/html/test.txt"
inventory.txtを作成し、作業対象のサーバを記述します。
[cluster_nodes] 192.168.11.121 192.168.11.122 192.168.11.123
playbookを実行します。
[jinglan@ansible-server ~]# ansible-playbook -i inventory.txt cluster_setup.yml --ask-become-pass -vv
しばらくすると環境構築が終わります。結果にfailedが表示されていないことを確かめてください。
次からの作業はクラスタのうち一つにログインして作業します。3つのノードを登録しクラスターとして動作させます。
[root@cluster1 ~]# pcs cluster auth cluster1.example.net cluster2.example.net cluster3.example.net -u hacluster Password: (playbookで定義したパスワードを入力) cluster2.example.net: Authorized cluster1.example.net: Authorized cluster3.example.net: Authorized [root@cluster1 ~]# pcs cluster setup --name httpcluster cluster1.example.net cluster2.example.net cluster3.example.net Destroying cluster on nodes: cluster1.example.net, cluster2.example.net, cluster3.example.net... cluster3.example.net: Stopping Cluster (pacemaker)... cluster1.example.net: Stopping Cluster (pacemaker)... cluster2.example.net: Stopping Cluster (pacemaker)... cluster1.example.net: Successfully destroyed cluster cluster2.example.net: Successfully destroyed cluster cluster3.example.net: Successfully destroyed cluster Sending 'pacemaker_remote authkey' to 'cluster1.example.net', 'cluster2.example.net', 'cluster3.example.net' cluster1.example.net: successful distribution of the file 'pacemaker_remote authkey' cluster2.example.net: successful distribution of the file 'pacemaker_remote authkey' cluster3.example.net: successful distribution of the file 'pacemaker_remote authkey' Sending cluster config files to the nodes... cluster1.example.net: Succeeded cluster2.example.net: Succeeded cluster3.example.net: Succeeded Synchronizing pcsd certificates on nodes cluster1.example.net, cluster2.example.net, cluster3.example.net... cluster2.example.net: Success cluster1.example.net: Success cluster3.example.net: Success Restarting pcsd on the nodes in order to reload the certificates... cluster2.example.net: Success cluster1.example.net: Success cluster3.example.net: Success [root@cluster1 ~]# pcs cluster start --all cluster1.example.net: Starting Cluster (corosync)... cluster2.example.net: Starting Cluster (corosync)... cluster3.example.net: Starting Cluster (corosync)... cluster1.example.net: Starting Cluster (pacemaker)... cluster3.example.net: Starting Cluster (pacemaker)... cluster2.example.net: Starting Cluster (pacemaker)... [root@cluster1 ~]# pcs property set stonith-enabled=false [root@cluster1 ~]#
クラスターを構成したので現在の状態を確認します。
[root@cluster1 ~]# pcs status Cluster name: httpcluster Stack: unknown Current DC: NONE Last updated: Sat Jun 27 15:55:09 2020 Last change: Sat Jun 27 15:55:04 2020 by root via cibadmin on cluster1.example.net 3 nodes configured 0 resources configured OFFLINE: [ cluster1.example.net cluster2.example.net cluster3.example.net ] No resources Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled
3つのノードが認識されていますが、リソースが設定されていないためOFFLINE状態になっています。 そのため、クラスターで冗長化するリソースについて設定します。今回は冗長化されたIPアドレス(192.168.11.120)とHTTPサーバを定義します。
[root@cluster1 ~]# pcs resource create VIP ocf:heartbeat:IPaddr2 ip=192.168.11.120 cidr_netmask=24 op monitor interval=10s on-fail="standby" --group httpgroup [root@cluster1 ~]# pcs resource create HTTPD ocf:heartbeat:apache configfile="/etc/httpd/conf/httpd.conf" statusurl="http://127.0.0.1/server-status" --group httpgroup
HTTPDとVIPは同じリソースグループに属しているので一緒に切り替わります。 再度、pacemakerの状態を表示します。
[root@cluster1 ~]# pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster1.example.net (version 1.1.21-4.el7-f14e36fd43) - partition with quorum Last updated: Sat Jun 27 10:25:59 2020 Last change: Fri Jun 26 22:00:25 2020 by root via cibadmin on cluster1.example.net 3 nodes configured 2 resources configured Online: [ cluster1.example.net cluster2.example.net cluster3.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster1.example.net HTTPD (ocf::heartbeat:apache): Started cluster1.example.net Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
Resource Groupの表示に「Started cluster1.example.net」と記載があり、cluster1で実行されていることがわかります。実際にVIPアドレスへHTTPリクエストを飛ばして確認してみます。
$ curl http://192.168.11.120/test.txt running on cluster1.example.net
応答からcluster1でHTTP処理が行われたことが分かります。 続いてcluster1を疑似的に停止します。その前に、別ターミナルから連続でHTTPリクエストを飛ばし、切り替え状態をモニターします。
$ while : ; do curl http://192.168.11.120/test.txt ; sleep 1; done; running on cluster1.example.net
VMを実行しているホストにて下記コマンドでVMを停止します。
# virsh suspend cluster1
モニターしているターミナルでは一時疎通不可になったのち、切り替わることが確認できます。
running on cluster1.example.net running on cluster1.example.net curl: (7) Failed to connect to 192.168.11.120 port 80: Connection refused curl: (7) Failed to connect to 192.168.11.120 port 80: Connection refused running on cluster2.example.net running on cluster2.example.net running on cluster2.example.net
次に、cluster3を停止します。
# virsh suspend cluster3
モニター側ではWebサイトからの応答がなくなります。 cluster2側で状態を確認します。
[jinglan@cluster2 ~]$ sudo pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster2.example.net (version 1.1.21-4.el7-f14e36fd43) - partition WITHOUT quorum Last updated: Sat Jun 27 13:54:09 2020 Last change: Sat Jun 27 13:52:53 2020 by root via cibadmin on cluster1.example.net 3 nodes configured 2 resources configured Online: [ cluster2.example.net ] OFFLINE: [ cluster1.example.net cluster3.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Stopped HTTPD (ocf::heartbeat:apache): Stopped Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
Resource Groupが停止していることが確認できます。3ノード構成ではquorumによりアクティブになるノードが決定されます。これにより、2ノードから疎通ができなくなったノードは冗長構成から切り離されたと判断し、リソースの競合を防ぐため停止します。
停止させたcluster1とcluster3を再開します。
# virsh resume cluster1 # virsh resume cluster3
cluster1とcluster3が復帰したことでリソースはcluster1に戻ります。
[root@cluster1 ~]# pcs status Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster1.example.net HTTPD (ocf::heartbeat:apache): Started cluster1.example.net
特定のホストでリソースを実行したい場合はstandbyを使います。cluster1とcluster2をstandby状態にして、cluster3で実行させるようにします。
[root@cluster1 ~]# pcs cluster standby cluster1.example.net [root@cluster1 ~]# pcs cluster standby cluster2.example.net [root@cluster1 ~]# pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster3.example.net (version 1.1.21-4.el7-f14e36fd43) - partition with quorum Last updated: Sat Jun 27 15:59:00 2020 Last change: Sat Jun 27 15:58:54 2020 by root via cibadmin on cluster1.example.net 3 nodes configured 2 resources configured Node cluster1.example.net: standby Node cluster2.example.net: standby Online: [ cluster3.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster3.example.net HTTPD (ocf::heartbeat:apache): Started cluster3.example.net
リソースはcluster3で実行を続けます。なお、この時にcluster3が停止状態になるとリソースの移動先がないために切り替わりが起きません。 standby状態はunstandbyコマンドにより解除することができます。
[root@cluster1 ~]# pcs cluster unstandby --all
standbyによるACT/SBY構成の切り替えはシングル障害点になってしまいます。特定のノードにリソースを移したい場合はresource moveにより切り替えます。
[root@cluster1 ~]# pcs resource move httpgroup cluster1.example.net [root@cluster1 ~]# pcs status (略) Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster1.example.net HTTPD (ocf::heartbeat:apache): Started cluster1.example.net
次に、リソース起動に失敗した場合の動作について確認してみます。Apacheの設定ファイルを取り除きます。
[root@cluster1 ~]# cd /etc/httpd/conf/ [root@cluster1 conf]# mv httpd.conf httpd.conf.bak
現在動いているプロセスをkillします。
[root@cluster1 ~]# ps aux | grep httpd root 24998 0.0 0.3 224080 3468 ? Ss Jun27 0:18 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run/httpd.pid [root@cluster1 ~]# kill 24998
ログを確認すると起動に失敗したため系切り替えが発生したことが分かります。
[root@cluster1 conf]# tail /var/log/messages Jun 29 22:24:19 cluster1 lrmd[22953]: notice: HTTPD_start_0:17745:stderr [ ocf-exit-reason:Configuration file /etc/httpd/conf/httpd.conf not found! ] Jun 29 22:24:19 cluster1 lrmd[22953]: notice: HTTPD_start_0:17745:stderr [ ocf-exit-reason:environment is invalid, resource considered stopped ] Jun 29 22:24:19 cluster1 crmd[22956]: notice: Result of start operation for HTTPD on cluster1.example.net: 5 (not installed) Jun 29 22:24:19 cluster1 crmd[22956]: notice: cluster1.example.net-HTTPD_start_0:24 [ ocf-exit-reason:Configuration file /etc/httpd/conf/httpd.conf not found!\nocf-exit-reason:environment is invalid, resource considered stopped\n ] Jun 29 22:24:19 cluster1 apache(HTTPD)[17773]: ERROR: Configuration file /etc/httpd/conf/httpd.conf not found! Jun 29 22:24:19 cluster1 apache(HTTPD)[17773]: INFO: environment is invalid, resource considered stopped Jun 29 22:24:19 cluster1 lrmd[22953]: notice: HTTPD_stop_0:17773:stderr [ ocf-exit-reason:Configuration file /etc/httpd/conf/httpd.conf not found! ] Jun 29 22:24:19 cluster1 crmd[22956]: notice: Result of stop operation for HTTPD on cluster1.example.net: 0 (ok) Jun 29 22:24:19 cluster1 IPaddr2(VIP)[17800]: INFO: IP status = ok, IP_CIP= Jun 29 22:24:19 cluster1 crmd[22956]: notice: Result of stop operation for VIP on cluster1.example.net: 0 (ok)
現在の状態を確認します。
[root@cluster1 conf]# pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster3.example.net (version 1.1.21-4.el7-f14e36fd43) - partition with quorum Last updated: Mon Jun 29 22:24:27 2020 Last change: Sat Jun 27 16:07:21 2020 by root via crm_resource on cluster1.example.net 3 nodes configured 2 resources configured Online: [ cluster1.example.net cluster2.example.net cluster3.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster2.example.net HTTPD (ocf::heartbeat:apache): Started cluster2.example.net Failed Resource Actions: * HTTPD_start_0 on cluster1.example.net 'not installed' (5): call=24, status=complete, exitreason='environment is invalid, resource considered stopped', last-rc-change='Mon Jun 29 22:24:19 2020', queued=0ms, exec=36ms
起動に失敗したことがFailed Resource Actionsに表示されています。取り除いたApacheの設定ファイルを元に戻します。
mv httpd.conf.bak httpd.conf
これでcluster1のApacheは正常に起動できるはずです。cluster2とcluster3をstanbyにしてみます。
[root@cluster1 conf]# pcs cluster standby cluster2.example.net [root@cluster1 conf]# pcs cluster standby cluster3.example.net [root@cluster1 conf]# pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster3.example.net (version 1.1.21-4.el7-f14e36fd43) - partition with quorum Last updated: Mon Jun 29 22:34:30 2020 Last change: Mon Jun 29 22:34:13 2020 by root via cibadmin on cluster1.example.net 3 nodes configured 2 resources configured Node cluster2.example.net: standby Node cluster3.example.net: standby Online: [ cluster1.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster1.example.net HTTPD (ocf::heartbeat:apache): Stopped Failed Resource Actions: * HTTPD_start_0 on cluster1.example.net 'not installed' (5): call=24, status=complete, exitreason='environment is invalid, resource considered stopped', last-rc-change='Mon Jun 29 22:24:19 2020', queued=0ms, exec=36ms
HTTPDについてはリソースは停止したままです。たとえノードがOnline状態であっても、Failed Resource Actionsとして傷害の記録が残っているものは切り替わりません。そのため、下記コマンドで障害の状態をリセットする必要があります。
[root@cluster1 conf]# pcs resource cleanup Cleaned up VIP on cluster3.example.net Cleaned up VIP on cluster2.example.net Cleaned up VIP on cluster1.example.net Cleaned up HTTPD on cluster3.example.net Cleaned up HTTPD on cluster2.example.net Cleaned up HTTPD on cluster1.example.net Waiting for 1 reply from the CRMd. OK [root@cluster1 conf]# pcs status Cluster name: httpcluster Stack: corosync Current DC: cluster3.example.net (version 1.1.21-4.el7-f14e36fd43) - partition with quorum Last updated: Mon Jun 29 22:41:35 2020 Last change: Mon Jun 29 22:41:30 2020 by hacluster via crmd on cluster1.example.net 3 nodes configured 2 resources configured Node cluster2.example.net: standby Node cluster3.example.net: standby Online: [ cluster1.example.net ] Full list of resources: Resource Group: httpgroup VIP (ocf::heartbeat:IPaddr2): Started cluster1.example.net HTTPD (ocf::heartbeat:apache): Started cluster1.example.net
Failed Resource Actionsについては見落としやすいので注意したほうがよいです。