CentOS 7でPacemaker、Corosync、Floating IPを使用して高可用性セットアップを作成する方法

前書き

Corosyncは、アプリケーション内に高可用性を実装するために使用されるオープンソースのクラスターエンジンです。 一般にmessaging layerと呼ばれる、Corosyncは、複製されたステートマシンを作成するためのクラスターメンバーシップとクローズドコミュニケーションモデルを提供し、その上でPacemakerなどのクラスターリソースマネージャーを実行できます。 Corosyncはクラスターノードを相互に接続する基盤システムと見なすことができますが、Pacemakerはクラスターを監視し、障害発生時にアクションを実行します。

このチュートリアルでは、CorosyncとPacemakerを使用して、CentOS 7サーバーとフローティングIPを備えたDigitalOcean上に高可用性(HA)インフラストラクチャを作成する方法を示します。 クラスターノードのセットアップと管理のプロセスを容易にするために、CorosyncとPacemakerの両方と対話するコマンドラインインターフェイスであるPCSを使用します。

前提条件

このガイドに従うには、次のものが必要です。

  • 同じデータセンターにある2つのCentOS7ドロップレットで、Private Networkが有効になっています

  • Initial Server Setupチュートリアルに従って設定できる非rootsudoユーザー

  • DigitalOcean APIへのパーソナルアクセストークン。チュートリアルHow to Use the DigitalOcean API V2に従って生成できます。

これらのドロップレットを作成するときは、説明的なホスト名を使用してそれらを一意に識別します。 このチュートリアルでは、これらのドロップレットをprimaryおよびsecondaryと呼びます。

先に進む準備ができたら、sudoユーザーで両方のサーバーにログインしていることを確認してください。

[[step-1 -—- set-up-nginx]] ==ステップ1—Nginxを設定する

処理を高速化するために、Nginxをインストールし、その特定のサーバーに関する情報を含む基本的なWebページを設定する単純なshell scriptを使用します。 この方法により、フローティングIPセットアップで現在アクティブなサーバーを簡単に識別できます。 スクリプトは、DigitalOceanのMetadata serviceを使用して、ドロップレットのIPアドレスとホスト名をフェッチします。

スクリプトを実行するには、両方のサーバーで次のコマンドを実行します。

sudo curl -L -o install.sh http://do.co/nginx-centos
sudo chmod +x install.sh
sudo ./install.sh

スクリプトの実行が完了したら、ブラウザからパブリックIPアドレスを介していずれかのDropletにアクセスすると、Dropletのホスト名とIPアドレスを示す基本的なWebページが表示されます。

このチュートリアルの複雑さを軽減するために、クラスターノードとして単純なWebサーバーを使用します。 実稼働環境では、ノードは通常、冗長ロードバランサーとして機能するように構成されます。 ロードバランサーの詳細については、Introduction to HAProxy and Load Balancing Conceptsガイドをご覧ください。

[[step-2 -—- create-and-assign-floating-ip]] ==ステップ2—フローティングIPを作成して割り当てる

最初のステップは、フローティングIPを作成し、それをprimaryサーバーに割り当てることです。 DigitalOceanコントロールパネルで、トップメニューのNetworkingをクリックし、次にサイドメニューのFloating IPsをクリックします。

次のようなページが表示されるはずです。

Floating IPs Control Panel

primaryサーバーを選択し、[フローティングIPの割り当て]ボタンをクリックします。 フローティングIPが割り当てられたら、ブラウザからフローティングIPアドレスにアクセスして、primaryドロップレットに到達できることを確認します。

http://your_floating_ip

プライマリドロップレットのインデックスページが表示されます。

[[step-3 -—- create-ip-reassignment-script]] ==ステップ3—IP再割り当てスクリプトを作成する

この手順では、DigitalOcean APIを使用して、フローティングIPを別のドロップレットに再割り当てする方法を示します。 後で、クラスターがノードの1つで障害を検出したときにこのスクリプトを実行するようにPacemakerを構成します。

この例では、Floating IPアドレスとDroplet IDを引数として使用して、Floating IPを特定のDropletに割り当てる基本的なPythonスクリプトを使用します。 ドロップレットのIDは、メタデータサービスを使用してドロップレット自体から取得できます。

assign-ipスクリプトをダウンロードして、実行可能にすることから始めましょう。 スクリプトをダウンロードする前に、スクリプトの内容を自由に確認してください。

次の2つのコマンドは、both servers(プライマリおよびセカンダリ)で実行する必要があります。

sudo curl -L -o /usr/local/bin/assign-ip http://do.co/assign-ip
sudo chmod +x /usr/local/bin/assign-ip

assign-ipスクリプトを実行するには、次の情報が必要です。

  • Floating IP:スクリプトの最初の引数、割り当てられているフローティングIP

  • Droplet ID:スクリプトの2番目の引数、フローティングIPを割り当てる必要のあるドロップレットID

  • DigitalOcean API Token:環境変数DO_TOKEN、読み取り/書き込みDigitalOceanパーソナルアクセストークンとして渡されます

IP再割り当てスクリプトのテスト

発生しているIPの再割り当てを監視するために、curlコマンドを使用して、各要求の間に1秒の間隔でループ内のフローティングIPアドレスにアクセスできます。

新しいローカルターミナルを開き、次のコマンドを実行します。必ずfloating_IP_addressを実際のフローティングIPアドレスに置き換えてください。

while true; do curl floating_IP_address; sleep 1; done

このコマンドは、CTRL+Cで中断されるまで、アクティブな端末で実行され続けます。 フローティングIPが現在割り当てられているサーバーによってホストされているWebページを取得するだけです。 出力は次のようになります。

OutputDroplet: primary, IP Address: primary_IP_address
Droplet: primary, IP Address: primary_IP_address
Droplet: primary, IP Address: primary_IP_address
...

次に、assign-ipスクリプトを実行して、フローティングIPをsecondaryドロップレットに再割り当てしましょう。 DigitalOceanのメタデータサービスを使用して現在のドロップレットIDを取得し、スクリプトへの引数として使用します。 メタデータサービスからDropletのIDを取得するには、次のようにします。

curl -s http://169.254.169.254/metadata/v1/id

ここで、169.254.169.254はメタデータサービスによって使用される静的IPアドレスであるため、変更しないでください。 この情報は、ドロップレット内からのみ利用できます。

スクリプトを実行する前に、DigitalOcean APIトークンを含むDO_TOKEN環境変数を設定する必要があります。 secondaryサーバーから次のコマンドを実行し、your_api_tokenをDigitalOceanAPIへの読み取り/書き込みパーソナルアクセストークンに置き換えることを忘れないでください。

export DO_TOKEN=your_api_token

引き続きsecondaryサーバーで、assign-ipスクリプトを実行し、floating_IP_addressをフローティングIPアドレスに置き換えます。

assign-ip floating_IP_address `curl -s http://169.254.169.254/metadata/v1/id`
OutputMoving IP address: in-progress

ローカル端末でcurlコマンドによって生成された出力を監視すると、フローティングIPが割り当てられたIPアドレスを変更し、数秒後にsecondaryドロップレットをポイントし始めることがわかります。

OutputDroplet: primary, IP Address: primary_IP_address
Droplet: primary, IP Address: primary_IP_address
Droplet: secondary, IP Address: secondary_IP_address

ブラウザからフローティングIPアドレスにアクセスすることもできます。 secondaryドロップレット情報を示すページが表示されます。 これは、再割り当てスクリプトが期待どおりに機能したことを意味します。

フローティングIPをプライマリサーバーに再割り当てするには、2段階のプロセスを繰り返しますが、今回はprimaryドロップレットから:

export DO_TOKEN=your_api_token
assign-ip floating_IP_address `curl -s http://169.254.169.254/metadata/v1/id`

数秒後、フローティングIPはプライマリドロップレットを再度指すようになります。

[[step-4 -—- install-corosync-pacemaker-and-pcs]] ==ステップ4— Corosync、Pacemaker、およびPCSをインストールします

次のステップでは、Corosync、Pacemaker、PCSをドロップレットにインストールします。 CorosyncはPacemakerの依存関係であるため、通常はPacemakerをインストールし、インストールするCorosyncバージョンをシステムに決定させる方が良いでしょう。

ソフトウェアパッケージをboth serversにインストールします。

sudo yum install pacemaker pcs

PCSユーティリティは、インストール中に、パスワードが無効になっているhaclusterという名前の新しいシステムユーザーを作成します。 両方のサーバーでこのユーザーのパスワードを定義する必要があります。 これにより、PCSは、複数ノードでのCorosync構成の同期、クラスターの開始および停止などのタスクを実行できます。

both serversで、次を実行します。

passwd hacluster

両方のサーバーでsame passwordを使用する必要があります。 次のステップで、このパスワードを使用してクラスターを構成します。

[.note]#ユーザーhaclusterには、アカウントに関連付けられたインタラクティブなシェルまたはホームディレクトリがありません。つまり、その資格情報を使用してサーバーにログインすることはできません。

[[step-5 --- setup-up-the-cluster]] ==ステップ5—クラスターをセットアップします

両方のサーバーにCorosync、Pacemaker、およびPCSがインストールされたので、クラスターをセットアップできます。

PCSの有効化と起動

PCSデーモンを有効にして起動するには、both serversで以下を実行します。

sudo systemctl enable pcsd.service
sudo systemctl start pcsd.service

各ノードのプライベートネットワークIPアドレスの取得

ネットワークのパフォーマンスとセキュリティを向上させるには、ノードをprivate networkを使用して接続する必要があります。 DropletのプライベートネットワークIPアドレスを取得する最も簡単な方法は、メタデータサービスを使用することです。 各サーバーで、次のコマンドを実行します。

curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo

このコマンドは、ログインしているDropletのプライベートネットワークIPアドレスを単に出力します。 この情報は、DropletのページのDigitalOceanコントロールパネル(Settingsタブの下)にもあります。

次の手順のために、両方のドロップレットからプライベートネットワークIPアドレスを収集します。

クラスターノードの認証

ユーザー名haclusterと、手順3で定義したものと同じパスワードを使用してクラスターノードを認証します。 各ノードのプライベートネットワークIPアドレスを提供する必要があります。 primaryサーバーから、以下を実行します。

sudo pcs cluster auth primary_private_IP_address secondary_private_IP_address

次のような出力が得られるはずです。

OutputUsername: hacluster
Password:
primary_private_IP_address: Authorized
secondary_private_IP_address: Authorized

Corosync設定の生成

まだprimaryサーバーで、次のコマンドを使用してCorosync構成ファイルを生成します。

sudo pcs cluster setup --name webcluster \
primary_private_IP_address secondary_private_IP_address

出力は次のようになります。

OutputShutting down pacemaker/corosync services...
Redirecting to /bin/systemctl stop  pacemaker.service
Redirecting to /bin/systemctl stop  corosync.service
Killing any remaining services...
Removing all cluster configuration files...
primary_private_IP_address: Succeeded
secondary_private_IP_address: Succeeded
Synchronizing pcsd certificates on nodes primary_private_IP_address, secondary_private_IP_address...
primary_private_IP_address: Success
secondary_private_IP_address: Success

Restaring pcsd on the nodes in order to reload the certificates...
primary_private_IP_address: Success
secondary_private_IP_address: Success

これにより、pcs cluster setupコマンドに指定されたパラメーターに基づいて、/etc/corosync/corosync.confにある新しい構成ファイルが生成されます。 この例では、クラスター名としてwebclusterを使用しましたが、任意の名前を使用できます。

クラスターの開始

セットアップしたばかりのクラスターを開始するには、primaryサーバーから次のコマンドを実行します。

sudo pcs cluster start --all
Outputprimary_private_IP_address: Starting Cluster...
secondary_private_IP_address: Starting Cluster...

これで、いずれかのサーバーで次のコマンドを実行して、両方のノードがクラスターに参加したことを確認できます。

sudo pcs status corosync
OutputMembership information
----------------------
    Nodeid      Votes Name
         2          1 secondary_private_IP_address
         1          1 primary_private_IP_address (local)

クラスタの現在のステータスに関する詳細情報を取得するには、次を実行できます。

sudo pcs cluster status

出力は次のようになります。

OutputCluster Status:
 Last updated: Fri Dec 11 11:59:09 2015     Last change: Fri Dec 11 11:59:00 2015 by hacluster via crmd on secondary
 Stack: corosync
 Current DC: secondary (version 1.1.13-a14efad) - partition with quorum
 2 nodes and 0 resources configured
 Online: [ primary secondary ]

PCSD Status:
  primary (primary_private_IP_address): Online
  secondary (secondary_private_IP_address): Online

これで、corosyncおよびpacemakerサービスを有効にして、システムの起動時にそれらが開始されることを確認できます。 both serversで以下を実行します。

sudo systemctl enable corosync.service
sudo systemctl enable pacemaker.service

STONITHを無効にする

STONITH(ヘッドのもう一方のノードを撃つ)は、応答しないがまだアプリケーションデータにアクセスしているクラスター内の障害のあるノードによって引き起こされるデータ破損を防ぐためのフェンシング手法です。 その構成は、このガイドの範囲外のいくつかの要因に依存するため、クラスターのセットアップでSTONITHを無効にします。

STONITHを無効にするには、プライマリまたはセカンダリのいずれかのドロップレットで次のコマンドを実行します。

sudo pcs property set stonith-enabled=false

[[step-6 -—- create-floating-ip-reassignment-resource-agent]] ==ステップ6—フローティングIP再割り当てリソースエージェントを作成する

あとは、クラスタノードの1つで障害が検出されたときにIP再割り当てスクリプトを実行するリソースエージェントを設定するだけです。 リソースエージェントは、クラスターとリソース自体の間にインターフェイスを作成する役割を果たします。 この場合、リソースはassign-ipスクリプトです。 クラスターは、start、stop、またはmonitorコマンドが与えられたときに、リソースエージェントに依存して正しい手順を実行します。 リソースエージェントにはさまざまな種類がありますが、最も一般的なものはOCF(Open Cluster Framework)標準です。

両方のサーバーでassign-ipサービスを管理するために、新しいOCFリソースエージェントを作成します。

最初に、リソースエージェントを含むディレクトリを作成します。 ディレクトリ名は、このカスタムエージェントの識別子としてPacemakerによって使用されます。 both serversで以下を実行します。

sudo mkdir /usr/lib/ocf/resource.d/digitalocean

次に、FloatIPリソースエージェントスクリプトをダウンロードして、新しく作成したディレクトリのboth serversに配置します。

sudo curl -L -o /usr/lib/ocf/resource.d/digitalocean/floatip http://do.co/ocf-floatip

次に、both serversで次のコマンドを使用してスクリプトを実行可能にします。

sudo chmod +x /usr/lib/ocf/resource.d/digitalocean/floatip

PCSユーティリティを使用して、クラスター内にリソースエージェントを登録する必要があります。 次のコマンドは、ノードのoneから実行する必要があります(your_api_tokenをDigitalOcean APIトークンに、floating_IP_addressを実際のフローティングIPアドレスに置き換えることを忘れないでください)。

sudo pcs resource create FloatIP ocf:digitalocean:floatip \
    params do_token=your_api_token \
    floating_ip=floating_IP_address

これで、リソースがクラスターに登録され、アクティブになります。 pcs statusコマンドを使用して、任意のノードから登録済みリソースを確認できます。

sudo pcs status
Output...
2 nodes and 1 resource configured

Online: [ primary secondary ]

Full list of resources:

 FloatIP    (ocf::digitalocean:floatip):    Started primary

...

[[step-7 --- test-failover]] ==ステップ7—フェイルオーバーのテスト

これで、クラスターはノード障害を処理する準備ができました。 フェールオーバーをテストする簡単な方法は、フローティングIPセットアップで現在アクティブなサーバーを再起動することです。 このチュートリアルのすべての手順を実行した場合、これはprimaryサーバーである必要があります。

繰り返しになりますが、ループ内でcurlコマンドを使用して、IPの再割り当てを監視しましょう。 ローカル端末から、次を実行します。

while true; do curl floating_IP_address; sleep 1; done

primaryサーバーから、再起動コマンドを実行します。

sudo reboot

しばらくすると、プライマリサーバーが使用できなくなります。 これにより、セカンダリサーバーがアクティブノードを引き継ぎます。 curlを実行しているローカル端末に次のような出力が表示されます。

Output...
Droplet: primary, IP Address: primary_IP_address
Droplet: primary, IP Address: primary_IP_address
curl: (7) Failed connect to floating_IP_address; Connection refused
Droplet: secondary, IP Address: secondary_IP_address
Droplet: secondary, IP Address: secondary_IP_address
…

[.note]#「接続が拒否されました」エラーは、IPの再割り当てが行われる直前または同時に要求が行われた場合に発生します。 出力に表示される場合と表示されない場合があります。

セカンダリノードでフェイルオーバーをテストしながら、フローティングIPをプライマリノードに戻す場合は、プロセスを繰り返しますが、今回はsecondaryドロップレットから:

sudo reboot

結論

このガイドでは、フローティングIPをCorosync、Pacemaker、PCSとともに使用して、CentOS 7サーバー上で高可用性Webサーバー環境を作成する方法を説明しました。 フローティングIPの使用法を示すためにかなり単純なインフラストラクチャを使用しましたが、このセットアップを拡張して、アプリケーションスタックのどのレベルでも高可用性を実装できます。

Related