前書き

高可用性はシステム設計の機能であり、障害が発生した場合にアプリケーションが自動的に再起動するか、作業を別の対応システムに再ルーティングできるようにします。 サーバーに関しては、可用性の高いシステムをセットアップするために必要なテクノロジーがいくつかあります。 作業をリダイレクトできるコンポーネントが必要です。また、障害を監視し、中断が検出された場合にシステムを移行するメカニズムが必要です。

`+ keepalived `デーモンを使用して、サービスまたはシステムを監視し、問題が発生した場合にスタンバイに自動的にフェールオーバーできます。 このガイドでは、 ` keepalived +`を使用して高可用性Webサービスをセットアップする方法を示します。 2つの対応するWebサーバー間で移動できるhttps://www.digitalocean.com/community/tutorials/how-to-use-floating-ips-on-digitalocean[floating IP address]を構成します。 プライマリサーバーがダウンした場合、フローティングIPは自動的に2番目のサーバーに移動され、サービスを再開できます。

前提条件

このガイドを完了するには、DigitalOceanアカウントに2つのUbuntu 14.04サーバーを作成する必要があります。 両方のサーバーは同じデータセンター内に配置する必要があり、プライベートネットワーキングを有効にする必要があります。

これらの各サーバーでは、 `+ sudo +`アクセスで設定された非rootユーザーが必要です。 これらのユーザーのセットアップ方法については、https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [Ubuntu 14.04初期サーバーセットアップガイド]を参照してください。

開始する準備ができたら、root以外のユーザーで両方のサーバーにログインします。

Nginxのインストールと構成

「+ keepalived +」はロードバランサーの監視とフェイルオーバーによく使用されますが、運用の複雑さを軽減するために、このガイドではNginxを単純なWebサーバーとして使用します。

各サーバーのローカルパッケージインデックスを更新することから始めます。 その後、Nginxをインストールできます。

sudo apt-get update
sudo apt-get install nginx

ほとんどの場合、可用性の高いセットアップでは、両方のサーバーでまったく同じコンテンツを提供する必要があります。 ただし、わかりやすくするために、このガイドではNginxを使用して、2つのサーバーのどちらがいつでもリクエストを処理していることを示します。 これを行うには、各ホストのデフォルトの `+ index.html`ページを変更します。 今すぐファイルを開きます。

sudo nano /usr/share/nginx/html/index.html

最初のサーバーで、ファイルの内容を次のものに置き換えます。

プライマリサーバーの/usr/share/nginx/html/index.html

<h1>Primary</h1>

2番目のサーバーで、ファイルの内容を次のように置き換えます。

セカンダリサーバーの/usr/share/nginx/html/index.html

<h1>Secondary</h1>

完了したら、ファイルを保存して閉じます。

Keepalivedのビルドとインストール

次に、サーバーに `+ keepalived `デーモンをインストールします。 Ubuntuのデフォルトリポジトリには「 keepalived」のバージョンがありますが、それは時代遅れであり、構成が機能しなくなるいくつかのバグに悩まされています。 代わりに、ソースから `+ keepalived +`の最新バージョンをインストールします。

開始する前に、ソフトウェアのビルドに必要な依存関係を取得する必要があります。 `+ build-essential `メタパッケージは必要なコンパイルツールを提供し、 ` libssl-dev `パッケージには ` keepalived +`がビルドする必要のあるSSLライブラリが含まれます。

sudo apt-get install build-essential libssl-dev

依存関係が整ったら、 `+ keepalived `のtarballをダウンロードできます。 ソフトウェアの最新バージョンを見つけるには、http://www.keepalived.org/download.html [このページ]にアクセスしてください。 最新バージョンを右クリックして、リンクアドレスをコピーします。 サーバーに戻り、ホームディレクトリに移動して、 ` wget +`を使用してコピーしたリンクを取得します。

cd ~
wget http://www.keepalived.org/software/keepalived-.tar.gz

`+ tar +`コマンドを使用してアーカイブを展開し、結果のディレクトリに移動します。

tar xzvf keepalived*
cd keepalived*

次を入力して、デーモンをビルドおよびインストールします。

./configure
make
sudo make install

これでデーモンがシステムにインストールされました。

Keepalived Upstartスクリプトを作成する

`+ keepalived +`のインストールにより、すべてのバイナリとサポートファイルがシステム上の所定の場所に移動しました。 ただし、含まれていないものの1つは、Ubuntu 14.04システムのUpstartスクリプトです。

`+ keepalived `サービスを処理できる非常にシンプルなUpstartスクリプトを作成できます。 ` / etc / init `ディレクトリ内の ` keepalived.conf +`というファイルを開いて開始します:

sudo nano /etc/init/keepalived.conf

内部では、 `+ keepalived `が提供する機能の簡単な説明から始めることができます。 付属の「 man +」ページの説明を使用します。 次に、サービスを開始および停止するランレベルを指定します。 このサービスは、すべての通常の状態(ランレベル2〜5)でアクティブになり、他のすべてのランレベル(たとえば、再起動、電源オフ、またはシングルユーザーモードが開始されたとき)で停止します。

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

このサービスはWebサービスを引き続き利用できるようにするために不可欠なので、障害が発生した場合にこのサービスを再起動する必要があります。 その後、サービスを開始する実際の `+ exec `行を指定できます。 Upstartが ` pid `を正しく追跡できるように、 `-dont-fork +`オプションを追加する必要があります。

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/local/sbin/keepalived --dont-fork

完了したら、ファイルを保存して閉じます。

Keepalived構成ファイルを作成する

Upstartファイルを用意したら、 `+ keepalived +`の設定に進むことができます。

サービスは `+ / etc / keepalived +`ディレクトリで設定ファイルを探します。 両方のサーバーでそのディレクトリを作成します。

sudo mkdir -p /etc/keepalived

サーバーのプライベートIPアドレスを収集する

構成ファイルを作成する前に、両方のサーバーのプライベートIPアドレスを見つける必要があります。 DigitalOceanサーバーでは、次のように入力して、メタデータサービスからプライベートIPアドレスを取得できます。

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

これは、「+ iproute2 +」ツールで次のように入力することでも見つけることができます。

ip -4 addr show dev eth1

探している値は次のとおりです。

Output3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /16 brd 10.132.255.255 scope global eth1
      valid_lft forever preferred_lft forever

両方のシステムからこの値をコピーします。 以下の構成ファイル内でこれらのアドレスを参照する必要があります。

プライマリサーバーの構成の作成

次に、プライマリサーバーで、メインの `+ keepalived `設定ファイルを作成します。 デーモンは、 ` / etc / keepalived `ディレクトリ内で ` keepalived.conf +`というファイルを探します:

sudo nano /etc/keepalived/keepalived.conf

内部では、 `+ vrrp_script `ブロックを開いてNginxサービスのヘルスチェックを定義することから始めます。 これにより、 ` keepalived`がWebサーバーの障害を監視できるようになり、プロセスがダウンしていることを通知し、対策を回復できるようになります。

チェックは非常に簡単です。 2秒ごとに、 `+ nginx `というプロセスがまだ ` pid +`を要求していることを確認します。

プライマリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

次に、 `+ vrrp_instance `というブロックを開きます。 これは、「 keepalived +」が高可用性を実装する方法を定義するメインの設定セクションです。

まず、プライベートインターフェイスである「+ eth1 」を介してピアと通信するように「 keepalived 」に指示します。 プライマリサーバーを設定しているので、 ` state `設定を“ MASTER”に設定します。 これは、デーモンがピアにコンタクトして選択を保持できるようになるまで、「 keepalived +」が使用する初期値です。

選挙中に、「+ priority +」オプションを使用して、選出されるメンバーを決定します。 決定は、どのサーバーがこの設定の最大数を持っているかに基づいています。 プライマリサーバーには「200」を使用します。

プライマリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

vrrp_instance VI_1 {
   interface eth1
   state MASTER
   priority 200


}

次に、両方のノードで共有されるこのクラスターグループにIDを割り当てます。 この例では「33」を使用します。 以前に取得した* primary *サーバーのプライベートIPアドレスに `+ unicast_src_ip `を設定する必要があります。 ` unicast_peer +`を*セカンダリ*サーバーのプライベートIPアドレスに設定します:

プライマリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

vrrp_instance VI_1 {
   interface eth1
   state MASTER
   priority 200

   virtual_router_id 33
   unicast_src_ip
   unicast_peer {

   }


}

次に、 `+ keepalived `デーモンが互いに通信するための簡単な認証を設定できます。 これは、問題のサーバーが正当であることを確認するための基本的な手段にすぎません。 ` authentication`サブブロックを作成します。 内部では、 `+ auth_type `を設定してパスワード認証を指定します。 ` auth_pass +`パラメーターには、両方のノードで使用される共有シークレットを設定します。 残念ながら、重要なのは最初の8文字のみです。

プライマリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

vrrp_instance VI_1 {
   interface eth1
   state MASTER
   priority 200

   virtual_router_id 33
   unicast_src_ip
   unicast_peer {

   }

   authentication {
       auth_type PASS
       auth_pass
   }


}

次に、ファイルの先頭で作成した「+ chk_nginx 」というラベルの付いたルーチンを使用してローカルシステムの健全性を判断するように、「 keepalived 」に指示します。 最後に、このノードがペアの「マスター」になるたびに実行される ` notify_master +`スクリプトを設定します。 このスクリプトは、フローティングIPアドレスの再割り当てをトリガーします。 このスクリプトを一時的に作成します。

プライマリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

vrrp_instance VI_1 {
   interface eth1
   state MASTER
   priority 200

   virtual_router_id 33
   unicast_src_ip
   unicast_peer {

   }

   authentication {
       auth_type PASS
       auth_pass
   }

   track_script {
       chk_nginx
   }

   notify_master /etc/keepalived/master.sh
}

上記の情報を設定したら、ファイルを保存して閉じます。

セカンダリサーバーの構成の作成

次に、セカンダリサーバーでコンパニオンスクリプトを作成します。 セカンダリサーバー上の `+ / etc / keepalived / keepalived.conf +`でファイルを開きます。

sudo nano /etc/keepalived/keepalived.conf

内部では、使用するスクリプトは主サーバーのスクリプトとほぼ同等です。 変更する必要がある項目は次のとおりです。

  • + state +:これは、選択が行われる前にノードがバックアップ状態に初期化されるように、セカンダリサーバーで「BACKUP」に変更する必要があります。

  • + priority +:これは、プライマリサーバーよりも低い値に設定する必要があります。 このガイドでは、値「100」を使用します。

  • + unicast_src_ip +:これは* secondary *サーバーのプライベートIPアドレスでなければなりません。

  • + unicast_peer +:これには、*プライマリ*サーバーのプライベートIPアドレスが含まれている必要があります。

これらの値を変更すると、セカンダリサーバーのスクリプトは次のようになります。

セカンダリサーバーの/etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
   script "pidof nginx"
   interval 2
}

vrrp_instance VI_1 {
   interface eth1
   state
   priority

   virtual_router_id 33
   unicast_src_ip
   unicast_peer {

   }

   authentication {
       auth_type PASS
       auth_pass
   }

   track_script {
       chk_nginx
   }

   notify_master /etc/keepalived/master.sh
}

スクリプトを入力して適切な値を変更したら、ファイルを保存して閉じます。

フローティングIP移行スクリプトを作成する

次に、ローカルの `+ keepalived +`インスタンスがマスターサーバーになるたびに、現在のドロップレットにフローティングIPアドレスを再割り当てするために使用できるスクリプトのペアを作成する必要があります。

フローティングIP割り当てスクリプトをダウンロードする

まず、汎用のPythonスクリプト(https://www.digitalocean.com/community/users/asb[DigitalOceanコミュニティマネージャー]が作成)をダウンロードします。これは、DigitalOceanを使用してフローティングIPアドレスをDropletに再割り当てするために使用できます。 API。 このファイルを `+ / usr / local / bin +`ディレクトリにダウンロードする必要があります。

cd /usr/local/bin
sudo curl -LO http://do.co/assign-ip

このスクリプトを使用すると、次を実行して既存のフローティングIPを再割り当てできます。

python /usr/local/bin/assign-ip

これは、アカウントの有効なDigitalOcean APIトークンに設定された `+ DO_TOKEN +`という環境変数がある場合にのみ機能します。

DigitalOcean APIトークンを作成する

上記のスクリプトを使用するには、アカウントにDigitalOcean APIトークンを作成する必要があります。

コントロールパネルで、上部の[API]リンクをクリックします。 APIページの右側で、「新しいトークンを生成」をクリックします。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/generate_api_token.png [DigitalOcean generate API token]

次のページで、トークンの名前を選択し、「トークンの生成」ボタンをクリックします。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/make_token.png [DigitalOcean make new token]

APIページに、新しいトークンが表示されます:

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/new_token.png [DigitalOceanトークン]

トークンをコピーします* now *。 セキュリティのため、後でこのトークンを再度表示する方法はありません。 このトークンを紛失した場合、それを破棄して別のトークンを作成する必要があります。

インフラストラクチャにフローティングIPを構成する

次に、サーバーで使用するフローティングIPアドレスを作成して割り当てます。

DigitalOceanコントロールパネルで、「ネットワーク」タブをクリックし、「フローティングIP」ナビゲーション項目を選択します。 「プライマリ」サーバーとして割り当てたリストからドロップレットを選択します。

image:https://assets.digitalocean.com/site/ControlPanel/fip_assign_to_primary.png [DigitalOcean add floating IP]

アカウントに新しいフローティングIPアドレスが作成され、指定されたドロップレットに割り当てられます。

image:https://assets.digitalocean.com/site/ControlPanel/fip_assigned_to_primary.png [DigitalOceanフローティングIP割り当て]

WebブラウザでフローティングIPにアクセスすると、「プライマリ」サーバーの `+ index.html`ページが表示されます。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/primary_index.png [DigitalOcean primary index.html]

フローティングIPアドレスをコピーします。 以下のスクリプトでこの値が必要になります。

ラッパースクリプトを作成する

これで、正しい認証情報で `+ / usr / local / bin / assign-ip +`スクリプトを呼び出すラッパースクリプトを作成するために必要なアイテムができました。

次のように入力して、*両方*サーバーでファイルを作成します。

sudo nano /etc/keepalived/master.sh

内部では、作成したAPIトークンを保持する `+ DO_TOKEN `という変数を割り当ててエクスポートすることから始めます。 その下で、フローティングIPアドレスを保持する「 IP +」という変数を割り当てることができます。

/etc/keepalived/master.sh

export DO_TOKEN=''
IP=''

次に、 `+ curl `を使用して、現在使用しているサーバーのDroplet IDをメタデータサービスに要求します。 これは、「 ID 」という変数に割り当てられます。 また、このDropletに現在フローティングIPアドレスが割り当てられているかどうかを尋ねます。 そのリクエストの結果を ` HAS_FLOATING_IP +`という変数に保存します:

/etc/keepalived/master.sh

export DO_TOKEN=''
IP=''
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

これで、上記の変数を使用して `+ assign-ip +`スクリプトを呼び出すことができます。 フローティングIPがドロップレットに関連付けられていない場合にのみ、スクリプトを呼び出します。 これにより、API呼び出しが最小限に抑えられ、マスターステータスがサーバー間で急速に切り替わる場合に、APIへの競合する要求を防ぐことができます。

フローティングIPで既に進行中のイベントがある場合に対処するために、 `+ assign-ip +`スクリプトを数回再試行します。 以下では、各呼び出しの間に3秒間隔で、スクリプトを10回実行しようとします。 フローティングIPの移動が成功すると、ループはすぐに終了します。

/etc/keepalived/master.sh

export DO_TOKEN=''
IP=''
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

if [ $HAS_FLOATING_IP = "false" ]; then
   n=0
   while [ $n -lt 10 ]
   do
       python /usr/local/bin/assign-ip $IP $ID && break
       n=$((n+1))
       sleep 3
   done
fi

完了したら、ファイルを保存して閉じます。

ここで、スクリプトを実行可能にして、 `+ keepalived +`で呼び出せるようにするだけです。

sudo chmod +x /etc/keepalived/master.sh

Keepalivedサービスの起動とフェールオーバーのテスト

`+ keepalived +`デーモンとそのすべてのコンパニオンスクリプトは完全に設定されているはずです。 次のように入力して、両方のマシンでサービスを開始できます。

sudo start keepalived

サービスは各サーバーで起動し、ピアに接続して、構成した共有シークレットで認証する必要があります。 各デーモンはローカルのNginxプロセスを監視し、リモートの `+ keepalived +`プロセスからのシグナルをリッスンします。

両方のサーバーが正常な場合、WebブラウザーでフローティングIPにアクセスすると、プライマリサーバーのNginxページに移動します。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/primary_index.png [DigitalOcean primary index.html]

これで、構成のフェイルオーバー機能をテストする準備が整いました。

次のいずれかの条件が発生すると、フェールオーバーが発生します。

  • *プライマリサーバーのNginxヘルスチェックでNginxが実行されていないことが示された場合。*この場合、プライマリサーバーの「+ keepalived +」デーモンは「障害」状態になります。 セカンダリサーバーに、マスター状態に移行し、フローティングIPを要求する必要があることを通知します。

  • セカンダリサーバーがプライマリサーバーへの「+ keepalived +」接続を失ったとき。 セカンダリサーバーが何らかの理由でプライマリサーバーに到達できない場合、「マスター」状態に移行し、フローティングIPを要求しようとします。

プライマリサーバーが後で回復した場合、マスターサーバーは新しい選択を開始するため、フローティング状態のIPを回収します(最高の優先順位番号を保持します)。

Nginxの障害のテスト

プライマリサーバーでNginxサービスを停止することにより、最初の条件をテストできます。

sudo service nginx stop

Webブラウザを更新すると、最初にページが利用できないことを示す応答を受け取る場合があります。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/page_not_available.png [DigitalOceanページは利用できません]

ただし、数秒後にページを数回更新すると、セカンダリサーバーがフローティングIPアドレスを要求したことがわかります。

画像:https://assets.digitalocean.com/articles/keepalived_nginx_1404/secondary_index.png [DigitalOcean secondary index.html]

プライマリサーバーでNginxデーモンを再起動することで、障害から回復できます。

sudo service nginx start

数秒後、ページを更新すると、プライマリサーバーが再びフローティングIPの所有権を取り戻したことがわかります。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/primary_index.png [DigitalOcean primary index.html]

サーバー障害のテスト

テストする必要があるもう1つのシナリオは、プライマリサーバーに接続できない場合にセカンダリがマスター状態に正しく移行するかどうかです。 これをテストするためにマスターサーバーを再起動できます。

sudo reboot

繰り返しますが、最初はフローティングIPアドレスでサービスの中断が発生するはずです。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/page_not_available.png [DigitalOceanページは利用できません]

数秒後、セカンダリサーバーがリクエストを取得します。

画像:https://assets.digitalocean.com/articles/keepalived_nginx_1404/secondary_index.png [DigitalOcean secondary index.html]

しばらくして、プライマリサーバーが再起動を完了すると、IPアドレスを再利用します。

image:https://assets.digitalocean.com/articles/keepalived_nginx_1404/primary_index.png [DigitalOcean primary index.html]

これにより、2番目の障害シナリオが検証されます。

結論

このガイドでは、 + keepalived +、DigitalOcean API、およびフローティングIPアドレスを使用して、可用性の高いWebサーバー環境を構成しました。 実際のインフラストラクチャはかなり単純でしたが、この概念は、サービスの可用性と稼働時間が重要なあらゆるタイプのインフラストラクチャに適用できます。