nginx のリバースプロキシ設定

f:id:Naotsugu:20201019221824p:plain


はじめに

nginx の利用用途として多いリバースプロキシの設定まとめです。

nginx の導入方法については以下を参照してください。

blog1.mammb.com

/etc/nginx/conf.d/default.conf; に対する設定(http コンテキスト配下)として記載します。


upstream コンテキストによるバックエンドの指定

リバースプロキシとして扱うには upstream コンテキストでバックエンドのサーバを指定します。

upstream backend1 {
  server 192.168.0.1:8080;
  server 192.168.0.2:8080;
}
server {
  listen 80;
  server_name  localhost;
  location / {
    proxy_pass http://backend1;
  }
}

ここでは backend1 という名前でバックエンドサーバのグループに名前を付けています。 nginx で受け付けたリクエストがバックエンドのサーバ 192.168.0.1 と 192.168.0.2 に転送されます。

location コンテキスト内の proxy_pass ディレクティブで backend1 という名前で転送先を指定します。

バックエンドへのリクエストを http://backend1 のように upstream の名前とした場合、リクエストパスがそのままバックエンドにリクエストされます。

http://backend1/foo/ のように upstream の名前の後にパス名をつけた場合、location で指定したパス名が置換されます。

以下のような設定があった場合

  location /path {
      proxy_pass http://backend1/foo/;
  }

/pathbar/index.html というパスでのリクエストは /foo/bar/index.html というパスでバックエンドにリクエストされます。

proxy_pass により書き換えられたリクエストは、バックエンドサーバからリダイレクトされた場合でも Location ヘッダが適切な値に書き換えられます。 これは proxy_redirect ディレクティブのデフォルト値が default と定義されているためです。 rewrite ディレクティブなどによりURLの書き換えを行った場合には、proxy_redirect ディレクティブで書き換えルールを指定することができます。

リバースプロキシ側で HTTPS 通信を行い、バックエンドには HTTP 接続を行うには、通常通り nginx 側に SSL の設定を行うことで対応できます。

server {
  listen 443 ssl;
  ssl_certificate /path/to/certificate;
  ssl_certificate_key /path/to/certificate_key;

}


リクエストのバランシング

先程の例では、バックエンドへのリクエストの振り分けはラウンドロビンで行われます。

振り分けに重み付けを行うには以下のように weight を指定することができます。

  upstream backend1 {
    server 192.168.0.1:8080 weight=2;
    server 192.168.0.2:8080;
  }

weight を省略した場合には weight=1 と同等となり、192.168.0.1 に 66%、192.168.0.2 に 33% のリクエストがわりふられます。

一方を待機系にするには backup を指定します。

  upstream backend1 {
    server 192.168.0.1:8080;
    server 192.168.0.2:8080 backup;
  }

通常系にエラーが発生した場合に限り、待機系にリクエストするようになります。

接続数の少ないバックエンドに優先的に振り分けを行うには以下のように least_conn を指定します。

  upstream backend1 {
    least_conn;
    server 192.168.0.1:8080;
    server 192.168.0.2:8080;
  }

接続元のIPアドレスに応じて振り分け先を固定するには ip_hash を指定します。

  upstream backend1 {
    ip_hash;
    server 192.168.0.1:8080;
    server 192.168.0.2:8080;
  }

クライアントIPアドレスのハッシュ値に応じて振り分け先が決定されます。

クライアントのIPアドレスではなく、任意の値のハッシュ値により振り分けを行うには以下のようにします。

  upstream backend1 {
    hash $http_user_agent;
    server 192.168.0.1:8080;
    server 192.168.0.2:8080;
  }

この例ではユーザエージェントのハッシュ値による振り分けを行います。


タイムアウト

バックエンドサーバに対するタイムアウトは以下のように指定します。

  location / {
    proxy_pass http://backend1;
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
  }

proxy_connect_timeout は接続タイムアウトとなります。TCP接続が開始できない場合はすぐに別サーバへ振り分けが行われますが、接続シーケンスのやり取りの応答が得られない場合などはここで設定したタイムアウトで処理が打ち切られて別サーバへの振り分けが行われます。

proxy_read_timeoutproxy_send_timeout はそれぞれ受信/送信データが残っているが、それらの受信/送信処理が滞った場合のタイムアウトです。 タイムアウトが発生した場合、同じリクエストを振り分け先のサーバに対してリトライします。そのため短すぎるタイムアウトを設定した場合多重POSTなどが発生するケースがあるため注意が必要です。

タイムアウトが発生した場合、対象サーバへのアクセスはデフォルトで10秒間抑止されます。これらの動作を変更する場合には、max_failsfail_timeout を使います。

  upstream backend1 {
    server 192.168.0.1:8080 max_fails=2 fail_timeout=15s;
    server 192.168.0.2:8080;
  }

上記の設定とした場合、15秒以内に2回バックエンドサーバへのアクセスが失敗した場合、15秒間は対象サーバへのアクセスを控える動作となります。


リクエストヘッダの追加

クライアントのIPアドレスなどはリバースプロキシ側で X- で始まる追加ヘッダとして付与することが一般的です。

proxy_set_header を使うことでバックエンドのサーバに追加のヘッダ情報を引き渡すことができます。

server {
  proxy_set_header Host               $host;
  proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host   $host;
  proxy_set_header X-Forwarded-Server $hostname;
  proxy_set_header X-Real-IP          $remote_addr;
}


バックエンドへの Keep-Alive 接続

nginx ではバックエンドへのリクエストは HTTP/1.0 となり Connection は close となります。

バックエンドへのリクエストに Keep-Alive を使うには以下のようにします。

upstream backend1 {
    server 192.168.0.1:8080;
    server 192.168.0.2:8080;
    keepalive 32
}
server {
    listen 80;
    location / {
      proxy_set_header Connection "";
      proxy_http_version 1.1;
      proxy_pass http://app1;
    }
}

server.location コンテキストで proxy_set_header Connection でヘッダを空に設定し、proxy_http_version で HTTP/1.1 を利用するように設定します。

upstream コンテキストの keepalive ディレクティブでは、Keep-Alive で接続を保持する待機中のコネクション数(worker別)を指定します。



マスタリングNginx

マスタリングNginx

nginx実践ガイド impress top gearシリーズ

nginx実践ガイド impress top gearシリーズ

  • 作者:渡辺高志
  • 発売日: 2017/02/16
  • メディア: Kindle版