前書き

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

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

画像:https://assets.digitalocean.com/articles/high_availability/ha-diagram-animated.gif [高可用性図]

前提条件

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

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

サーバーネットワーク情報の検索

インフラストラクチャコンポーネントの実際の構成を開始する前に、各サーバーに関する情報を収集することをお勧めします。

このガイドを完了するには、サーバーに関する次の情報が必要です。

  • ウェブサーバー:プライベートIPアドレス

  • *ロードバランサー*プライベートおよびアンカーIPアドレス

プライベートIPアドレスの検索

DropletのプライベートIPアドレスを見つける最も簡単な方法は、 `+ curl +`を使用してDigitalOceanメタデータサービスからプライベートIPアドレスを取得することです。 このコマンドは、ドロップレット内から実行する必要があります。 各ドロップレットで、次を入力します。

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

ターミナルウィンドウに正しいIPアドレスを印刷する必要があります。

Output10.132.20.236

アンカーIPアドレスの検索

「アンカーIP」は、DigitalOceanサーバーに接続されたときにフローティングIPがバインドするローカルプライベートIPアドレスです。 これは、ハイパーバイザーレベルで実装される通常の「+ eth0 +」アドレスの単なるエイリアスです。

この値を取得する最も簡単でエラーの少ない方法は、DigitalOceanメタデータサービスから直接です。 「+ curl +」を使用すると、次のように入力して、各サーバー上のこのエンドポイントに到達できます。

curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address && echo

アンカーIPは独自の行に印刷されます。

Output10.17.1.18

Webサーバーのインストールと構成

上記のデータを収集したら、サービスの構成に進むことができます。

Note

最初に、バックエンドWebサーバーをセットアップします。 これらのサーバーは両方ともまったく同じコンテンツを提供します。 プライベートIPアドレスを介したWeb接続のみを受け入れます。 これにより、後で設定する2つのHAProxyサーバーのいずれかを経由してトラフィックが送信されるようになります。

ロードバランサーの背後にWebサーバーをセットアップすると、いくつかの同一のWebサーバー間で要求の負荷を分散できます。 トラフィックのニーズの変化に応じて、この層にWebサーバーを追加または削除することで、新しい需要に合わせて簡単に拡張できます。

Nginxのインストール

この機能を提供するために、WebサービングマシンにNginxをインストールします。

Webサーバーとして使用する2台のマシンに「+ sudo +」ユーザーでログインすることから始めます。 各Webサーバーのローカルパッケージインデックスを更新し、次のように入力してNginxをインストールします。

sudo apt-get update
sudo apt-get install nginx

ロードバランサーからのリクエストのみを許可するようにNginxを構成する

次に、Nginxインスタンスを構成します。 Nginxに、サーバーのプライベートIPアドレスでのみリクエストをリッスンするように指示します。 さらに、2つのロードバランサーのプライベートIPアドレスからのリクエストのみを処理します。

これらの変更を行うには、各WebサーバーでデフォルトのNginxサーバーブロックファイルを開きます。

sudo nano /etc/nginx/sites-available/default

まず、 `+ listen `ディレクティブを変更します。 ` listen `ディレクティブを変更して、現在の*ウェブサーバーのプライベートIPアドレス*をポート80でリッスンします。 余分な ` listen +`行を削除します。 これは次のようになります。

/ etc / nginx / sites-available / default

server {
   listen :80;

   . . .

その後、2つの「+ allow 」ディレクティブを設定して、2つのロードバランサーのプライベートIPアドレスから発信されるトラフィックを許可します。 他のすべてのトラフィックを禁止する「 deny all +」ルールでこれをフォローアップします。

/ etc / nginx / sites-available / default

server {
   listen :80;

   allow ;
   allow ;
   deny all;

   . . .

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

次のように入力して、行った変更が有効なNginx構文を表していることをテストします。

sudo nginx -t

問題が報告されていない場合は、次のように入力してNginxデーモンを再起動します。

sudo service nginx restart

変更のテスト

Webサーバーが正しく制限されていることをテストするために、さまざまな場所から `+ curl`を使用してリクエストを行うことができます。

Webサーバー自体で、次のように入力して、ローカルコンテンツの簡単な要求を試すことができます。

curl 127.0.0.1

Nginxサーバーブロックファイルに設定されている制限のため、このリクエストは実際に拒否されます。

Outputcurl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused

これは予想されることであり、実装しようとした動作を反映しています。

これで、*ロードバランサー*のいずれかから、WebサーバーのパブリックIPアドレスのいずれかを要求できます。

curl

繰り返しますが、これは失敗するはずです。 Webサーバーはパブリックインターフェイスをリッスンしておらず、さらにパブリックIPアドレスを使用している場合、Webサーバーはロードバランサーからのリクエストに許可されたプライベートIPアドレスを表示しません。

Outputcurl: (7) Failed to connect to  port 80: Connection refused

ただし、ウェブサーバーの_プライベートIPアドレス_を使用してリクエストを行うように呼び出しを変更した場合、正しく動作するはずです。

curl

デフォルトのNginxの `+ index.html`ページが返されます:

Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

. . .

これを両方のロードバランサーから両方のWebサーバーにテストします。 プライベートIPアドレスに対する各リクエストは成功するはずであり、パブリックアドレスに対する各リクエストは失敗するはずです。

上記の動作が実証されたら、次に進みます。 バックエンドWebサーバーの設定が完了しました。

HAProxyのインストールと構成

次に、HAProxyロードバランサーを設定します。 これらはそれぞれWebサーバーの前に配置され、2つのバックエンドサーバー間でリクエストを分割します。 これらのロードバランサーは完全に冗長です。 常に1つだけがトラフィックを受信します。

HAProxy構成は、両方のWebサーバーに要求を渡します。 ロードバランサーは、アンカーIPアドレスでリクエストをリッスンします。 前述したように、これは、ドロップレットに添付されたときにフローティングIPアドレスがバインドするIPアドレスです。 これにより、フローティングIPアドレスから発信されたトラフィックのみが転送されます。

HAProxyをインストールする

ロードバランサーで行う必要がある最初のステップは、 `+ haproxy +`パッケージをインストールすることです。 これはデフォルトのUbuntuリポジトリにあります。 ロードバランサーのローカルパッケージインデックスを更新し、次のように入力してHAProxyをインストールします。

sudo apt-get update
sudo apt-get install haproxy

HAProxyを構成する

HAProxyを扱うときに変更する必要がある最初の項目は、 `+ / etc / default / haproxy +`ファイルです。 エディターでそのファイルを開きます。

sudo nano /etc/default/haproxy

このファイルは、起動時にHAProxyを開始するかどうかを決定します。 サーバーの電源がオンになるたびにサービスが自動的に開始されるようにするため、 `+ ENABLED +`の値を「1」に変更する必要があります。

/ etc / default / haproxy

# Set ENABLED to 1 if you want the init script to start haproxy.
ENABLED=
# Add extra flags here.
#EXTRAOPTS="-de -m 16"

上記の編集を行った後、ファイルを保存して閉じます。

次に、メインのHAProxy構成ファイルを開くことができます。

sudo nano /etc/haproxy/haproxy.cfg

調整する必要がある最初の項目は、HAProxyが動作するモードです。 TCP、またはレイヤー4の負荷分散を構成します。 これを行うには、 `+ default `セクションの ` mode +`行を変更する必要があります。 また、ログを処理するオプションの直後にオプションを変更する必要があります。

/etc/haproxy/haproxy.cfg

. . .

defaults
   log     global
   mode
   option

. . .

ファイルの最後で、フロントエンドの構成を定義する必要があります。 これにより、HAProxyが着信接続をリッスンする方法が決まります。 HAProxyをロードバランサーのアンカーIPアドレスにバインドします。 これにより、フローティングIPアドレスから発信されるトラフィックをリッスンできます。 簡単にするために、フロントエンドを「www」と呼びます。 また、トラフィックを渡すデフォルトのバックエンドも指定します(すぐに設定します)。

/etc/haproxy/haproxy.cfg

. . .

defaults
   log     global
   mode
   option

. . .

frontend www
   bind    :80
   default_backend nginx_pool

次に、バックエンドセクションを構成できます。 これにより、HAProxyが受信したトラフィックを渡すダウンストリームの場所が指定されます。 私たちの場合、これは設定した両方のNginx WebサーバーのプライベートIPアドレスになります。 従来のラウンドロビンバランシングを指定し、モードを再び「tcp」に設定します。

/etc/haproxy/haproxy.cfg

. . .

defaults
   log     global
   mode
   option

. . .

frontend www
   bind :80
   default_backend nginx_pool

backend nginx_pool
   balance roundrobin
   mode tcp
   server web1 :80 check
   server web2 :80 check

上記の変更が完了したら、ファイルを保存して閉じます。

次のように入力して、行った構成変更が有効なHAProxy構文を表していることを確認します。

sudo haproxy -f /etc/haproxy/haproxy.cfg -c

エラーが報告されていない場合は、次を入力してサービスを再起動します。

sudo service haproxy restart

変更のテスト

もう一度 `+ curl`でテストすることで、設定が有効であることを確認できます。

ロードバランサーサーバーから、ローカルホスト、ロードバランサー自身のパブリックIPアドレス、またはサーバー自身のプライベートIPアドレスをリクエストしてください:

curl 127.0.0.1
curl
curl

これらはすべて、次のようなメッセージで失敗します。

Outputcurl: (7) Failed to connect to  port 80: Connection refused

ただし、ロードバランサーの_アンカーIPアドレス_にリクエストを行うと、正常に完了するはずです:

curl

2つのバックエンドWebサーバーのいずれかからルーティングされたデフォルトのNginx `+ index.html`ページが表示されます。

Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

. . .

この動作がシステムの動作と一致する場合、ロードバランサーは正しく構成されています。

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

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

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

sudo nano /etc/keepalived/keepalived.conf

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

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

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

vrrp_script chk_haproxy {
   script "pidof haproxy"
   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」を使用します。 `+ unicast_src_ip `を* primary *ロードバランサーのプライベートIPアドレスに設定する必要があります。 ` unicast_peer +`を*セカンダリ*ロードバランサーのプライベートIPアドレスに設定します。

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

vrrp_script chk_haproxy {
   script "pidof haproxy"
   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_haproxy {
   script "pidof haproxy"
   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_haproxy 」というラベルの付いたチェックを使用してローカルシステムの健全性を判断するように、「 keepalived 」に指示します。 最後に、このノードがペアの「マスター」になるたびに実行される ` notify_master +`スクリプトを設定します。 このスクリプトは、フローティングIPアドレスの再割り当てをトリガーします。 このスクリプトを一時的に作成します。

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

vrrp_script chk_haproxy {
   script "pidof haproxy"
   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_haproxy
   }

   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_haproxy {
   script "pidof haproxy"
   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_haproxy
   }

   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_haproxy_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にアクセスすると、バックエンドWebサーバーのいずれかから提供されるデフォルトのNginxページが表示されます。

image:https://assets.digitalocean.com/articles/keepalived_haproxy_1404/default_index.png [DigitalOcean default 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

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

現在、フローティングIPアドレスが割り当てられているプラ​​イマリロードバランサーは、リクエストを各バックエンドNginxサーバーに順番に送信します。 通常適用される単純なセッションスティッキがいくつかあり、Webブラウザーを介して要求を行うときに同じバックエンドを取得する可能性が高くなります。

プライマリロードバランサーでHAProxyをオフにするだけで、簡単な方法でフェールオーバーをテストできます。

sudo service haproxy stop

ブラウザでフローティングIPアドレスにアクセスすると、ページが見つからなかったことを示すエラーが一時的に表示される場合があります。

http://

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

ページを数回更新すると、すぐにデフォルトのNginxページが表示されます:

image:https://assets.digitalocean.com/articles/keepalived_haproxy_1404/default_index.png [DigitalOcean default index.html]

HAProxyサービスはプライマリロードバランサーでまだ停止しているため、セカンダリロードバランサーが引き継いだことを示しています。 「+ keepalived +」を使用して、セカンダリサーバーはサービスの中断が発生したことを判別できました。 その後、「マスター」状態に移行し、DigitalOcean APIを使用してフローティングIPを要求しました。

これで、プライマリロードバランサーでHAProxyを再び起動できます。

sudo service haproxy start

プライマリロードバランサーは、すぐにフローティングIPアドレスの制御を取り戻しますが、これはユーザーに対してかなり透過的でなければなりません。

遷移の視覚化

ロードバランサー間の移行をよりよく視覚化するために、移行中にサーバーログの一部を監視できます。

使用されているプロキシサーバーに関する情報はクライアントに返されないため、ログを表示するのに最適な場所は、実際のバックエンドWebサーバーからです。 これらの各サーバーは、どのクライアントがアセットを要求するかに関するログを保持する必要があります。 Nginxサービスの観点から見ると、クライアントは実際のクライアントに代わってリクエストを行うロードバランサーです。

Webサーバーでログを追跡する

各バックエンドWebサーバーで、 `+ / var / log / nginx / access.log `の場所を ` tail +`できます。 これにより、サーバーに対して行われた各リクエストが表示されます。 ロードバランサーはラウンドロビンローテーションを使用してトラフィックを均等に分割するため、各バックエンドWebサーバーは約半分のリクエストを確認する必要があります。

幸いなことに、クライアントアドレスはアクセスログの最初のフィールドです。 単純な `+ awk +`コマンドを使用して値を抽出できます。 Nginx Webサーバーの両方で次を実行します。

sudo tail -f /var/log/nginx/access.log | awk '{print $1;}'

これらは、ほとんどの場合単一のアドレスを示します。

Output. . .

サーバーのIPアドレスを参照すると、これらのほとんどがプライマリロードバランサーからのものであることがわかります。 実際の配布は、HAProxyが実装する単純なセッションスティッキ性により、少し異なる可能性が高いことに注意してください。

両方のWebサーバーで「+ tail +」コマンドを実行し続けます。

フローティングIPへのリクエストを自動化する

次に、ローカルマシンで、2秒ごとに1回、フローティングIPアドレスでWebコンテンツを要求します。 これにより、ロードバランサーの変更が簡単に確認できます。 ローカルターミナルで、次のように入力します(実際の応答は破棄されます。これは、どのロードバランサーが使用されているかに関係なく同じであるためです)。

while true; do curl -s -o /dev/null ; sleep 2; done

Webサーバーで、新しい要求が着信するのを確認する必要があります。 Webブラウザーを介して行われるリクエストとは異なり、単純な「+ curl +」リクエストは同じセッションスティッキ性を示しません。 バックエンドWebサーバーへのリクエストがより均等に分割されるはずです。

プライマリロードバランサーでHAProxyサービスを中断する

これで、プライマリロードバランサーのHAProxyサービスを再びシャットダウンできます。

sudo service haproxy stop

数秒後、ウェブサーバーで、プライマリロードバランサーのプライベートIPアドレスからセカンダリロードバランサーのプライベートIPアドレスに移行するIPのリストが表示されます。

Output. . .

新しいリクエストはすべて、セカンダリロードバランサーから行われます。

次に、プライマリロードバランサーでHAProxyインスタンスを再度起動します。

sudo service haproxy start

数秒以内に、クライアントリクエストがプライマリロードバランサーのプライベートIPアドレスに戻ることがわかります。

Output. . .

プライマリサーバーは、フローティングIPアドレスの制御を取り戻し、インフラストラクチャのメインロードバランサーとしてのジョブを再開しました。

実際のクライアントIPアドレスを記録するようにNginxを構成する

これまで見てきたように、Nginxアクセスログは、すべてのクライアントリクエストが、リクエストを最初に作成したクライアントの実際のIPアドレスではなく、現在のロードバランサーのプライベートIPアドレスからのものであることを示しています(つまり、 ローカルマシン)。 ロードバランサーサーバーではなく、元のクライアントのIPアドレスをログに記録しておくと便利です。 これは、すべてのバックエンドWebサーバーでNginx構成にいくつかの変更を加えることで簡単に実現できます。

両方のWebサーバーで、エディターで `+ nginx.conf +`ファイルを開きます。

sudo nano /etc/nginx/nginx.conf

「ロギング設定」セクション(「+ http +」ブロック内)を見つけて、次の行を追加します。

/etc/nginx/nginx.confに追加します

log_format haproxy_log 'ProxyIP: $remote_addr - ClientIP: $http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';

保存して終了。 これは、 `+ haproxy_log `と呼ばれる新しいログ形式を指定し、デフォルトのアクセスログエントリに ` $ http_x_forwarded_for `の値(元のリクエストを行ったクライアントのIPアドレス)を追加します。 また、 ` $ remote_addr +`を含めています。これは、リバースプロキシロードバランサーのIPアドレスです(つまり、 アクティブなロードバランサーサーバー)。

次に、この新しいログ形式を使用するには、デフォルトのサーバーブロックに行を追加する必要があります。

両方のWebサーバーで、「+ default +」サーバー設定を開きます。

sudo nano /etc/nginx/sites-available/default

+ server`ブロック内( + listen`ディレクティブのすぐ下が適切な場所です)に、次の行を追加します:

/ etc / nginx / sites-available / defaultに追加します

       access_log /var/log/nginx/access.log haproxy_log;

保存して終了。 これは、上で作成した `+ haproxy_log +`ログ形式を使用してアクセスログを書き込むようにNginxに指示します。

両方のWebサーバーで、Nginxを再起動して変更を有効にします。

sudo service nginx restart

これで、Nginxアクセスログには、リクエストを行っているクライアントの実際のIPアドレスが含まれているはずです。 前のセクションで行ったように、アプリサーバーのログを追跡してこれを確認します。 ログエントリは次のようになります。

New Nginx access logs:. . .
ProxyIP:  - ClientIP:  - - [05/Nov/2015:15:05:53 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .

ログに問題がなければ、準備は完了です!

結論

このガイドでは、可用性の高い、負荷分散されたインフラストラクチャをセットアップする完全なプロセスを説明しました。 アクティブなHAProxyサーバーがバックエンドのWebサーバーのプールに負荷を分散できるため、この構成はうまく機能します。 需要の増減に応じて、このプールを簡単に拡張できます。

フローティングIPおよび「+ keepalived +」構成は、ロードバランシングレイヤーでの単一障害点を排除し、プライマリロードバランサーが完全に失敗した場合でもサービスが機能し続けることを可能にします。 この構成はかなり柔軟であり、HAProxyサーバーの背後に好みのWebスタックをセットアップすることにより、独自のアプリケーション環境に適合させることができます。