【メモ】HTTP/2リバースプロキシnghttpxをDockerで実行するときのTips

2016.09.26

ども、大瀧です。
gRPCの関連ツールとしてHTTP/2リバースプロキシであるnghttpxを触っています。手軽に利用するためにDockerで実行する場合のTipsをいくつかご紹介します。

1. Dockerイメージはdit4c/nghttpxがオススメ

Docker Hubでnghttpxを検索するといくつかのイメージが表示されますが、dit4c/nghttpxが使い勝手が良く、おすすめです。ベースイメージがAlpine Linuxなのでイメージのサイズが小さく、最小限のDockerfileなのでカスタマイズしやすいです。ただ、タグがルーズ(latestのみで、ビルド時のAlpine Linuxのパッケージ最新版を利用)なので、以下のようにnghttpx -vを実行してバージョンを確認してから利用するのが良いでしょう。

$ sudo docker run -it --rm dit4c/nghttpx -v
nghttpx nghttp2/1.13.0
$

今回は、バージョン1.13.0でした。

2. アクセスログを標準出力に出力

nghttpxのログは既定ではアクセスログなし、エラーログは標準エラー出力に出ます。Dockerで実行する場合はdocker logsコマンドで確認できるコンテナログが望ましいと思うので、エラーログはそのまま、アクセスログを標準出力(/dev/stdout)に向けるのが良いでしょう。アクセスログは--accesslog-fileオプションで指定します。

--accesslog-file=/dev/stdout

アクセスログの形式も、以下の既定値と変更方法(--accesslog-formatオプション)を把握しておくと良いでしょう。

アクセスログ形式の既定値

$remote_addr - - [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"

このあたりはnghttpxのドキュメントが詳しいです。

3. バージョン1.8以前の説明はオプションが古くて動かない

nghttpxはバージョン1.9でオプション形式に変更があり、一部のオプションはバージョン1.8以前と互換性がありません。自分が検証したときには、--http2-bridge--frontend-no-tls--backend-no-tlsが軒並み通らず、焦りました。以下の移行ドキュメントが参考になります。

--http2-bridgeオプションは、-b|--backendオプションのプロトコル指定にh2を入れて代用します。

-b "172.17.0.1,50051;;proto=h2"

--frontend-no-tls--backend-no-tlsも、-f|--frontendおよび-b|--backendオプションのパラメータにno-tlsをそれぞれ指定する形になりました。

-b "172.17.0.1,50051;;proto=h2;no-tls" \
-f "0.0.0.0,3000;no-tls" \

以上をまとめた、Dockerコンテナの実行例を以下に示します。ローカルの別コンテナがエクスポートする50051番ポートのHTTP/2サービスにプロキシし、アクセスログにX-Forwarded-Forを追加したものです。

$ sudo docker run -d  \
  -p 3000:3000 \
  dit4c/nghttpx \
  -b "172.17.0.1,50051;;proto=h2;no-tls" \
  -f "0.0.0.0,3000;no-tls" \
  --accesslog-file=/dev/stdout \
  --accesslog-format='$remote_addr - - [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_x_forwarded_for'

まとめ

HTTP/2リバースプロキシnghttpxを、Dockerコンテナで実行する際のTipsをいくつかご紹介しました。何かのお役に立てば幸いです。

参考URL