前書き
reverse proxyは、HTTP(S)要求を受け取り、それらを1つ以上のバックエンドサーバーに透過的に配布するプロキシサーバーの一種です。 多くの最新のWebアプリケーションは、ユーザーが直接アクセスすることを意図しておらず、多くの場合基本的なHTTP機能のみをサポートするバックエンドアプリケーションサーバーを使用して着信HTTPリクエストを処理するため、リバースプロキシが役立ちます。
リバースプロキシを使用して、これらの基になるアプリケーションサーバーが直接アクセスされるのを防ぐことができます。 また、これらを使用して、着信要求から複数の異なるアプリケーションサーバーに負荷を分散し、大規模なパフォーマンスを向上させ、フェイルセーフを実現できます。 キャッシング、圧縮、SSL暗号化など、アプリケーションサーバーが提供しない機能でギャップを埋めることができます。
このチュートリアルでは、mod_proxy
拡張子を使用してApacheを基本的なリバースプロキシとして設定し、同じネットワーク上で実行されている1つまたは複数のバックエンドサーバーに着信接続をリダイレクトします。 このチュートリアルでは、Flask web frameworkで記述された単純なバックエンドを使用しますが、任意のバックエンドサーバーを使用できます。
前提条件
このチュートリアルを実行するには、次のものが必要です。
-
sudo非rootユーザーとファイアウォールを含むthis initial server setup tutorialでセットアップされた1つのUbuntu16.04サーバー。
-
How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 16.04のステップ1に従って、サーバーにApache2をインストールします。
[[step-1 -—- enableing-necessary-apache-modules]] ==ステップ1—必要なApacheモジュールを有効にする
Apacheには多くのモジュールがバンドルされており、それらは利用可能ですが、新規インストールでは有効になりません。 まず、このチュートリアルで使用するものを有効にする必要があります。
必要なモジュールは、mod_proxy
自体とそのアドオンモジュールのいくつかであり、さまざまなネットワークプロトコルをサポートするように機能を拡張します。 具体的には、次のものを使用します。
-
mod_proxy
、接続をリダイレクトするためのメインプロキシモジュールApacheモジュール。これにより、Apacheが基盤となるアプリケーションサーバーへのゲートウェイとして機能できるようになります。 -
mod_proxy_http
。HTTP接続のプロキシのサポートを追加します。 -
mod_proxy_balancer
およびmod_lbmethod_byrequests
。複数のバックエンドサーバーに負荷分散機能を追加します。
これらの4つのモジュールを有効にするには、次のコマンドを連続して実行します。
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
これらの変更を有効にするには、Apacheを再起動します。
sudo systemctl restart apache2
Apacheは、HTTPリクエストのリバースプロキシとして機能する準備ができました。 次の(オプションの)ステップでは、2つの非常に基本的なバックエンドサーバーを作成します。 これらは、構成が適切に機能するかどうかを確認するのに役立ちますが、すでに独自のバックエンドアプリケーションがある場合は、手順3にスキップできます。
[[step-2 -—- creating-backend-test-servers]] ==ステップ2—バックエンドテストサーバーの作成
いくつかの単純なバックエンドサーバーを実行すると、Apache構成が適切に機能しているかどうかを簡単にテストできます。 ここでは、HTTP要求に応答してテキスト行を印刷する2つのテストサーバーを作成します。 一方のサーバーはHello world!と表示し、もう一方のサーバーはHowdy world!と表示します。
[.note]#Note:非テスト設定では、バックエンドサーバーは通常すべて同じ種類のコンテンツを返します。 ただし、特にこのテストでは、2つのサーバーが異なるメッセージを返すようにすることで、負荷分散メカニズムが両方を使用していることを簡単に確認できます。
#
Flaskは、Webアプリケーションを構築するためのPythonマイクロフレームワークです。 基本的なアプリでは数行のコードしか必要ないため、Flaskを使用してテストサーバーを作成しています。 これらを設定するためにPythonを知っている必要はありませんが、学習したい場合は、these Python tutorialsを確認できます。
最初にパッケージリストを更新します。
sudo apt-get update
次に、推奨されるPythonパッケージマネージャーであるPipをインストールします。
sudo apt-get -y install python3-pip
Pipを使用してFlaskをインストールします。
sudo pip3 install flask
必要なすべてのコンポーネントがインストールされたので、現在のユーザーのホームディレクトリに最初のバックエンドサーバーのコードを含む新しいファイルを作成することから始めます。
nano ~/backend1.py
次のコードをファイルにコピーし、保存して閉じます。
~/backend1.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello world!'
最初の2行は、Flaskフレームワークを初期化します。 1行のテキスト(Hello world!
)を返す1つの関数home()
があります。 home()
関数定義の上の@app.route('/')
行は、アプリケーションの/
ルートURLに向けられたHTTP要求への応答としてhome()
の戻り値を使用するようにFlaskに指示します。
2番目のバックエンドサーバーは、最初のサーバーとまったく同じですが、異なるテキスト行に戻ることを除けば、最初のファイルを複製することから始めます。
cp ~/backend1.py ~/backend2.py
新しくコピーしたファイルを開きます。
nano ~/backend2.py
返されるメッセージをHello world!からHowdy world!に変更し、ファイルを保存して閉じます。
~/backend2.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy world!'
次のコマンドを使用して、ポート8080
で最初のバックグラウンドサーバーを起動します。 これにより、Flaskの出力が/dev/null
にリダイレクトされます。これは、コンソール出力がさらに曇ってしまうためです。
FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
ここでは、flask
コマンドの前に、同じ行にFLASK_APP
環境変数を設定しています。 環境変数は、シェルから生成されるプロセスに情報を渡す便利な方法です。 環境変数の詳細については、How To Read and Set Environmental and Shell Variables on a Linux VPSを参照してください。
この場合、環境変数を使用すると、設定が実行中のコマンドにのみ適用され、その後は使用できなくなります。これは、flask
コマンドに2番目のサーバーを起動するように指示するのと同じ方法で別のファイル名を渡すためです。
同様に、このコマンドを使用して、ポート8081
で2番目のサーバーを起動します。 FLASK_APP
環境変数の値が異なることに注意してください。
FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &
curl
を使用して、2つのサーバーが実行されていることをテストできます。 最初のサーバーをテストします。
curl http://127.0.0.1:8080/
これにより、端末にHello world!が出力されます。 2番目のサーバーをテストします。
curl http://127.0.0.1:8081/
代わりにHowdy world!が出力されます。
[.note]#Note:このチュートリアルを終了するときのように、両方のテストサーバーが不要になった後で閉じるには、killall flask
。
#を実行するだけです。
次のステップでは、Apacheの構成ファイルを変更して、リバースプロキシとして使用できるようにします。
[[step-3 -—- modifying-the-default-configuration-to-enable-reverse-proxy]] ==ステップ3—デフォルト構成を変更してリバースプロキシを有効にする
このセクションでは、デフォルトのApache仮想ホストを設定して、単一のバックエンドサーバーまたは負荷分散されたバックエンドサーバーのアレイのリバースプロキシとして機能します。
[。注意]##
Note:このチュートリアルでは、仮想ホストレベルで構成を適用します。 Apacheのデフォルトのインストールでは、単一のデフォルトの仮想ホストのみが有効になっています。 ただし、他の仮想ホストでもこれらの構成フラグメントをすべて使用できます。 Apacheの仮想ホストの詳細については、このHow To Set Up Apache Virtual Hosts on Ubuntu 16.04チュートリアルをお読みください。
ApacheサーバーがHTTPサーバーとHTTPSサーバーの両方として機能する場合は、HTTPとHTTPSの両方の仮想ホストにリバースプロキシ構成を配置する必要があります。 Apacheを使用したSSLの詳細については、このHow To Create a Self-Signed SSL Certificate for Apache in Ubuntu 16.04チュートリアルを参照してください。
nano
またはお気に入りのテキストエディタを使用して、デフォルトのApache設定ファイルを開きます。
sudo nano /etc/apache2/sites-available/000-default.conf
そのファイル内には、最初の行から始まる<VirtualHost *:80>
ブロックがあります。 以下の最初の例では、このブロックを単一のバックエンドサーバーのリバースプロキシに構成する方法を説明し、2番目の例では複数のバックエンドサーバーの負荷分散リバースプロキシを設定します。
[[example-1 -—- reverse-proxying-a-single-backend-server]] ===例1—単一のバックエンドサーバーのリバースプロキシ
VirtualHost
ブロック内のすべての内容を次のように置き換えると、構成ファイルは次のようになります。
/etc/apache2/sites-available/000-default.conf
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
手順2でサーバーの例を実行した場合は、上記のブロックに記述されているように127.0.0.1:8080
を使用します。 独自のアプリケーションサーバーがある場合は、代わりにそのアドレスを使用します。
ここには3つのディレクティブがあります。
-
ProxyPreserveHost
により、Apacheは元のHost
ヘッダーをバックエンドサーバーに渡します。 これは、アプリケーションへのアクセスに使用されるアドレスをバックエンドサーバーに認識させるので便利です。 -
ProxyPass
は、メインのプロキシ構成ディレクティブです。 この場合、ルートURL(/
)の下にあるすべてのものを、指定されたアドレスのバックエンドサーバーにマップする必要があることを指定します。 たとえば、Apacheが/example
の要求を受け取ると、http://your_backend_server/example
に接続し、元のクライアントに応答を返します。 -
ProxyPassReverse
は、ProxyPass
と同じ構成にする必要があります。 Apacheにバックエンドサーバーからの応答ヘッダーを変更するよう指示します。 これにより、バックエンドサーバーがロケーションリダイレクトヘッダーを返す場合、クライアントのブラウザーはバックエンドサーバーアドレスではなくプロキシアドレスにリダイレクトされます。これは意図したとおりに機能しません。
これらの変更を有効にするには、Apacheを再起動します。
sudo systemctl restart apache2
これで、Webブラウザーでhttp://your_server_ip
にアクセスすると、標準のApacheウェルカムページの代わりにバックエンドサーバーの応答が表示されます。 手順2に従った場合、これはHellow world!が表示されることを意味します。
[[example-2 -—- load-balancing-across-multiple-backend-servers]] ===例2—複数のバックエンドサーバー間での負荷分散
複数のバックエンドサーバーがある場合、プロキシ時にトラフィックをサーバー間で分散する良い方法は、mod_proxy
の負荷分散機能を使用することです。
VirtualHost
ブロック内のすべての内容を次のように置き換えると、構成ファイルは次のようになります。
/etc/apache2/sites-available/000-default.conf
BalancerMember http://127.0.0.1:8080
BalancerMember http://127.0.0.1:8081
ProxyPreserveHost On
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
構成は前の構成と似ていますが、単一のバックエンドサーバーを直接指定する代わりに、追加のProxy
ブロックを使用して複数のサーバーを定義しました。 ブロックの名前はbalancer://mycluster
(名前は自由に変更できます)で、1つ以上のBalancerMember+`s, which specify the underlying backend server addresses. The `+ProxyPass
で構成され、ProxyPassReverse
ディレクティブは特定の代わりにmycluster
という名前のロードバランサープールを使用しますサーバ。
手順2のサーバーの例に従った場合は、上記のブロックに記述されているように、BalancerMember
ディレクティブに127.0.0.1:8080
と127.0.0.1:8081
を使用します。 独自のアプリケーションサーバーがある場合は、代わりにそのアドレスを使用します。
これらの変更を有効にするには、Apacheを再起動します。
sudo systemctl restart apache2
Webブラウザでhttp://your_server_ip
にアクセスすると、標準のApacheページではなく、バックエンドサーバーの応答が表示されます。 手順2を実行した場合、ページを複数回更新すると、Hello world!とHowdy world!が表示されます。これは、リバースプロキシが機能し、両方のサーバー間で負荷分散されていることを意味します。
結論
これで、Apacheを1つ以上の基礎となるアプリケーションサーバーへのリバースプロキシとして設定する方法がわかりました。 mod_proxy
を効果的に使用して、PythonとDjango、RubyとRuby on Railsなど、さまざまな言語とテクノロジーで記述されたアプリケーションサーバーへのリバースプロキシを構成できます。 また、トラフィックの多いサイトの複数のバックエンドサーバー間のトラフィックのバランスをとったり、複数のサーバーで高可用性を提供したり、SSLをネイティブにサポートしていないバックエンドサーバーに安全なSSLサポートを提供したりするためにも使用できます。
mod_proxy
とmod_proxy_http
は、おそらく最も一般的に使用されるモジュールの組み合わせですが、さまざまなネットワークプロトコルをサポートする他のいくつかの組み合わせがあります。 ここでは使用しませんでしたが、他の一般的なモジュールには次のものがあります。
-
FTPの場合は
mod_proxy_ftp
。 -
SSLトンネリングの場合は
mod_proxy_connect
。 -
TomcatベースのバックエンドのようなAJP(Apache JServ Protocol)の
mod_proxy_ajp
。 -
Webソケットの場合は
mod_proxy_wstunnel
。
mod_proxy
の詳細については、the official Apache mod_proxy
documentationを参照してください。