キャッシュ機能付きリバースプロクシ「Apache Traffic Server」を使ってみる

昨今ではWebサービスを運営する場合、リバースプロクシを介してサービスを公開するという運用形態が多く見られる。こういった構成の際に使われるリバースプロクシサーバーはいくつかがあるが、今回は優れたキャッシュ機能が特徴の「Apache Traffic Server」を紹介する。

HTTP/2にも対応するキャッシュサーバー

Apache Traffic Serverは、Apache Software Foundation(ASF)傘下で開発が進められているキャッシュプロクシサーバーだ(図1)。ASF傘下のプロジェクトとしてはWebサーバー「Apache HTTP Server」が有名だが、Traffic ServerはHTTP Serverとはまったく異なるソフトウェアで、元々は米Yahooが独自に開発を行っていたものが由来となっている。2009年にオープンソース化されてApacheプロジェクト傘下となり、現在では世界各国の多くの企業で利用されるようになっている。

図1 Apache Traffic ServerのWebサイト

キャッシュプロクシサーバーとは

キャッシュプロクシサーバーは、クライアント(Traffic Serverの場合は主としてWebブラウザ)と、コンテンツを配信するWebサーバー(Traffic Serverにおいては「オリジンサーバー」と呼ばれる)の間を中継するソフトウェアだ。単にこの動作のみを行うソフトウェアはプロクシサーバーやリバースプロクシサーバーなどと呼ばれるが、キャッシュプロクシサーバーはオリジンサーバーから受け取ったコンテンツを保存(キャッシュ)し、そのコンテンツの配信をオリジンサーバーに代わって行う仕組みをを搭載している点が特徴となっている(図2)。

図2 Traffic Serverのキャッシュ動作

Traffic Serverでは、キャッシュされているURLへのリクエストはオリジンサーバーに転送せずに、キャッシュしていたコンテンツをそのままレスポンスとして返す。こういった仕組みにより、オリジンサーバーの負荷軽減や、レスポンスの高速化が期待できる。

また、特定の条件に合致したリクエストについてはコンテンツをキャッシュせず、毎回オリジンサーバーにリクエストを転送するような設定が可能だ。たとえばログイン機能が実装されている会員制サイトなどでは、そのユーザーごとに異なる情報を表示する仕組みになっていることが多い。こういったサイトでも適切な設定を行うことで、どのユーザーに対しても同じ結果を返すコンテンツはキャッシュして負荷軽減を行い、特定のユーザーのみに表示したいコンテンツについてはキャッシュしない、という動作が可能になる。ただし、設定を間違えると情報漏洩の危険性もあるので、こういった設定については慎重に設計し、十分なテストを行ってから利用するよう注意したい。

Apache Traffic Serverの特徴

Traffic Serverの大きな特徴としては、まずキャッシュ設定を柔軟に行える点がある。URL単位でキャッシュの有効/無効やキャッシュの有効期間などを設定できる。また、リクエストの「Cookie:」ヘッダーの有無や、レスポンスのキャッシュ関連ヘッダーの値、コンテンツの種別に応じてキャッシュを行うか否かの挙動を変えることも可能だ。

プロキシ設定についても、keep-aliveの利用やリクエストのTraffic Serverでのフィルタリング、ロードバランシングなどを細かい粒度で指定できるようになっている。さらにTraffic Server自体をクラスタ構成で運用することも可能だ。そのほかプラグイン機構も備えており、ヘッダの内容などに応じて独自にキャッシュを管理したり挙動を変えるようなプラグインを独自に作成することもできる。HTTP/2に対応している点も大きな特徴だ。

Traffic Serverは元々米Yahoo!で開発されていたということで、導入実績も豊富だ。たとえば米Yahoo!では1日あたり400TBのトラフィックを捌くような構成での運用が行われていたという。また、Yahoo! JAPANでもTraffic Serverを使って大規模なコンテンツ配信システムを構築しているそうだ。

Apache Traffic Serverのバージョン

記事執筆時点でのTraffic Serverの最新版はバージョン7.x系だ。また、バージョン4系、5系、6系についてもまだサポートは続けられている。現在多くのディストリビューションではバージョン5系もしくはバージョン7系が提供されているようだ。バージョン7系ではHTTP/2のサーバープッシュ機能に対応したほか、多くの機能強化が行われている。なお、HTTP/2のサポート自体はバージョン6で安定扱いとなっており、こちらでも基本的な機能は利用できる。

以下では、Red Hat Enterprise Linux(RHEL)およびその互換環境CentOS、Fedoraで提供されているバージョン5.3.0をベースにTraffic Serverの機能や基本的な設定方法を紹介する。

Apache Traffic Serverのインストールと設定

Apache Traffic Serverは多くのLinuxディストリビューションで標準パッケージとして提供されている。たとえばDebian/Ubuntuでは「trafficserver」というパッケージ名で提供されており、こちらをインストールするのがもっとも簡単だ。

# apt-get install trafficserver

また、RHEL/CentOSでは拡張パッケージ集であるEPELで「trafficserver」パッケージが提供されている。たとえばCentOSでは「epel-release」パッケージをインストールしてこのリポジトリを利用可能にすれば、yumコマンドでのインストールが行える。

# yum install epel-release
# yum install trafficserver

もちろん、ソースコードからのインストールも可能だ。ただしこの場合、バグ修正や脆弱性修正を含むマイナーアップデートリリースが行われた場合、その都度自分でビルドを行わなければならないという手間がある。ディストリビューションのパッケージでは提供されていない最新バージョンを利用したい場合など、特段の理由がある場合以外はおすすめしない。ビルド方法についてはTraffic Serverのドキュメントで説明されている。

なお、Docker向けの公式コンテナイメージは用意されておらず、第三者が作成して公開している非公式イメージがいくつかあるだけだ。Docker上でTrafficServerを動かしたい場合、自分でコンテナイメージを作成することをおすすめする。

Traffic Serverの設定ファイル

Traffic Serverでは複数の設定ファイルが用意されており、設定内容ごとに異なる設定ファイルを編集する必要がある(表1)。これらファイルは通常は/etc/trafficserver以下に格納される。ただしこのすべてを編集する必要はなく、目的に応じて必要なファイルのみを編集すれば良い。

表1 Traffic Serverの設定ファイル
ファイル名 設定内容
cache.config キャッシュ関連
congestion.config 輻輳発生時の対応
hosting.config オリジンサーバーやドメインごとのキャッシュ管理
icp.config ICP(Internet Cache Protocol)関連
ip.config クライアントに対するアクセス制限
log_hosts.config オリジンサーバーごとのログ出力
logs_xml.config ログの書式やフィルタ、処理内容
parent.config 多段プロクシ利用時の親プロクシ関連
plugin.config プラグイン関連
records.config Traffic Server内で使われる各種変数設定
remap.config リバースプロクシの際のURLマッピング
splitdns.config 使用するDNSサーバー関連
ssl_multicert.config IPアドレス/ホスト名に対し使用するSSLサーバー証明書の割り当て
storage.config キャッシュに使用するストレージ
update.config キャッシュの更新関連
volume.config キャッシュへのストレージ割り当て方法

これら設定ファイルはファイル毎に書式が異なるが、いずれにおいても「#」で始まる行や空行は無視され、また「\」で改行をエスケープできる。

さて、Traffic Serverでは非常に多くの設定項目が用意されている。そのため、今回はまずよく利用されるだろう設定内容について紹介していく。

リバースプロクシのための設定

Traffic Serverを利用するにあたってまず必要となるのがリバースプロクシの設定だ。具体的には、Traffic Serverが受け付けたリクエストをどのオリジンサーバーに向けて転送するかや、その際にリクエストされたパスをどのように変換するかを決めるものとなる。これらの設定はremap.configファイル内に、以下の形式で記述する。

<設定タイプ> <URL> <オリジンサーバーのURL> <タグ> <フィルタ>

「設定タイプ」はその設定行がどのような内容の設定を行うかを示すもので、たとえば指定したURLでのアクセスを単純にオリジンサーバーに転送する場合、次のように「map」を指定する。「タグ」や「フィルタ」は省略が可能だ。

map <URL> <転送先のURL>

設定タイプはmapのほか、次の表2のものが指定できる。ここで「regex_」で始まるものは正規表現を使った指定が可能だが、regex_remap以外はホスト部分にしか正規表現を使えない点には注意したい。

表2 指定できる設定タイプ
タイプ 説明
map、regex_map 指定したURLへのリクエストを、指定したオリジンサーバーのURLへのリクエストに変換する
map_with_referer、regex_map_with_referer リクエストにRefererヘッダーが付与されていた場合のみ指定したリクエスト変換を行う。いわゆる「直リンク禁止」のような設定を行う場合に有用
map_with_recv_port、regex_map_with_recv_port 「map」と同様だが、リクエストを受け取ったポートを使って対象を指定できる
reverse_map オリジンサーバーがリダイレクトを含むレスポンスを返した際に、そのURLを変換する
redirect、regex_redirect オリジンサーバーにリクエストを行うこと無しにリダイレクトを行う
redirect_temporary、regex_redirect_temporary オリジンサーバーにリクエストを行うこと無しにリ一時的なダイレクト(307リダイレクト)を行う

また、<URL>や<オリジンサーバーへのURL>は「<スキーマ>://<ホスト>:<ポート>/<パス>」という形で指定する。たとえば「http://example.com/」へのアクセスを「http://test01/」に転送する場合、次のように設定すれば良い。

map http://example.com/ http://test01/

ここでは、指定したURL以下のパスについてはそのまま指定した転送先のURLに引き継がれる。たとえばこの例の場合、「http://example.com/foo/bar」というリクエストは「http://test01/foo/bar」というURLへのリクエストに変換される。

また、多くの場合Webサーバーにおけるリダイレクトレスポンスを正しく解決できるように同時に「reverse_map」設定も記述しておく必要がある。この設定を行っておくことで、Webサーバーが出力した「Location」ヘッダー内のURLをTraffic ServerのURLに変換されるようになる。

たとえば次のように記述すると、http://test01/というサーバーへのリダイレクトはhttp://example.com/へのリダイレクトに書き換えられるようになる。

reverse_map http://test01/ http://example.com/

mapの場合と同様、指定したURL以下のパスは転送先のURLに引き継がれる。

ちなみに、複数の条件にマッチするリクエストの場合、次の優先順位で変換が行われる。

  1. map_with_recv_port、regex_map_with_recv_port
  2. map、regex_map、reverse_map
  3. redirect、redirect_temporary
  4. regex_redirect、regex_redirect_temporary

また、設定項目が多数に分かれる場合などは、設定を複数のファイルに分割して記述することもできる。その場合、メインの設定ファイル(remap.config)内に「.include <ファイル名>」の形で読み込む設定ファイルを記述しておく必要がある。

キャッシュストレージの設定

Traffic Serverでは、指定したファイルまたはブロックデバイスにキャッシュデータを保存する。この保存先ファイル/ブロックデバイスはstorage.configファイル内に以下の形式で記述する。

<ディレクトリのパス名もしくはデバイスファイル> <容量>

ディレクトリのパスを指定するとそのディレクトリ内に「cache.db」というファイルが作成され、そこにキャッシュデータが格納される。また、デバイスファイル(/dev/sda1など)を指定すると、そのデバイスを直接キャッシュ用ストレージとして利用する。デバイスファイルを利用するほうがパフォーマンスは向上するようだ。

たとえば以下のように設定した場合、/var/cache/trafficserverディレクトリ以下にキャッシュファイル(cache.db)を作成して使用される

/var/cache/trafficserver 256M

Traffic Serverの各種挙動に関わる設定

Traffic Serverの挙動などは、records.configファイル内でパラメータを指定することで行う。ここで設定できるのはたとえばキャッシュの有効/無効やネットワーク接続時の各種パラメータ、利用するスレッド数など多岐にわたる。以下では、設定できるパラメータのうちよく利用されるだろうものに絞って紹介する。より詳しくはドキュメントを参照して欲しい。

records.configファイル内では、次のような形で設定を行う。

<スコープ> <パラメータ名> <型> <値>

ここで「スコープ」および「型」はパラメータに応じて決まっている値で、スコープはその設定がローカルサーバーのみに影響するのか(「LOCAL」)、Traffic Serverクラスタすべてに影響するのか(「CONFIG」)を示している。また、「型」は指定できる値の型を示すもので、「INT」(整数)、「STRING」(文字列)、「FLOAT」(小数)が指定できる。ちなみに型がINTの場合、「K」「M」「G」「T」(それぞれ10の3乗/6乗/9乗/12乗)という接尾辞も利用可能だ。

これら設定パラメータは環境変数を使っても定義できる。たとえば「proxy.config.product_company」変数の値は設定ファイルだけでなく「PROXY_CONFIG_PRODUCT_COMPANY」という環境変数でも定義できる。設定ファイルと環境変数の両方で値が指定された場合、環境変数の値が優先される。

まず設定を確認しておきたいのが、使用するIPアドレスやポートを指定するproxy.config.http.server_portsパラメータだ。ここではIPv4/IPv6で異なる設定を使用するなどさまざまな設定が可能だが、たとえばIPv4のみ使用し、80番ポートで待ち受けを行うには単に「80」とだけ記述すれば良い。

CONFIG proxy.config.http.server_ports STRING 80

また、待ち受けに使用するIPアドレスを指定することもできる。たとえば192.168.10.10というアドレスで待ち受けをする場合、次のように「ip-in」キーワードを使用する。

CONFIG proxy.config.http.server_ports STRING 80:ipv4:ip-in=192.168.10.10

そのほか、ログ関連の設定やRAMキャッシュの容量、リバースプロクシの有効/無効などの確認も行っておくと良いだろう(表3)。

表3 主な設定パラメータ
スコープ 変数名 説明 指定できる値
CONFIG proxy.config.http.server_ports STRING 使用するポート、IPアドレスを指定する
CONFIG proxy.config.output.logfile STRING ログファイルの保存先パス名
CONFIG proxy.config.cache.ram_cache.size INT RAMキャッシュの容量を指定する。デフォルトは-1 -1を指定するとディスクキャッシュ1GBあたり10MBとなる
CONFIG proxy.config.log.logging_enabled INT ログの設定。デフォルトは3 0(無効)、1(エラーのみ)、2(トランザクションのみ)、3(すべて)
CONFIG proxy.config.reverse_proxy.enabled INT リバースプロクシの有効/無効を切り替える。デフォルトは1 0(無効)、1(有効)
CONFIG proxy.config.header.parse.no_host_url_redirect STRING リバースプロキシでhostヘッダがないリクエストのリダイレクト先を指定する

Traffic Serverのログ

Traffic Serverでは、各種ログをその内容毎に異なるファイルに出力する。デフォルトでは/var/log/trafficserverディレクトリに表4のログファイルが作成されるが、これらの保存先や形式、ファイル名などはrecords.configファイルで変更が可能だ。なにか問題があった場合などは、これらのファイルを確認すると良いだろう。

表4 Traffic Serverのログ
種類 出力先
診断メッセージ(diagnosic output) syslogおよびdiags.log
警告やステータス、エラーなどのメッセージ traffic.out
アクセスログ(Squid log形式) squid.blog
管理APIサービスのログ manager.log

デフォルトではアクセスログ(squid.blog)はバイナリ形式となっている。このログファイルは、「traffic_logcat」コマンドでASCII形式に変換できる。たとえばsquid.blogファイルが格納されているディレクトリで以下のように実行すると、標準出力にログが出力される。

$ traffic_logcat squid.blog

Traffic Serverを起動する

設定ファイルの修正や確認を行ったら、Traffic Serverを起動して動作を確認してみよう。パッケージでインストールした場合、systemctlコマンドでTraffic Serverを起動できる。

# systemctl start trafficserver

Traffic Serverが起動したら、続いて稼動サーバーにWebブラウザでアクセスしてリバースプロクシが正しく動作しているかも確認しておこう。

設定の変更

Traffic Serverでは設定ファイルの変更後に再起動を行わなくても、「traffic_line」コマンド利用することで設定を変更できる。具体的には、次のように「-x」オプション付きでtraffic_lineコマンドを実行すれば良い。

# traffic_line -x

これは次のように「systemctl reload」コマンドでも代用できる(systemctl reloadコマンドを実行すると「traffic_line -x」コマンドが実行されるように設定されている)。

# systemctl reload trafficserver

ちなみにTraffic Serverは稼動中に定期的に設定ファイルを書き出すようになっており、その場合古い設定ファイルは「_<数字>」という名前に自動的にリネームされてバックアップとして保存される。

特に設定を行わずとも利用できるものの、キャッシュ設定については要確認

さて、ここまでではTraffic Serverのインストールと基本的な設定について紹介した。Traffic Serverの設定の多くはデフォルトのままでも十分に動作するよう設定されるため、特に設定を行わずともこの段階でもキャッシュプロクシサーバーとして動作するのだが、本格的にTraffic Serverを利用するにはキャッシュ関連の設定は避けて通れない。記事後編では、このキャッシュ関連の設定について紹介する。