序章

リバースプロキシは、HTTP(S)リクエストを受け取り、それらを1つ以上のバックエンドサーバーに透過的に配信するタイプのプロキシサーバーです。 最近の多くのWebアプリケーションは、バックエンドアプリケーションサーバーを使用して着信HTTP要求を処理するため、リバースプロキシは便利です。 これらのサーバーは、ユーザーが直接アクセスすることを意図したものではなく、多くの場合、基本的なHTTP機能のみをサポートします。

リバースプロキシを使用して、これらの基盤となるアプリケーションサーバーに直接アクセスされないようにすることができます。 また、着信要求からの負荷を複数の異なるアプリケーションサーバーに分散して、大規模なパフォーマンスを向上させ、フェイルセーフを提供するためにも使用できます。 キャッシュ、圧縮、SSL暗号化など、アプリケーションサーバーが提供しない機能でギャップを埋めることができます。

このチュートリアルでは、Apacheを基本的なリバースプロキシとして設定します。 mod_proxy 同じネットワーク上で実行されている1つまたは複数のバックエンドサーバーに着信接続をリダイレクトする拡張機能。 このチュートリアルでは、 Flask Webフレームワークで記述されたバックエンドを使用しますが、任意のバックエンドサーバーを使用できます。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • この初期サーバーセットアップチュートリアルでセットアップされた1つのUbuntu20.04サーバー。 sudorootユーザーとファイアウォール。
  • [X43X] Ubuntu 20.04にApacheWebサーバーをインストールする方法のステップ1および2に従って、サーバーにApache2をインストールします。

ステップ1—必要なApacheモジュールを有効にする

Apacheには多くのモジュールがバンドルされており、これらは使用可能ですが、新規インストールでは有効になりません。 まず、このチュートリアルで使用するものを有効にする必要があります。

必要なモジュールは mod_proxy それ自体と、さまざまなネットワークプロトコルをサポートするように機能を拡張するアドオンモジュールのいくつか。 具体的には、以下を使用します。

  • mod_proxy:接続をリダイレクトするためのメインプロキシモジュール。 これにより、Apacheが基盤となるアプリケーションサーバーへのゲートウェイとして機能できるようになります。
  • mod_proxy_http:HTTP接続のプロキシのサポートを追加します。
  • mod_proxy_balancermod_lbmethod_byrequests:これらは、複数のバックエンドサーバーの負荷分散機能を追加します。

これらの4つのモジュールを有効にするには、次のコマンドを実行します。

  1. sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests

これらの変更を有効にするには、Apacheを再起動します。

  1. sudo systemctl restart apache2

これで、ApacheはHTTPリクエストのリバースプロキシとして機能する準備が整いました。 次のオプションの手順では、2つの基本的なバックエンドサーバーを作成します。 これらは、構成が正しく機能するかどうかを確認するのに役立ちますが、独自のバックエンドアプリケーションが既にある場合は、ステップ3にスキップできます。

一部のバックエンドサーバーを実行すると、Apache構成が正しく機能しているかどうかをテストするのに役立ちます。 ここでは、1行のテキストを出力してHTTPリクエストに応答する2つのテストサーバーを作成します。 一方のサーバーはHelloworld!と表示し、もう一方のサーバーは Howdy world!と表示します。これにより、複数のサービス間の負荷分散をテストできます。

注:実際のセットアップでは、バックエンドサーバーは通常、すべて同じ種類のコンテンツを返します。 ただし、このテストでは、2つのサーバーが異なるメッセージを返すようにすることで、負荷分散メカニズムが両方を使用していることを確認できます。

Flask は、Webアプリケーションを構築するためのPythonマイクロフレームワークです。 このステップでは、最小限のアプリケーションで数行のコードしか必要としないため、Flaskを使用してテストサーバーを作成する方法の概要を説明します。 これらを設定するためにPythonを知っている必要はありませんが、学びたい場合は、Pythonでコーディングする方法のシリーズをチェックしてください。

まず、を使用してパッケージインデックスリストを更新します apt:

  1. sudo apt update

次にインストールします pip、推奨されるPythonパッケージマネージャー:

  1. sudo apt install python3-pip

次に、 pip Flaskをインストールするには:

  1. sudo pip3 install Flask

必要なすべてのコンポーネントがインストールされたので、現在のユーザーのホームディレクトリにある最初のバックエンドサーバーのコードを含む新しいファイルを作成します。 お好みのテキストエディタでこれを行うことができます。ここでは使用します nano:

  1. nano ~/backend1.py

次のコードスニペットをファイルに挿入します。

〜/ backend1.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello world!'

コードの最初の2行は、Flaskフレームワークを初期化します。 1つの機能があります、 home()、テキストの行を返します(Hello world!). The @app.route('/') 上の線 home() 関数定義はFlaskに使用するように指示します home()に向けられたHTTPリクエストへの応答としてのの戻り値 / アプリケーションのルートURL。

完了したら、ファイルを保存して終了します。 使用している場合 nano、を押すことでこれを行うことができます CTRL + X、 それから YENTER.

2番目のバックエンドサーバーは、異なる行のテキストを返すことを除けば、最初のサーバーとまったく同じです。 したがって、実行します cp 最初のファイルからコンテンツをコピーするには、 backend1.pybackend2.py ファイル:

  1. cp ~/backend1.py ~/backend2.py

次に、お好みのテキストエディタを使用して、新しくコピーしたファイルを開きます。

  1. 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 これは、コンソール出力をさらに曇らせるためです。

  1. FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &

ここでは、あなたは flask コマンドを設定して FLASK_APP 同じ行の環境変数。 環境変数は、シェルから生成されたプロセスに情報を渡すための便利な方法です。 環境変数の詳細については、LinuxVPSで環境変数とシェル変数を読み取って設定する方法のガイドを参照してください。

この場合、環境変数を使用すると、設定が実行中のコマンドにのみ適用され、その後は使用できなくなります。 これは、混乱を避けるために必要です。同じ方法で別のファイル名を渡して、 flask 2番目のサーバーを起動するコマンド。

同様に、次のコマンドを実行して、ポートで2番目のサーバーを起動します。 8081. の異なる値に注意してください FLASK_APP 環境変数:

  1. FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &

これで、2つのサーバーが実行されているかどうかをテストできます。 curl 指図。 最初のサーバーをテストすることから始めます。 このコマンドは curl 接続するには 127.0.0.1localhostを表す特別なIPアドレス。 これは、次のコマンドがサーバーに接続して独自の応答を出力するように指示することを意味します。

  1. curl http://127.0.0.1:8080/

これにより、サーバーから次の応答が出力されます。

Output
Hello world!

次に、2番目のサーバーをテストします。

  1. curl http://127.0.0.1:8081/

以前と同様に、これによりサーバーからの期待される応答が出力されます。

Output
Howdy world!

次のステップでは、Apacheの構成ファイルを変更して、リバースプロキシとして使用できるようにします。

ステップ3—リバースプロキシを有効にするためにデフォルト構成を変更する

このセクションでは、単一のバックエンドサーバーまたは負荷分散されたバックエンドサーバーのアレイのリバースプロキシとして機能するように、デフォルトのApache仮想ホストを設定します。

:このチュートリアルでは、仮想ホストレベルで構成を適用しています。 Apacheのデフォルトのインストールでは、有効になっているデフォルトの仮想ホストは1つだけです。 ただし、これらすべての構成フラグメントを他の仮想ホストでも使用できます。 Apacheの仮想ホストの詳細については、 Ubuntu20.04でApache仮想ホストを設定する方法のチュートリアルを参照してください。

ApacheサーバーがHTTPサーバーとHTTPSサーバーの両方として機能する場合は、リバースプロキシ構成をHTTP仮想ホストとHTTPS仮想ホストの両方に配置する必要があります。 Apacheを使用したSSLの詳細については、 Ubuntu20.04チュートリアルでApacheの自己署名SSL証明書を作成する方法に関するチュートリアルを参照してください。

お好みのテキストエディタを使用して、デフォルトのApache設定ファイルを開きます。

  1. sudo nano /etc/apache2/sites-available/000-default.conf

そのファイルの中には、 <VirtualHost *:80> 最初の行から始まるブロック。 次の最初の例では、単一のバックエンドサーバーのリバースプロキシにこのブロックを構成する方法を説明し、2番目の例では、複数のバックエンドサーバーの負荷分散されたリバースプロキシを設定します。

例1—単一のバックエンドサーバーのリバースプロキシ

まず、内のすべてのコンテンツを置き換えます VirtualHost 構成ファイルが次のようになるようにブロックします。 ステップ2のサンプルサーバーを実行した場合は、次を使用します。 127.0.0.1:8080. 独自のアプリケーションサーバーがある場合は、代わりにそれらのアドレスを使用してください。

/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

表示されるディレクティブは3つあり、それらが実行していることの概要は次のとおりです。

  • ProxyPreserveHost:Apacheにオリジナルを渡します Host バックエンドサーバーへのヘッダー。 これは、バックエンドサーバーにアプリケーションへのアクセスに使用されるアドレスを認識させるので便利です。
  • ProxyPass:メインプロキシ構成ディレクティブ。 この場合、ルートURLの下にあるすべてのものを指定します(/)は、指定されたアドレスのバックエンドサーバーにマップする必要があります。 たとえば、Apacheが /example、に接続します http://your_backend_server/example 応答を元のクライアントに返します。
  • ProxyPassReverse:と同じ構成にする必要があります ProxyPass. バックエンドサーバーからの応答ヘッダーを変更するようにApacheに指示します。 これにより、バックエンドサーバーがロケーションリダイレクトヘッダーを返す場合、クライアントのブラウザはバックエンドサーバーアドレスではなくプロキシアドレスにリダイレクトされ、意図したとおりに機能しなくなります。

このコンテンツの追加が完了したら、ファイルを保存して終了します。

これらの変更を有効にするには、Apacheを再起動します。

  1. sudo systemctl restart apache2

今、あなたがアクセスする場合 http://your_server_ip Webブラウザーでは、標準のApacheウェルカムページの代わりにバックエンドサーバーの応答が表示されます。 ステップ2に従った場合、これは、ブラウザーに Hello world!が表示されることを意味します。

例2—複数のバックエンドサーバー間での負荷分散

複数のバックエンドサーバーがある場合、プロキシ時にトラフィックをサーバー間で分散する良い方法は、の負荷分散機能を使用することです。 mod_proxy.

まず、お好みのテキストエディタを使用してデフォルトのApache設定ファイルを開きます。

  1. sudo nano /etc/apache2/sites-available/000-default.conf

次に、内のすべてのコンテンツを置き換えます VirtualHost 構成ファイルが次のようになるようにします。 ステップ2のサンプルサーバーを実行した場合は、次を使用します。 127.0.0.1:8080127.0.0.1:8081 のために BalancerMember ディレクティブ。 独自のアプリケーションサーバーがある場合は、代わりにそれらのアドレスを使用してください。

/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:8081
</Proxy>

    ProxyPreserveHost On

    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>

構成は前の構成と似ていますが、単一のバックエンドサーバーを直接指定する代わりに、これらのディレクティブは次のことを実行します。

  • Proxy:この追加 Proxy ブロックは、複数のサーバーを定義するために使用されます。 ブロックの名前は balancer://mycluster (名前は自由に変更できます)1つ以上で構成されます BalancerMembers。基になるバックエンドサーバーのアドレスを指定します。
  • ProxyPassProxyPassReverse: these directives use the load balancer pool named 特定のサーバーの代わりにmycluster`。

ステップ2のサンプルサーバーを実行した場合は、次を使用します。 127.0.0.1:8080127.0.0.1:8081 のために BalancerMember 上記のブロックに記述されているディレクティブ。 独自のアプリケーションサーバーがある場合は、代わりにそれらのアドレスを使用してください。

このコンテンツの追加が完了したら、ファイルを保存して終了します。

これらの変更を有効にするには、Apacheを再起動します。

  1. sudo systemctl restart apache2

アクセスした場合 http://your_server_ip Webブラウザーでは、標準のApacheページの代わりに、バックエンドサーバーの応答が表示されます。 ステップ2を実行した場合、ページを複数回更新すると、 Hello world! Howdy world!が表示されます。これは、リバースプロキシが機能し、サーバー間の負荷分散が行われていることを意味します。両方のサーバー。

:このチュートリアルを終了したときのように、両方のテストサーバーが不要になった後で閉じるには、次のコマンドを実行できます。 killall flask 指図。

結論

これで、1つまたは複数の基盤となるアプリケーションサーバーへのリバースプロキシとしてApacheを設定する方法がわかりました。 mod_proxy PythonとDjango、RubyとRuby on Railsなど、さまざまな言語とテクノロジーで記述されたアプリケーションサーバーへのリバースプロキシを効果的に構成できます。 また、トラフィックの多いサイトの複数のバックエンドサーバー間でトラフィックのバランスをとったり、複数のサーバーを介して高可用性を提供したり、SSLをネイティブにサポートしていないバックエンドサーバーに安全なSSLサポートを提供したりするためにも使用できます。

その間 mod_proxymod_proxy_http おそらく最も一般的に使用されるモジュールの組み合わせですが、さまざまなネットワークプロトコルをサポートする他のモジュールがいくつかあります。 このチュートリアルではそれらを使用しませんでしたが、他の一般的なモジュールには次のものがあります。

  • mod_proxy_ftp FTP(ファイル転送プロトコル)の場合。
  • mod_proxy_connect SSLトンネリング用。
  • mod_proxy_ajp TomcatベースのバックエンドなどのAJP(Apache JServプロトコル)用。
  • mod_proxy_wstunnel Webソケット用。

詳細については mod_proxy公式のApachemod_proxyドキュメントを読むことができます。