小規模なブログ、大規模なアプリケーション、APIのどれを実行しているかは関係ありません。オフラインにしたいことはありません。

単一障害点とは、障害が発生した場合にダウンタイムを引き起こすインフラストラクチャの任意の部分です。 たとえば、1つのサーバーを使用して、Webサーバーとデータベースの両方をホストすることができます。 多くの場合、停止はこれらの単一障害点によって引き起こされるため、これらの状況を回避するためにインフラストラクチャを設計する必要があります。

高可用性インフラストラクチャには、単一障害点はありません。 通常、これは、インフラストラクチャがサービスごとに分割され、各サービスを複数のサーバーで実行することを意味します。 1つのサーバーに障害が発生した場合、要求を処理するために他のサーバーを使用できます。 可用性の高い構成は、冗長性にとって重要であるだけでなく、インフラストラクチャを拡張する方が高速で費用対効果が高くなります。

ファイルをホストするWebサービスを想像してください。 ここで、3つの独立したサーバーで実行されていることを想像してください。 差し迫った問題がいくつかあります。 ユーザーはこれらのサーバーにどのようにアクセスできますか? 各独立サーバーにDNSレコードを追加できます。 残念ながら、ユーザーはサーバーにランダムにルーティングされ、オフラインのサーバーに送信される可能性があります。

インフラストラクチャにロードバランサーを追加することで、これらの落とし穴を回避できます。 ロードバランサーは、構成内にある各サーバーのヘルスチェックを実行します。 サーバーがオフラインの場合、ロードバランサーはユーザー要求を送信しません。 ロードバランサーは、利用可能な最適なサーバーにユーザーをより効果的にルーティングすることにより、パフォーマンスを向上させます。

この追加を実行する際のもう1つの懸念は、ロードバランサー自体が単一障害点にならないようにすることです。 私たちはそのことを考えており、ロードバランサーレイヤーとバックエンドサーバーで可用性の高い2つの完全なソリューションを用意しています。

私たちのセットアップ

この章では、いくつかのWebサーバーで負荷分散ソリューションを展開する2つの方法について説明します。 このセクションの終わり(4〜6章)までに、Webサービスとデータベースサービスの前に複数のロードバランサーを設定し、単一障害点がないようにします。

負荷分散を設定するには、さまざまな方法があります。 バックエンドでNginx Webサービスを提供する2つの設定例を見ていきます。

最初のソリューションでは、https://www.digitalocean.com/docs/networking/load-balancers/ [DigitalOcean Load Balancers]を使用します。これは、フェイルオーバーリカバリを自動的に処理する高可用性サービスです。 また、手動リストの代わりにhttps://www.digitalocean.com/docs/droplets/how-to/tag/[tags]に基づいてトラフィックをDropletsに転送する機能も含まれているため、スケーリングが簡単になります。

2番目のソリューションは、HAProxyおよびhttps://www.digitalocean.com/docs/networking/floating-ips/[DigitalOcean Floating IPs]を使用した、よりカスタムの負荷分散ソリューションです。コントロールパネルまたはAPIのいずれかを使用して自動的に領域を設定します。 これらを使用して、メインのロードバランサーに障害が発生した場合に、トラフィックをスタンバイロードバランサーに再ルーティングできます。

この本でTerraformとAnsibleを使用するのはこれが初めてなので、このセクションを手動で行って、手動で独自のプロジェクトを作成する経験を提供します。 次の章でより複雑なセットアップに進むと、ほとんどの構成が自動化されます。

DigitalOceanロードバランサーの使用

DigitalOceanロードバランサーのセットアップ

コントローラーのドロップレットで、https://github.com/digitalocean/navigators-guide/tree/master/example-code/02-scale/ch04/digitalocean_loadbalancer [リポジトリのこの章のディレクトリ]に移動します。

cd /root/navigators-guide/example-code/02-scale/ch04/digitalocean_loadbalancer

このディレクトリには、https://github.com/digitalocean/navigators-guide/blob/master/example-code/02-scale/ch04/digitalocean_loadbalancer/terraform.tfvars.sample [a `+ terraform.tfvars.sample + `ファイル]。 このサンプルファイルには、必要な情報を見つけるのに役立つコメントとメモが含まれています。 コメントがない場合、ファイルは次のようになります。

do_token = ""

project = "DO-LB"

region = "sfo2"

image_slug = "debian-9-x64"

keys = ""

private_key_path = ""

ssh_fingerprint = ""

public_key = ""

これにより、Nginxを実行するいくつかのドロップレットとともにDigitalOceanロードバランサーが作成されます。 各Webサーバーは、個々のDropletのホスト名を含む簡単なウェルカムメッセージを表示します。

コメントの指示に従って変数を入力し、ファイルの名前を `+ terraform.tfvars +`に変更します。

mv terraform.tfvars.sample terraform.tfvars

この構成ではTLS証明書は必要ありませんが、DigitalOceanロードバランサーに追加できます。 DigitalOceanロードバランサー機能には、無料で証明書を提供するLet’s Encryptも統合されています。 Lets Encryptでは、登録してDigitalOceanアカウントに追加するドメイン名が必要です。

次に、Terraformデプロイメントを準備して実行します。 最初に、 `+ terraform init `を使用して計画ファイルとモジュールを解析します。 オプションで、 ` terraform plan `を実行して、実際のスクリプトを実行したときに何が起こるかを確認できます。 準備ができたら、 ` terraform apply +`を実行して、DigitalOcean APIを介して作成リクエストを実行します。

terraform init
terraform apply

「+ yes +」と入力して実行を確認する必要があります。適用が完了すると通知されます。

この時点で、ブラウザでロードバランサーのパブリックIPアドレス(「+ terraform show +」で取得できます)にアクセスして、Webサーバーからサンプルコンテンツを表示できます。

Terraformは、 `+ destroy `オプションを使用してクラスターを自動的に削除することもできます。 このワークフローを使用して迅速なテストを行うことができますが、クラスターに保存されたデータはすべて削除されることを知っています。 * ` destroy `オプションはクラスターを削除します。*これは、この章で行っている作業をクリーンアップする最も速い方法です。 「 apply +」を再実行して、新しいクラスターを生成できます。

このサンプルクラスターを分解する前に、実際に可用性が高いことをテストしてみましょう。

クラスターの可用性のテスト

バックエンドWebサーバーの可用性をテストするために、ロードバランサーからの接続を継続的に要求しながら、1つのサーバーをオフラインにすることができます。 接続が継続して行われる場合、サーバーに障害が発生してもサービスがオンラインのままであることがわかります。 (ロードバランサーはサービスとして実行されるため、ロードバランサー自体のフェールオーバーをテストすることはできません。つまり、個々のコンポーネントに直接アクセスする必要はありません。)

ターミナルで次のコマンドを実行します。これは、1秒に1回ロードバランサーに接続します。

while true; do curl -k load_balancer_ip; sleep 1; done

次のような連続出力が表示されます。

Welcome to DO-LB-backend-01!
Welcome to DO-LB-backend-02!
Welcome to DO-LB-backend-03!
Welcome to DO-LB-backend-01!
Welcome to DO-LB-backend-02!
Welcome to DO-LB-backend-03!

バックエンドドロップレットのいずれかの電源をオフにしてみてください。 ドロップレットをオフラインにしても、他のロードバランサーのバックエンドから有効な応答を返すテストが表示されるはずです。 オフにしたドロップレットが応答しなくなっていることがわかります。 電源を再投入すると、ロードバランサーの設定済みのチェックに合格すると、自動的にローテーションに追加されます。

(実行中のテストを停止するのに助けが必要な場合、 `+ CTRL-C +`キーボードコマンドでループを終了できます)

クラスターのスケーリング

初期クラスタセットアップでは、3つのバックエンドドロップレットを使用します。 バックエンドドロップレットの数の設定は、variables.tfファイルのデフォルトの変数宣言にあります。 変数 `+ node_count `を5に設定して ` terraform.tfvars +`に行を追加することでオーバーライドできます。 行を追加したら、Terraform計画を再適用する必要があります。

terraform apply

Terraformはここで本当に輝いています。 この変数に基づいてドロップレットの数を変更するロジックを処理するため、 `+ node_count +`変数が増減するときに自動的にドロップレットを作成または破棄します。

Load Balancerに対して「+ curl +」を実行しているターミナルで、出力を確認します。 新しいドロップレットがプロビジョニングされると、それらが自動的に応答を開始します。

Welcome to DO-LB-backend-02!
Welcome to DO-LB-backend-03!
Welcome to DO-LB-backend-01!
Welcome to DO-LB-backend-02!
Welcome to DO-LB-backend-03!
Welcome to DO-LB-backend-04!
Welcome to DO-LB-backend-05!
Welcome to DO-LB-backend-01!
Welcome to DO-LB-backend-02!
Welcome to DO-LB-backend-03!
Welcome to DO-LB-backend-04!
Welcome to DO-LB-backend-05!
Welcome to DO-LB-backend-01!

先に進む前に、このテストプロジェクトを破棄する必要があります。 Terraformは、現在の作業ディレクトリに計画の現在の状態を保持します。 Terraformを介してリソースを破棄すると、自動的に状態がクリアされます。

terraform destroy

HAProxyとDigitalOceanフローティングIPアドレスの使用

カスタムの負荷分散ソリューションを展開するのが正しい選択かもしれません。 DigitalOcean Load Balancerが現在サポートしていないオプションがいくつかあります。 これの例は、複数のサイトまたはアプリケーションをバックエンドとしてホストすること、複数のTLS証明書、プロキシプロトコルのサポート、または特定のTCPパラメーターの調整です。

この例では、フェイルオーバーにDigitalOcean Floating IPを使用してクラスター化されたHAProxy v1.8ロードバランサーを使用します。

HAProxyのセットアップ

コントローラーのドロップレットで、https://github.com/digitalocean/navigators-guide/tree/master/example-code/02-scale/ch04/haproxy_loadbalancer [リポジトリのこの章のディレクトリ]に移動します。

cd /root/navigators-guide/example-code/02-scale/ch04/haproxy_loadbalancer

このディレクトリには、https://github.com/digitalocean/navigators-guide/blob/master/example-code/02-scale/ch04/haproxy_loadbalancer/terraform.tfvars.sample [a `+ terraform.tfvars.sample + `ファイル]。 このサンプルファイルには、必要な情報を見つけるのに役立つコメントとメモが含まれています。 コメントがない場合、ファイルは次のようになります。

do_token = ""

project = "HAPROXY-LB"

region = "sfo2"

image_slug = "debian-9-x64"

keys = ""

private_key_path = ""

ssh_fingerprint = ""

public_key = ""

コメントの指示に従って変数を入力し、ファイルの名前を `+ terraform.tfvars +`に変更します。

mv terraform.tfvars.sample terraform.tfvars

次に、Terraformデプロイメントを準備して実行します。 最初に、 `+ terraform init `を使用して計画ファイルとモジュールを解析します。 オプションで、 ` terraform plan `を実行して、実際のスクリプトを実行したときに何が起こるかを確認できます。 準備ができたら、 ` terraform apply +`を実行して、DigitalOcean APIを介して作成リクエストを実行します。

terraform init
terraform apply

「+ yes +」と入力して実行を確認する必要があります。適用が完了すると通知されます。

ここで「+ terraform show 」を実行すると、デプロイしたリソースを確認できます。 リソースの各セット(つまり、 ドロップレット)は、Terraform構成ファイルのリソース名に従ってグループ名に配置されます。 この例では、https://github.com/digitalocean/navigators-guide/blob/master/example-code/02-scale/ch04/haproxy_loadbalancer/haproxy.tf [the ` haproxy.tf +` file] ‘s resourceこれらのグループは宣言によって決まります。

3つのグループは、HAProxyの場合は「+ load_balancer 」、Nginxの場合は「 web_node 」、フローティングIPの場合は「 fip 」です。 ` terraform-inventory -inventory `で見て、AnsibleインベントリをINI形式で取得するか、 ` -list`オプションでJSONを出力できます。

この時点で、必要なドロップレットが作成されて実行されていますが、まだ設定する必要があります。

Ansibleでのドロップレットの構成

Ansibleを使用して、ドロップレットの構成を自動化します。 Ansibleのいくつかのロールをダウンロードするように事前構成されたAnsible Playbookがあります。 これらのAnsibleロールはhttps://github.com/digitalocean/navigators-guide/blob/master/example-code/02-scale/ch04/haproxy_loadbalancer/requirements.yml[the `+ requirements.yml +`ファイルにリストされています]。 1つずつインストールする必要はありません。 Ansible Galaxyで必要な役割をダウンロードできます。

このコマンドは、ロールを `+ roles +`ディレクトリに配置します。

ansible-galaxy install -r requirements.yml

このロールに設定する必要のある変数がいくつかあります。/ root / navigators-guide / example-code / 02-scale / ch04 / haproxyloadbalancer / groupvars / load_balancer / _ディレクトリに戻ります。 既存の* vars.yml *ファイルを表示すると、「+ do_token 」と「 ha_auth_key 」にそれぞれ「 vault_do_token 」と「 vault_ha_auth_key 」の値が割り当てられていることがわかります。 * vault.yml *というセカンダリファイルを作成し、 ` vault +`変数を初期化します。

変数を設定する前に、2つのことが必要です。 フェールオーバーシナリオのフローティングIP割り当ての処理に使用されるDigitalOcean APIトークン、およびクラスターメンバーの認証に使用されるSHA-1ハッシュ。 これを作成するためのツールがあります。

cd /root/navigators-guide/example-code/02-scale/ch04/haproxy_loadbalancer/
./gen_auth_key

authkeyが作成されたら、先に進み、 groupvars / load_balancer / vault.yml ファイルを作成します。 ファイルは次のようになります。

---
vault_do_token: "79da2e7b8795a24c790a367e4929afd22bb833f59bca00a008e2d91cb5e4285e"
vault_ha_auth_key: "c4b25a9f95548177a07d425d6bc9e00c36ec4ff8"

これらのキーのセキュリティと機密性は、インフラストラクチャにとって不可欠です。 この* vault.yml *ファイルを表示または編集できるユーザーを制限します。 Ansibleには、 `+ ansible-vault +`という名前の暗号化システムが組み込まれています。

このコマンドを使用して、ファイルを暗号化します。

ansible-vault encrypt vault.yml

このプロセスでは、パスワードの入力が求められます。 Ansibleプレイブックを実行するたびに、このパスワードの入力も求められます。 暗号化されたファイルを編集する必要がある場合は、 `+ ansible-vault +`を使用して編集する必要があります。 Ansible Vaultのhttps://docs.ansible.com/ansible/2.4/vault.html [ドキュメント]には、この機能のすべての機能の完全なリストがあります。

ansible-vault edit vault.yml

Ansibleは、プレイブックを実行するたびに復号化パスワードを要求しますが、これは自動化には理想的ではありません。 パスワードをシステムのどこかに保存して、許可コントロールを追加することでパスワードを保護できます。 パスワードを保存するファイルを作成するには、 `+ echo ‘password’>〜/ .vaultpass.txt `を実行するか、テキストエディターを使用して手動でファイルを作成します。 非特権ユーザーがこのファイルにアクセスできないことを確認します。 * / root / navigators-guide / example-code / 02-scale / ch04 / haproxy_loadbalancer / ansible.cfg *構成ファイルの「 vault_password_file +」行のコメントを解除します。 これにより、プレイブックを実行するたびに、Ansibleがボールトパスワードを要求することがなくなります。 パスワードを保存するために使用するファイルとファイル名へのパスを変更することもできますが、gitリポジトリに保管しないようにしてください。 パスワードやシークレットトークンを誤ってコミットしてプッシュしたくはありません。

これで、メインのAnsibleプレイブックを実行する準備が整いました。 リポジトリのルートに戻り、 `+ ansible-playbook -i / usr / local / bin / terraform-inventory site.yml +`を実行します。 繰り返しますが、現在実行中のロール、現在実行中のロール、および変更またはエラーが検出されたかどうかを表示するテキストストリームが画面に表示されます。 プレイの最後には、ホストごとの合計が次のようなプレイ概要が表示されます。

PLAY RECAP *********************************************************************
138.68.50.232              : ok=1    changed=0    unreachable=0    failed=0
159.65.78.225              : ok=1    changed=0    unreachable=0    failed=0
165.227.9.176              : ok=40   changed=38   unreachable=0    failed=0
178.128.128.168            : ok=1    changed=0    unreachable=0    failed=0
178.128.3.35               : ok=40   changed=38   unreachable=0    failed=0
206.189.174.220            : ok=1    changed=0    unreachable=0    failed=0

フローティングIPアドレスにアクセスするか、https://www.digitalocean.com/docs/networking/dns/how-to/add-domains/にアクセスして、サイト(この場合は単純なhtmlページ)にアクセスできます。フローティングIPアドレスを指す[ドメインを追加]。

クラスターの可用性のテスト

バックエンドWebサーバーの可用性をテストするために、ロードバランサーからの接続を継続的に要求しながら、1つをオフラインにすることができます。 接続が継続して行われる場合、サーバーに障害が発生してもサービスがオンラインのままであることがわかります。

ターミナルで次のコマンドを実行します。これは、1秒に1回ロードバランサーに接続します。

while true; do curl -k floating_ip; sleep 1; done

次のような連続出力が表示されます。

Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!

バックエンドドロップレットのいずれかの電源をオフにしてみてください。 Dropletがオフラインの場合でも、他のロードバランサーのバックエンドから有効な応答を返すcurlが表示されるはずです。 オフにしたドロップレットが応答しなくなっていることがわかります。 電源を再投入すると、ロードバランサーの設定済みチェックに合格すると、再びローテーションに追加されます。

テストを実行したまま、メインのHAProxy Dropletの電源をオフにすると、リクエストが数回ドロップされた後、フローティングIPアドレスがセカンダリHAProxy Dropletにリダイレクトされることがわかります。 セカンダリHAProxyドロップレットが自動的に取得され、テストの実行が継続されます。

(実行中のテストを停止するのに助けが必要な場合、 `+ CTRL-C +`キーボードコマンドでループを終了できます)

クラスターのスケーリング

初期クラスタセットアップでは、3つのバックエンドドロップレットを使用します。 バックエンドドロップレットの数の設定は、variables.tfファイルのデフォルトの変数宣言にあります。 変数 `+ node_count `を5に設定して ` terraform.tfvars +`に行を追加することでオーバーライドできます。

terraform apply

Terraformはここで本当に輝いています。 この変数に基づいてドロップレットの数を変更するロジックを処理するため、 `+ node_count +`変数が増減するときに自動的にドロップレットを作成または破棄します。

リソースカウントが変更されるたびに、ドロップレットに対してAnsibleを再度実行して、バックエンドドロップレットを構成し、HAProxyの構成を変更する必要があります。

ansible-playbook -i /usr/local/bin/terraform-inventory site.yml

Load Balancerに対して「+ curl +」を実行しているターミナルで、出力を確認します。 新しいドロップレットがプロビジョニングされると、それらが自動的に応答を開始します。

Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-04!
Welcome to HAPROXY-LB-backend-05!
Welcome to HAPROXY-LB-backend-01!
Welcome to HAPROXY-LB-backend-02!
Welcome to HAPROXY-LB-backend-03!
Welcome to HAPROXY-LB-backend-04!
Welcome to HAPROXY-LB-backend-05!
Welcome to HAPROXY-LB-backend-01!

完了したら、 `+ destroy +`で作成されたTerraformのリソースをクリーンアップできます。 この方法でクラスターを破壊すると、すべてのデータが失われます。

terraform destroy

次は何ですか?

シンプルなWebアプリケーションを使用して、複数のドロップレットで実行し、2種類のロードバランサーでトラフィックを動作可能なドロップレットに誘導することで、可用性を高めました。 これらは、冗長性とダウンタイム防止のための基本的な概念です。

次の章では、これらの概念を拡張して、ロードバランサーの構成を維持する方法、アプリケーションとアプリケーションが存在するドロップレットを管理する方法、ユーザーセッション、ファイルストレージ、データベースを処理する方法について説明します。 Terraform and Ansibleを引き続き使用して、8つのDropletのクラスターで実行されているWordPressをデプロイします。