前書き
このチュートリアルでは、DigitalOcean APIを使用してサーバー設定を水平方向にスケーリングする方法を示します。 これを行うには、DOProxyを使用します。これは比較的単純なRubyスクリプトであり、構成すると、HTTPアプリケーションサーバーの層を拡大または縮小するためのコマンドラインインターフェイスを提供します。
このチュートリアル専用に作成されたDOProxyは、DigitalOcean APIを使用してHAProxyロードバランサーの背後でアプリケーションサーバードロップレットを簡単に作成および削除し、それらを自動的に管理する方法を提供します。 この基本的なスケーリングモデルにより、ユーザーはHAProxyサーバーを介してアプリケーションにアクセスでき、負荷分散されたバックエンドアプリケーションサーバーに転送されます。
DOProxyは3つの主要な機能を実行します。
-
ドロップレットを作成し、ロードバランサーに追加します
-
ドロップレットを削除し、ロードバランサーから削除します
-
作成された液滴のインベントリを、削除されるまで維持します
Note:このチュートリアルの主な目的は、APIを介してDigitalOceanサーバーアーキテクチャをプログラムでスケーリングするために必要な最小限の概念を教えることです。 DOProxyを現在の形式で実稼働環境で実行しないでください。復元力を念頭に置いて設計されたものではなく、十分なエラーチェックを実行するだけです。 とはいえ、APIを使用した水平スケーリングについて知りたい場合は、始めるのに最適な方法です。
前提条件
このチュートリアルでは、先に進む前に読んでおくとよいさまざまなテクノロジーについて説明します。
DOProxyはRubyで作成されているため、Rubyの知識はプラスですが、必須ではありません。 DOProxyコードの要点を説明する擬似コードを提供します。 また、公式のDigitalOcean RubyラッパーDropletKitを使用します。これにより、RubyコードでAPI呼び出しを簡単に行うことができます。
DOProxyの動作の詳細に入る前に、サーバーにインストールして使用します。 ここで、Ubuntu 14.04ドロップレットにDOProxyをインストールしましょう。
DOProxyをインストールする
まず、NYC3リージョンにUbuntu 14.04ドロップレットを作成します(インストール後にdoproxy.yml
ファイルでregion
変数を構成する場合は、private networkingとuserdataをサポートする任意のリージョンを使用できます) DOProxy)。 このドロップレットは、HAProxyロードバランサーとDOProxyスケーリングスクリプトを実行するため、目的のスケールポテンシャルに十分であると思われるサイズを選択します。 このチュートリアルはスケーリングの基本的なデモンストレーションであり、実際のトラフィックを受信しないため、おそらく1GBのサイズで十分です。
この液滴をDOProxy serverと呼びます。
次に、ログインして、DOProxy GitHub repositoryのInstallationおよびConfiguration(doproxy configおよびUserdataを含む)セクションに従って、このサーバーにDOProxyをインストールします。 指示に記載されているように、サンプルのdoproxy.yml
ファイルとuser-data.yml
ファイルをコピーして使用します。 DOproxy構成ファイルのtoken
とssh_key_ids
の値を必ず置き換えてください。そうしないと、スクリプトが機能しません。
サーバーにDOProxyとHAProxyがインストールされたので、環境を拡張してみましょう。
DOProxyを実行する
DOProxyサーバーにrootとしてログインし、DOProxyのクローンを作成したディレクトリに移動します(まだ行っていない場合)。
引数なしでDOProxyを実行します。
ruby doproxy.rb
これにより、次のような使用可能なコマンドが出力されます。
Commands:
doproxy.rb print # Print backend droplets in inventory file
doproxy.rb create # Create a new backend droplet and reload
doproxy.rb delete # Delete a droplet and reload
doproxy.rb reload # Generate HAProxy config and reload HAProxy
doproxy.rb generate # Generate HAProxy config based on inventory
現在、DOProxyはドロップレットを作成していません。 HTTPサービスをオンラインで取得してスケールアップするためにいくつか作成してみましょう。
スケールアップ(作成)
createコマンドを実行して、DOProxyによって管理される最初のドロップレットを作成します。
ruby doproxy.rb create
これはプロンプトに戻るまでに時間がかかります(スクリプトがAPIを介して新しいドロップレットを作成し、起動するのを待つため)。 後でDOProxyコードを確認するときに、API呼び出しがどのように行われるかについて説明します。
完了すると、次のようなドロップレットIDを含む成功メッセージが表示されます。
Success: 4202645 created and added to backend.
WebブラウザでDOProxyサーバーのパブリックIPアドレスにアクセスした場合。 新しい液滴のhostname、id、およびpublic IP addressを一覧表示するページが表示されます。
DOProxyを使用して、さらに2つのドロップレットを作成します(合計3つ)。 必要に応じてさらに作成してください。
ruby doproxy.rb create
ruby doproxy.rb create
次に、WebブラウザーでDOProxyサーバーのパブリックIPアドレスに再度アクセスします。 ページを更新すると、ページ上の情報が変更され、作成したドロップレットが順番に表示されることがわかります。 これは、それらがすべてHAProxyによってロードバランシングされているためです。各ドロップレットは、作成時にロードバランサー構成に追加されます。
DigitalOceanコントロールパネルを見ると、これらの新しいドロップレットが(残りのドロップレットとともに)そこにリストされていることがわかります。
DOProxyの在庫を見て作成された水滴を詳しく見てみましょう。
在庫の印刷
DOProxyは、インベントリの一部であるすべてのドロップレットを出力するprintコマンドを提供します。
ruby doproxy.rb print
次のような出力が表示されるはずです。
0) auto-nginx-0 (pvt ip: 10.132.224.168, status: active, id: 4202645)
1) auto-nginx-1 (pvt ip: 10.132.228.224, status: active, id: 4205587)
2) auto-nginx-2 (pvt ip: 10.132.252.42, status: active, id: 4205675)
出力例では、ホスト名、ステータス、ドロップレットIDなど、作成した3つのドロップレットに関する情報が表示されます。 ホスト名とIDは、HAProxyロードバランサーにアクセスしたときに(DOProxyのパブリックIPアドレス経由で)表示したものと一致する必要があります。
お気づきかもしれませんが、DOProxyは、作成したドロップレットに関する情報のみを印刷しました。 これは、作成する液滴のインベントリを保持するためです。
今すぐinventory
ファイルの内容を確認してください。
cat inventory
各液滴のIDが1行に1つずつ表示されます。 ドロップレットが作成されるたびに、そのIDがこのインベントリファイルに保存されます。
ご想像のとおり、DOProxyのprint
コマンドは、インベントリファイル内のドロップレットIDを反復処理し、API呼び出しを実行して各IDに関するドロップレット情報を取得します。
サーバーインベントリを単一のファイルに保存するのは最善のソリューションではないことに注意してください。簡単に破損したり削除したりできますが、動作するシンプルな実装を示しています。 etcdなどの分散キー値ストアがより良いソリューションです。 また、在庫にドロップレットIDだけを保存することもできます(したがって、特定のドロップレット情報を確認するたびにAPI呼び出しを行う必要はありません)。
縮小(削除)
DOProxyには、インベントリ内のドロップレットを削除できる削除コマンドもあります。 deleteコマンドでは、削除するドロップレットの行番号を指定する必要があります(print
コマンドで表示されます)。
このコマンドを実行する前に、おそらくインベントリを印刷する必要があります。
ruby doproxy.rb print
したがって、たとえば、3番目の液滴を削除する場合は、行番号として2
を指定します。
ruby doprorxy.rb delete 2
しばらくすると、確認メッセージが表示されます:
Success: 4205675 deleted and removed from backend.
deleteコマンドは、APIを介してドロップレットを削除し、HAProxy構成から削除し、インベントリから削除します。 DOProxy印刷コマンドを使用するか、DigitalOceanコントロールパネルをチェックして、ドロップレットが削除されたことを確認してください。 また、ロードバランサーの一部ではなくなったことにも気付くでしょう。
HAProxy設定
まだ説明していないDOProxyの最後の部分は、HAProxyの構成方法です。
create
またはdelete
DOProxyコマンドを実行すると、インベントリ内の各ドロップレットの情報が取得され、その情報の一部がHAProxy構成ファイルの作成に使用されます。 特に、ドロップレットIDとプライベートIPアドレスは、各ドロップレットをバックエンドサーバーとして追加するために使用されます。
生成されたhaproxy.cfg
ファイルの最後の数行を次のように見てください。
tail haproxy.cfg
このようなものが見えるはずです。
frontend www-http
bind 104.236.236.43:80
reqadd X-Forwarded-Proto:\ http
default_backend www-backend
backend www-backend
server www-4202645 10.132.224.168:80 check # id:4202645, hostname:auto-nginx-0
server www-4205587 10.132.228.224:80 check # id:4205587, hostname:auto-nginx-1
frontend
セクションにはDOProxyサーバーのパブリックIPアドレスが含まれている必要があり、backend
セクションには作成された各ドロップレットを参照する行が含まれている必要があります。
Note:この時点で、DOProxyで作成された残りのドロップレットを削除することをお勧めします(すべてのサーバーがなくなるまでruby doproxy.rb delete 0
)。
DOProxyのスケーリングの実際の動作を確認したので、コードを詳しく見てみましょう。
DOProxyコード
このセクションでは、DOProxyを機能させる関連ファイルとコード行を見ていきます。 DOProxyの実装方法を確認すると、APIを使用して独自のサーバーインフラストラクチャを管理および自動化する方法についてのアイデアが得られるはずです。
リポジトリをサーバーに複製したので、そこでファイルを確認するか、DOProxyリポジトリ(https://github.com/thisismitch/doproxy)でファイルを確認できます。
重要なファイル:
-
doproxy.rb:DOProxyRubyスクリプト。 DOProxyの背後にあるコマンドラインインターフェイスと頭脳を提供します
-
doproxy.yml:DOProxy構成ファイル。 APIトークンが含まれ、ドロップレット作成オプションを指定します
-
haproxy.cfg.erb:HAProxy構成テンプレート。 適切なバックエンドサーバー情報でロードバランサー構成を生成するために使用
-
inventory:液滴インベントリファイル。 作成された液滴のIDを保存します
-
user-data.yml:ユーザーデータファイル。 新しい液滴が作成されたときに実行されるcloud-configファイル
最初に構成ファイルに飛び込みましょう。
doproxy.yml
DOProxy構成ファイルdoproxy.yml
の重要な行は、次のとおりです。
token: 878a490235d53e34b44369b8e78
ssh_key_ids: # DigitalOcean ID for your SSH Key
- 163420
...
droplet_options:
hostname_prefix: auto-nginx
region: nyc3
size: 1gb
image: ubuntu-14-04-x64
token
は、read and writeAPIトークンを構成できる場所です。
他の行は、DOProxyが新しいドロップレットを作成するときに使用されるオプションを指定します。 たとえば、指定されたSSHキーを(IDまたは指紋によって)インストールし、ホスト名の前に「auto-nginx」を付けます。
有効な液滴オプションの詳細については、DigitalOcean API documentationを確認してください。
user-data.yml
ユーザーデータファイルuser-data.yml
は、新しいドロップレットが作成されるたびに、cloud-initによって実行されるファイルです。 つまり、新しいドロップレットにアプリケーションソフトウェアをインストールするためのcloud-configファイルまたはスクリプトを提供できます。
サンプルのユーザーデータファイルには、UbuntuサーバーにNginxをインストールし、そのデフォルトの構成ファイルをドロップレットのホスト名、ID、パブリックIPアドレスに置き換える単純なbashスクリプトが含まれています。
#!/bin/bash
apt-get -y update
apt-get -y install nginx
export DROPLET_ID=$(curl http://169.254.169.254/metadata/v1/id)
export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
echo Droplet: $HOSTNAME, ID: $DROPLET_ID, IP Address: $PUBLIC_IPV4 > /usr/share/nginx/html/index.html
ドロップレット情報(ホスト名、ID、およびIPアドレス)は、DigitalOceanメタデータサービスを介して取得されます。これは、これらのcurl
コマンドが実行していることです。
明らかに、アプリケーションのインストールや構成など、これよりも便利なことをしたいと思うでしょう。 これを使用して、SSHキーを自動的にインストールし、構成管理ツールまたは監視ツールに接続するなどの方法で、全体的なインフラストラクチャへのドロップレットの統合を自動化できます。
ユーザーデータ、クラウド構成、メタデータの詳細については、次のリンクをご覧ください。
haproxy.cfg.erb
HAProxy構成テンプレートhaproxy.cfg.erb
には、ほとんどのロードバランサー構成が含まれており、一部のRubyコードはバックエンドのドロップレット情報に置き換えられます。
バックエンド構成を生成するRubyセクションを見てみましょう。
backend www-backend
<% @droplets.each_with_index do |droplet, index| %>
server www-<%= droplet.id %> <%= droplet.private_ip %>:80 check # id:<%= droplet.id %>, hostname:<%= droplet.name -%>
<% end %>
このコードは、インベントリ内の各ドロップレットを反復処理し、(プライベートIPアドレスに基づいて)各ドロップレットに新しいHAProxyバックエンドを追加します。
たとえば、次のような行が各液滴に対して生成されます。
server www-4202645 10.132.224.168:80 check # id:4202645, hostname:auto-nginx-0
ドロップレットが作成または削除されるたびに、DOProxyは新しいHAProxy構成ファイル(前に確認したhaproxy.cfg
ファイル)を生成します。
doproxy.rb
DOProxy Rubyスクリプトdoproxy.rb
は、主に、ドロップレットの作成と削除、インベントリ管理、およびHAProxy構成の生成を実行するメソッドを含むDOProxyクラスで構成されています。
Rubyを理解している場合は、GitHubのファイルhttps://github.com/thisismitch/doproxy/blob/master/doproxy.rbを確認してください。
Rubyを理解していない場合、各メソッドを説明する簡単な擬似コードを次に示します。 何が起こっているのかを理解するのを助けるために、実際のRubyコードに対してこれを参照することは有用かもしれません。
def初期化
引数が指定されていない限り、DOProxyが実行されるたびに実行されます。
-
doproxy.yml
構成ファイルを読み取ります(APIトークンとドロップレットオプションを取得します)。 2
def get_inventory
インベントリファイル内の各液滴の情報を取得します。 次のメソッドのいずれかを実行する前に実行する必要があります。
-
インベントリファイルの読み取り(ドロップレットIDを含む)
-
液滴IDごとに、APIを使用して液滴情報を取得します
def print_inventory
「doproxy.rb print」コマンドを使用すると、液滴情報が画面に出力されます。 get_inventory
に依存します。
-
インベントリ内の各ドロップレットについて、ホスト名、プライベートIPアドレス、ステータス、およびID(
get_inventory
によって取得された)を出力します。
def create_server
「doproxy.rbcreate」コマンドを使用すると、新しいドロップレットを作成してインベントリファイルに追加し、reload_haproxy
を呼び出してHAProxy構成を生成し、ロードバランサーをリロードします。
-
ユーザーデータファイルを読む
-
APIを使用して、提供されたユーザーデータとオプションに基づいてドロップレットを作成します
-
ドロップレットのステータスが「アクティブ」になるまで待ちます-APIを使用して、ステータスが変わるまで15秒ごとにドロップレット情報を取得します
-
ステータスが「アクティブ」の場合、ドロップレットIDをインベントリファイルに追加します
-
reload_haproxy
を呼び出して、HAProxy構成を生成し、ロードバランサーをリロードします
def delete_server(line_number)
「doproxy.rbdelete」コマンドを使用すると、指定したドロップレットを削除し、インベントリファイルからそのIDを削除してから、reload_haproxy
を呼び出してHAProxy構成を生成し、ロードバランサーをリロードします。
-
インベントリファイルから指定された行を削除します(ドロップレットIDを削除します)
-
APIを使用して、IDでドロップレットを削除します
-
reload_haproxy
を呼び出して、HAProxy構成を生成し、ロードバランサーをリロードします
def generate_haproxy_cfg
これは、インベントリ内のドロップレットに基づいて新しいHAProxy構成ファイルを作成するサポート方法です。
-
HAProxy構成テンプレート
haproxy.cfg.erb
を開きます -
インベントリ内の各ドロップレットに対して、対応するバックエンドサーバーを追加します
-
結果の
haproxy.cfg
ファイルをディスクに書き込みます
def reload_haproxy
これは、HAProxy構成ファイルを適切な場所にコピーし、HAProxyを再ロードするサポート方法です。 これはgenerate_haproxy_cfg
に依存します。
-
HAProxy構成ファイル
haproxy.cfg
を、HAProxyがリロード時に読み取る場所にコピーします -
HAProxyをリロードする
これがDOProxyを機能させる重要なコードのすべてです。 最後に説明するのは、DOProxyで使用したAPIラッパーであるDropletKitです。
DropletKit Gem
DOProxyは、公式のDigitalOcean API v2 RubyラッパーであるDropletKit gemを使用して、DigitalOceanAPI呼び出しを行います。 DropletKitを使用すると、次のようなことを行うRubyプログラムを簡単に作成できます。
-
新しい液滴を作成する
-
既存の液滴を削除する
-
ステータス、IPアドレス、ドロップレットID、地域など、既存のドロップレットに関する情報を取得する
このチュートリアルでは、これらの特定のAPIエンドポイントに焦点を当てましたが、DigitalOceanサーバーインフラストラクチャのプログラムによる管理を容易にするのに役立つ他の多くのエンドポイントがあることに留意してください。
結論
DigitalOcean API、cloud-config、およびメタデータを活用することで、簡単なスクリプトがサーバー環境の拡張にどのように役立つかを見てきたので、これらの概念を適用して独自のサーバー設定を拡張できることを願っています。 DOProxyは実稼働に対応していませんが、独自のスケーリングソリューションを実装するためのアイデアを提供するはずです。
ここで説明したスケーリング設定は、DOProxyを使用した場合は優れていますが、監視システムと組み合わせて使用することで大幅に改善できることを忘れないでください。 これにより、サーバーリソースの使用率などの特定の条件に応じて、アプリケーションサーバー層を自動的にスケールアップおよびスケールダウンできます。
質問やコメントがありますか? 以下にそれらを自由に投稿してください!