NGINX Plusは、オープンソース版のNGINXに様々な機能を拡張し搭載した商用版ソフトウェアです。これらの機能を利用することで、システムの可用性と堅牢性を向上させ、運用を簡素化できます。本特集では、NGINX(オープンソース版)とNGINX Plusの違いなど、そもそもNGINXがどのようなソフトウェアであるのか機能差を実際の設定例とともに紹介していきます。
そもそもNGINXとは
NGINXは、Igor Sysoev氏によって開発されたオープンソースソフトウェアです。初版は2004 年にリリースされました。当時、従来のWEBサーバが持っていたC10K問題(クライアント1万台問題)を解決することを念頭に開発されました。従来のWebサーバのアーキテクチャでは、1クライアントからの接続に対して、サーバの1プロセスあるいは1スレッドを割り当てて処理させていたため、同時接続数が増加すると、比例してプロセス数、スレッド数が増加し、コンテキストスイッチのオーバーヘッド等の原因により、性能低下が引き起こされていました。NGINXでは、イベント駆動型アーキテクチャの採用と、ノンブロッキングI/O多重化、ノンブロッキングI/O など、I/O処理の効率化を図り、クライアントからの接続数とプロセス数、スレッド数との対応を分離し、1プロセス内で複数のクライアントからの接続を処理することで、C10K問題を解決し、軽量で高いスケーラビリティを実現しています。(図1)

その後、2011年に米NGINX社が設立され、オープンソース版の開発と併せて、商用版であるNGINX Plusが提供されるようになりました。2019年5月、F5 NetworksがNGINX 社を買収しましたが、その後も以前と同様に、オープンソース版、商用版の双方共に、開発と提供が継続されています。
また、2019年12月度のNETCRAFT社の調査 によると、世界で最も利用されているWebサーバソフトウェアとされています。このように、NGINXはWEBサーバ単体として利用されることも多いのですが、WEBサーバ機能以外にも、以下のような豊富な機能を持っています。
- ロードバランサ
- リバースプロキシ
- コンテンツ キャッシュ
- APIゲートウェイ
- Web Application Firewall
これらに加え、Kubernetes環境においては、Ingress Controllerとして動作させることが可能で、L7ロードバランサとして動作し、Kubernetesクラスタ内に外部からのトラッフィクを誘導します。なお、Ingress Controllerとして提供されているNGINXは3種類が存在します。1つ目は、Kubernetesコミュニティが開発およびメンテナンスを行うオープンソースの「kubernetes/ingress-nginx」、2つ目はF5 Networks/NGINXが開発およびメンテナンスを行うオープンソースの「nginxinc/kubernetes-ingress with NGINX」、3つ目がF5 Networks/NGINXが開発およびメンテナンスする商用版の「nginxinc/kubernetes-ingress with NGINX Plus」です。それぞれの特徴については、表1を参照ください。

NGINX Plusとは
NGINX Plusは、NGINXの商用版ソフトウェアです。オープンソース版のNGINXに標準で実装されていないセッションパーシステンス機能や、APIによる動的設定変更機能、アクティブヘルスチェック機能などの拡張機能が数多く含まれています。利用者は、これらの機能を活用することにより、システムの可用性と堅牢性を向上させ、運用を簡素化できます。NGINX Plusはコンパイル済みのバイナリパッケージとして提供されますので、サポート対象のOSディストリビューションのパッケージ管理経由で、簡単に導入することが可能です。また、各種パブリッククラウドでは、NGINX Plusがインストールされたマシンイメージも提供されています。
NGINX Plusにはサポートが付属します。ベーシック、プロフェッショナル、エンタープライズと分かれ、サポート時間数や応答時間の異なる3種のプランが用意されており、NGINX Plusのサブスクリプション時に選択します。
その他NGINX製品
NGINX、NGINX Plus以外にも、NGINX製品シリーズとして、複数のソフトウェアやサービスが提供されています。これらの製品群について触れておきます。
NGINX Controller
NGINX Controllerは、複数のNGINX Plusノードを管理するための商用製品です。NGINX Controllerを導入することで、複数のNGINX Plusに対してロードバランサ機能の設定や、APIゲートウェイの設定およびAPIマネジメント機能を提供し、設定、構成の一元化が実現できます。また、リアルタイム監視、モニタリング機能やアラート生成機能などの運用監視機能も提供されます。管理対象のNGINX Plusノードにエージェントソフトウェアを追加インストールし、構成します。


NGINX Unit
- Restful API経由で動的に設定を変更
- 複数言語およびバージョンの同時実行
- プロセス数のオンデマンドスケール
- SSL/TLSのサポート
- 豊富なリクエストルーティングと静的コンテンツのサポート
- Node.js、Java 向けのWebSocketサーバ機能
- アプリケーションの名前空間の分離
- リクエストルーティング時のHTTPプロキシ
また、NGINX Unitが対応しているプログラミング言語は以下になります。
- Python
- PHP
- Go
- Perl
- Ruby
- JavaScript (Node.js)
- Java
その他詳細は、https://www.nginx.co.jp/products/nginx-unit/を参照ください。

NGINX App Protect
NGINX App Protectは、2020年5月にリリースされた商用版であるNGINX Plus上で動くWAFモジュールです。アプリケーションのパフォーマンスとセキュリティを確保する製品の提供で実績があるF5の豊富なWAF機能を移植した製品となっています。その特徴の1つは、極めて低い誤検知率を実現する信頼性の高いシグネチャを中心とした防御機能の充実です。従来のシグネチャに加え、F5が独自収集しているリアルタイムの攻撃情報を元に生成した高精度シグネチャ(Threat Campaigns)を利用しセキュリティポリシーを構成することで、アプリケーションの脆弱性に対する迅速な対処が図れます。またAPIゲートウェイとしての機能強化の一環として、多様なプロトコルへの適応も進めています。
そして、もう一つのポイントはパフォーマンスです。グラフで分かる通り、ModSecurityとの比較ではThroughput、Requests/secの性能は桁違いに高く、Latencyは、WAFモジュ−ルを適応していない状態とほぼ変わらない程度に抑えられています。(F5調べ)。高性能なNGINX App Protectを利用することで、例えばパブリッククラウドでのリソース利用を抑制や、オンプレミスでのハードウェアリソースの抑制などなど、コスト削減の効果を得やすくなります。
そのほか詳細は、https://www.nginx.co.jp/products/nginx-app-protect/をご覧ください。

NGINX Service Mesh
NGINX Service Mesh(NSM)は、データプレーンが重要であるという着想のもと、独自に設計されたシンプルなサービスメッシュソリューションです。高可用でスケーラブルなコンテナ環境の運用に、NGINX Plusをデータプレーンとして利用することで、他のリバースプロキシサイドカーでは提供不可能なレベルのインテリジェンスなトラフィック管理を提供します。
単一の設定でIngressとEgressの両方を管理する統合データプレーンによって、コンテナトラフィック管理に向けた安全なサービス管理ソリューションを提供します。Kubernetes環境におけるインテリジェントなトラフィック管理を可能にするプロダクショングレードの機能により、シンプルなトラフィック管理を実現します。
軽量でシームレスな設計になっており、小規模なシステムから安全にスケールが求められるエンタープライズグレードのシステムまで、マイクロサービスの計画におけるあらゆる段階に応じたスケーリングが可能です。
そのほか詳細は、https://www.nginx.co.jp/products/nginx-service-mesh/をご覧ください。

オープンソース版のNGINXとNGINX Plusの違い
オープンソース版のNGINXとNGINX Plusの機能については、様々な違いがあります。

ここでは、主要なものをピックアップして説明します。
ロードバランサ機能
NGINXは、ロードバランサとして動作させることができます。ユーザから通信を受け、背後のサーバ郡に通信を振り分けます。NGINXでは、これらの背後のサーバ郡をアップストリームサーバと呼びます。NGINXでは、負荷分散方式として、ラウンドロビン、最小コネクション、IPハッシュなどを選択できますが、NGINX Plusではこれに加えて、アップストリームサーバの最小コネクションと最小レスポンスタイムの情報を元に振り分けを行うLeast Timeという方式を利用できます。Least Timeを使用すると、振り分け処理時にアップストリームサーバの性能が考慮されるようになりますので、サーバによって性能のばらつきがある場合でも、負荷を均等に保つことができます。以下、この他のロードバランサ機能でのオープンソース版のNGINXとNGINX Plusの違いを記載します。

アクティブヘルスチェック
オープンソース版のNGINXでは、アップストリームサーバに対してのヘルスチェックは、実際のサービスに使われている通信状態で判定を行うパッシブヘルスチェックのみが利用可能です。このため、アップストリームサーバがダウンした際も一定期間、リクエストが当該アップストリームサーバに渡され、サービスに影響を及ばす可能性があります。一方、NGINX Plusでは、独立したヘルスチェック通信を設定でき、この結果を元に、アップストリームサーバへの振り分け処理を行うことが可能です。これにより、アップストリームサーバの異常を早期に検出し、負荷分散先から除外することで、サービスへの影響を極小化することが可能です。
実際の設定を図7に示します。
1 upstream my_upstream {
2 zone my_upstream 64k;
3 server server1.example.com slow_start=30s;
4 server server2.example.com slow_start=30s;
5 }
6
7 server {
8 location / {
9 proxy_pass http://my_upstream;
10 health_check interval=5s uri=/test.php match=statusok;
11 }
12 }
13
14 match statusok {
15 status 200;
16 header Content-Type = text/html;
17 body ~ "Server[0-9]+ is alive";
18 }
図7 アクティブヘルスチェックの設定例
1行目からのアップストリームグループ「my_upstream
」の定義では、zoneディレクティブで、ワーカープロセスが構成情報を保持するためのメモリ空間を定義します(2行目)。この設定は、アクティブヘルスチェックの設定を行うために必須の設定となります。また、3行目と4行目では、slow_start
ディレクティブを使い、指定サーバが利用可能となった場合にトラフィックが偏らないように指定時間をかけて重み付けを通常の状態まで戻していくように設定しています。こちらの設定も、NGINX Plusでのみ可能です。
8行目からのlocationディレクティブ内で、health_check
ディレクティブを定義します(10行目)。この例では、アップストリームグループ「my_upstream
」に対して、5秒ごとに/test.php
宛のヘルスチェックパケットを送出します。match
パラメータでは、後述するヘルスチェックの応答パケットが満たすべき条件を定義した設定名「statusok
」を指定します。
14行目からのmatch
ディレクティブでは、ヘルスチェックの応答パケットが満たすべき条件を定義します。図6の例では、 レスポンスコードが200
であり、コンテンツヘッダにContent-Type = text/html
が含まれ、ボディに正規表現で指定した文字列が含まれることが条件となります。
セッション維持(セッションパーシステンス)
負荷分散先のアップストリームサーバで提供されているアプリケーションがステートフルであった場合、同一のクライアントからのリクエストは同じアップストリームサーバに振り分ける必要があります。このような要件を実現するロードバランサの仕組みは、セッションパーシステンスと呼ばれます。NGINX Plusでは、Cookie を利用したSticky cookie
, Sticky route
, Sticky learn
という3つのセッションパーシステンス方法が提供されています。
Sticky cookie
は、NGINX Plus自身がセッション維持用のCookie
を生成してアップストリームサーバからの応答に挿入します。Sticky cookie
の設定例を、図8に示します。
1 upstream my_upstream {
2 server server1.example.com;
3 server server2.example.com;
4
5 sticky cookie srv_id expires=1h;
6 }
図8 Sticky cookieの設定例
図8の例では、「srv_id
」がNGINX Plusが生成するCookie名で、有効期限を1時間に設定しています。この設定より、最初のリクエストから1時間、同一クライアントからのリクエストは同じアップストリームサーバへ振り分けられます。
Sticky route
では、クライアントからの最初のリクエストを、アップストリームサーバグループの指定で設定されたroute
情報に紐付けます。以降のリクエストは、CookieやURL中に指定されているパラメータ情報をもとに、アップストリームサーバに振り分けを行います。設定例を図9に示します。
1 map $cookie_jsessionid $route_cookie {
2 ~.+\.(?P<route>\w+)$ $route;
3 }
4
5 map $request_uri $route_uri {
6 ~jsessionid=.+\.(?P<route>\w+)$ $route;
7 }
8
9 upstream backend {
10 server backend1.example.com route=a;
11 server backend2.example.com route=b;
12
13 sticky route $route_cookie $route_uri;
14 }
図 9 Sticky routeの設定例
図9の例では、Cookie「JSESSIONID」の値に、ピリオド(.)で区切って末尾に設定されている値があれば、それをパラメータとして採用します。当該Cookieの値がない場合は、URLのクエリ文字列中に「jsessionid
」で指定されている値のピリオド(.)で区切って末尾に設定されている値をパラメータとして採用します。採用したパラメータをもとに、最初のリクエストと同じroute
情報が指定されているアップストリームサーバに振り分けを行います。
Sticky learn
ではアップストリームサーバが生成した Cookieの値を学習し、セッション維持に使用します。設定例を図10に示します。
1 upstream backend {
2 server backend1.example.com;
3 server backend2.example.com;
4 sticky learn
5 create=$upstream_cookie_examplecookie
6 lookup=$cookie_examplecookie
7 zone=client_sessions:1m
8 timeout=1h;
9 }
図10 Sticky Leanの設定例
図10の例では、アップストリームサーバからの応答に含まれるCookie「EXAMPLECOOKIE
」の値を学習し(5行目)、クライアントからのリクエストに含まれる同じくCookie「EXAMPLECOOKIE
」の値を参照し(6行目)、振り分け先のアップストリームサーバを決定します。この方式は、セッション情報をzone
と呼ばれるメモリ空間に保存します(7行目)。このため、後述のステート共有の設定を追加することで、複数のノード間にまたがってセッション情報を共有することが可能です。
DNSサービス・ディスカバリ 統合
アプリケーションサービスを構成するアップストリームサーバのIPアドレスが変更されたり、あるいはアップストリームサーバの数が増減しうる環境では、それらの変更をロードバランサが検出し動作を適応させる必要があります。NGINX Plusでは、アップストリームサーバの指定をupstream
ディレクティブ内で、DNS名を使って行うことができますので、NGINX Plusが参照するDNSレコードを調整することで、このような要件に対応することが可能です。
まずは、AレコードをDNS名として使用する例を図11に示します。
1 resolver 10.0.0.2 valid=10s;
2
3 upstream backends {
4 zone backends 64k;
5 server backends.example.com:8080 resolve;
6 }
7
8 server {
9 location / {
10 proxy_pass http://backends;
11 }
12 }
図11 Aレコードを使用する設定例
この例では、10秒ごとに指定のDNSサーバにserver
ディレクティブで指定したDNS名「backends.example.com
」(5行目)の問い合わせを、1行目でresolver
に指定したDNSサーバに対して行い、応答で得たIPアドレスをアップストリームサーバとして扱います。ポイントは、server
ディレクティブの行末の「resolve
」パラメータです。このパラメータが、NGINX Plusでの使用可能なもので、DNS名に対応するIPアドレスの変更を監視する動作となります。オープンソース版のNGINXでも、server
ディレクティブでDNS名を指定することはできますが、プロセス起動時に名前解決を行った結果を、次回の設定の再読み込みまでキャッシュし続けてしまう等の制約があります。
また、NGINX Plusでは、DNSのSRV レコードを利用することもできます。DNSのSRVレコードでは、各サーバの優先度の設定や重み付けを行えます。また、サーバごとでサービスのリスニングポートを指定することができますので、先の例よりも柔軟にアップストリームサーバを構成することができます。
設定例を図12に示します。
1 resolver 10.0.0.2 valid=10s;
2
3 upstream backends {
4 zone backends 64k;
5 server backends.example.com service=_http._tcp resolve;
6 }
7
8 server {
9 location / {
10 proxy_pass http://backends;
11 }
12 }
図12 SRVレコードを利用する設定例
この例では、5行目のserver
パラメータで指定したDNS名「backends.example.com
」(10行目)のSRVレコードの問い合わせを、1行目でresolver
に指定したDNSサーバに対して行い、応答で得た情報(サーバの優先度の設定や重み付け、リスニングポートなど)をもとにアップストリームサーバとして構成します。
その他、DNSを用いたアップストリームサーバの構成例については、ブログ「Using DNS for Service Discovery with NGINX and NGINX Plus(https://www.nginx.com/blog/dns-service-discovery-nginx-plus/)」で詳細に解説されていますので、参照ください。
コンテンツ キャッシュ
NGINXは、コンテンツキャッシュサーバとしても動作させることができます。NGINXが動作しているローカルホストや外部のオリジンサーバのコンテンツをキャッシュし、レスポンスの高速化やオリジンサーバの負荷軽減が実現できます。

キャッシュ・パージ機能
オープンソース版のNGINX では、キャッシュを削除する仕組みが標準では提供されておらず、これを実現するためには、サードパーティモジュールを組み込む必要があります。NGINX Plusでは任意のタイミングでこのキャッシュエントリをパージする機能が標準で提供されています。この機能を利用し、キャッシュされているコンテンツを差し替えたい場合や、キャッシュ自体を無効にしたい場合に、即座に対応することができます。
設定例を図14に示します。図14 の例では、80番ポートでユーザからのリクエストをリスングして、同一ホストの8002番で動作するwebサーバからのコンテンツをキャッシュしています。
1 http {
2 ...
3 proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;
4
5 map $request_method $purge_method {
6 PURGE 1;
7 default 0;
8 }
9
10 server {
11 listen 80;
12 server_name www.example.com;
13
14 location / {
15 proxy_pass https://localhost:8002;
16 proxy_cache mycache;
17 proxy_cache_purge $purge_method;
18 }
19 }
20
21 geo $purge_allowed {
22 default 0;
23 10.0.0.1 1;
24 192.168.0.0/24 1;
25 }
26
27 map $request_method $purge_method {
28 PURGE $purge_allowed;
29 default 0;
30 }
31 }
図14 コンテンツキャッシュのパージ設定例
17行目のproxy_cache_purge
ディレクティブで、キャッシュパージ要求と見なす条件を定義しています。この例では、$purge_method
変数を条件とし、値が空でなく、また「0」でない場合に、キャッシュキーに対応するキャッシュエントリをパージします。5行目〜6行目では、リクエストメソッドがPURGE
だった場合に、$purge_method
変数の値が1になるように設定されています。
さらに、PURGE
リクエストの送信元制限を行うため、geo
モジュールを使用して、指定したIPアドレス(10.0.0.1
もしくは192.168.0.0/24
)に送信元IPアドレスが合致した場合のみ、$purge_method
変数の値が1になるよう設定されています(21行目〜25行目)。
上記の設定をNGINX Plusで行った状態で、下記の例のように、指定したIPアドレスから、PURGE
メソッドでアクセスすると、キャッシュエントリをパージすることできます。
$ curl -X PURGE -D – "http://www.example.com/*"
JWT 認証
NGINX Plusならではのセキュリティ制御関連の機能としては、JWT(JSON Web Token)の検証機能が挙げられます。この機能と他のリバースプロキシ機能と組み合わせることで、APIゲートウェイとしてNGINX Plusを使用してクライアントを認証できます。
JWT認証の詳細については、こちらのブログ「Authenticating API Clients with JWT and NGINX Plus(https://www.nginx.com/blog/authenticating-api-clients-jwt-nginx-plus/)」で解説されていますので、参照ください。
監視
オープンソース版のNGINXでは、監視用のメトリクスとして、合計リクエスト数や各種接続数(許可された接続数、処理された接続数、アクティブな接続数)などの情報を、オプションモジュールの「ngx_http_stub_status_module
」経由で取得することが可能です。一方、NGINX Plusでは、これらに加え、以下のようなメトリクスを、後述するNGINX Plus APIから取得することができます。
- HTTPステータスコードごとの応答数(4xx,5xx等)
- アップストリームサーバごとの統計
- キャッシュ機能の統計(サイズ、キャッシュヒット数、キャッシュミス数)
- SSLの統計(ハンドシェイクの成功数、失敗数)
冗長化構成(HA)
NGINX Plusがサポートする高可用性(HA)を実現する冗長化構成について、オンプレミスの場合とパブリッククラウド環境の場合の2通りを解説します。また、冗長化構成と併用できる「設定の同期」と「ステート共有」の二つの機能についても紹介します。
オンプレミスの場合
NGINX Plus では、keepalived
をベースにしたactive-passive
構成とactive-active
構成をサポートします。NGINX Plus のリポジトリで提供されているnginx-ha-keepalived
パッケージを追加インストールし、nginx-ha-setup
スクリプトを実行することで設定することが可能です。keepalived
が提供するVRRP機構で提供されるVIPをサービスのリスニングIPとして利用します。詳細はドキュメント「https://docs.nginx.com/nginx/admin-guide/high-availability/ha-keepalived/」を参照ください。

パブリッククラウド環境の場合
多くのパブリッククラウド環境ではVRRPの使用ができないため、オンプレミスと同じ冗長化構成をとることができません。そうした環境では、他の冗長化構成を採用する必要があります。ここでは、AWS環境を例として、利用可能な冗長構成について紹介します。
AWS上では、以下の3つのパターンの冗長構成をとることが可能です。
■Elastic IP Addressesを利用したactive-passive構成
OS(Linuxディストリビューション)が提供するkeepalived
を利用します。これに、GitHub「https://github.com/nginxinc/aws-ha-elastic-ip」で提供されている2つのスクリプト(nginx-ha-check
, nginx-ha-notify
)を組み合わせます。AWS環境では、サービスのリスニングIPとして、Elastic IP Addressを使用します。active
ノードの障害時には、keepalived
が、nginx-ha-notify
スクリプトをキックして、Elastic IP Addressをpassive
ノードに付け替えることによって、フェイルオーバーを実現します。

■AWS Network Load Balancerを利用したactive-active構成
AWSが提供するL4ロードバランサーであるAWS Network Load Balancerを前段に配置し、NGINX Plusノードをターゲットグループとして登録します。ユーザからのリクエストを、AWS Network Load Balancerが受け付け、背後のNGINX PlusにL4レベルで振り分けます。これにより、active-active
構成を実現することができます。詳細はドキュメント「https://docs.nginx.com/nginx/deployment-guides/amazon-web-services/high-availability-network-load-balancer/」を参照ください。

■グローバルロードバランサを利用した冗長化構成
グローバルロードバランサを利用することで、active-active
構成あるいはactive-standby
構成を実現することができます。AWS環境ですと、グローバルロードバランサとして、Route53を使うケースが多いと思います。NGINX Plusノードに、それぞれElastic IP Addressを割り当て、そのIPアドレスをRoute53側で、単一のDNS名に割り当て、DNSフェイルオーバーを構成することで、冗長化を実現できます。詳細はドキュメント「https://docs.nginx.com/nginx/deployment-guides/amazon-web-services/route-53-global-server-load-balancing/」を参照ください。

設定の同期
NGINX Plusでは、冗長構成のクラスタノード間での設定同期の仕組みが標準で提供されています。クラスタ内で一つのノードをマスタノードとして設定し、残りのノードをPeerノードとして設定します。マスタノードの設定が、Peerノードにrsyncで配布され、プロセスのリロードがssh経由で行われる仕組みです。(図19) この機能を利用することで、設定の均一化や、ノード追加時の設定の簡略化を簡単に実現できます。

以下、OSがCentOSの場合の設定手順を記載します。
1.マスタノード上に、nginx-sync パッケージをインストールします。
$sudo yum install nginx-sync
2.マスタノード上でpeerノードへのssh用の鍵を生成します。
$ sudo ssh-keygen -t rsa -b 2048
$ sudo cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc ... aRsL root@node1
3.peerノード上で、マスタノードからのsshアクセスを許可します。
下記の192.168.1.2は、マスタノードのIPアドレスに読み替えてください。
$ sudo mkdir /root/.ssh
$ sudo echo 'from="192.168.1.2" ssh-rsa AAAAB3NzaC1yc ... aRsL root@node1 ' >> /root/.ssh/authorized_keys
以下を、「/etc/ssh/ sshd_config」ファイルに追加します。
PermitRootLogin without-password
sshdをリロードします。
$ sudo systemctl reload sshd
4.マスタノード上で、設定ファイル、「/etc/nginx-sync.conf」 を作成します。図19に設定例を示します。
1 NODES="node2.example.com node3.example.com node4.example.com"
2 CONFPATHS="/etc/nginx/nginx.conf /etc/nginx/conf.d"
3 EXCLUDE="default.conf"
図20 nginx-sync.confの設定例
以下、設定項目の内容です。
1行目NODES:
peerノードを、スペースまたは改行区切りで指定します
2行目CONFPATHS:
同期する設定ファイルまたはディレクトリを、スペースまたは改行区切りで指定します
3行目EXCLUDE:
CONFPATHSで指定したディレクトリの内のファイルで同期から除外するファイルをスペースまたは改行区切りで指定します
この他、指定可能な設定項目は、ドキュメント「https://docs.nginx.com/nginx/admin-guide/high-availability/configuration-sharing/」を参照ください。
5.設定の同期は以下のコマンドで可能です
ヘルプコマンド
$ nginx-sync.sh -h
指定したpeerノードとの設定の比較
$ nginx-sync.sh -c node2.example.com
全てのpeerノードとの設定の比較
$ nginx-sync.sh -C
peerノードと設定を同期し、NGINXプロセスをリロードする
$ nginx-sync.sh
ステート共有:スティッキーセッション維持、レート制限、キーバリューストア
NGINX/NGINX Plusでは、リクエスト処理に利用している各種ステート情報を、各ノードのメモリ空間で管理しています。各ノードが固有の情報のみ保持している場合、リクエストを受信したノードによって処理が変わってしまうという問題が発生します。NGINX Plusでは、クラスタ内のノード間でステート情報を保持しているメモリの中身を同期することが可能です。このため、クラスタ内のどのノードでリクエストを受信しても、共有しているステート情報を元に同じ処理を行うことができます。具体的には、スティッキーセッションパーシステンス(Sticky learn)の情報や、レート制限(limit_req
)の情報、キーバリュストアの内容を、クラスタ内のノード間で共有させることができます。(スティッキーセッションパーシステンスは、リリースバージョンR15以降、レート制限とキーバリューストアは、リリースバージョンR16以降で共有可能です。)
前述の設定の同期では、クラスタ内でマスタノードを決定し、マスタノードの設定内容を他のpeer
ノードに配布するという構成でしたが、ステート共有ではマスターノードという概念はありません。クラスタ内のノードは同等で、フルメッシュ型で通信し、情報を共有します。
設定の詳細は、下記ドキュメント
「https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/」
を参照ください。
プログラマビリティ
プログラマビリティに関連するNGINX Plusの機能については、「NGINX PlusAPI」と「キーバリューストア」の二つを解説します。
NGINX Plus API
NGINX Plus リリースバージョンR13以降では、NGINX plus APIと呼ばれるRESTful APIが提供されています。このAPIを利用することで、設定ファイルの編集やプロセスのリロードをすることなく、アップストーリムサーバの設定などを行うことが可能です。設定例を図21に示します。
1 http {
2 # ...
3 # Configuration of the server group
4 upstream appservers {
5 # 共有メモリにサーバグループ構成を保存するように、ゾーンの設定を行う
6 zone appservers 64k;
7
8 server appserv1.example.com weight=5;
9 server appserv2.example.com:8080 fail_timeout=5s;
10 server reserve1.example.com:8080 backup;
11 server reserve2.example.com:8080 backup;
12 }
13 server {
14 # Location that proxies requests to the upstream group
15 location / {
16 proxy_pass http://appservers;
17 health_check;
18 }
19
20 # Location for dynamic configuration requests
21 location /api {
22 # GET以外のメソッドをBasic認証で制限
23 limit_except GET {
24 auth_basic "NGINX Plus API";
25 auth_basic_user_file /etc/nginx/.htpasswd;
26 }
27 # APIを書き込みモードで動作させる
28 api write=on;
29 # アクセス元をローカルホストのみに制限
30 allow 127.0.0.1;
31 deny all;
32 }
33 }
34 }
図21 NGINX Plus APIの設定例
上記の設定を行った後、以下のコマンドをローカルから実行すると、アップスストリームグループであるappservers
に、新しいサーバ” 172.16.0.70
”、リスニングポート80番を追加することができます。
(下記コマンドは、一行として実行してください。また、$USER
と$PASSWORD
はベーシック認証で設定したものに読み替えてください。)
curl -u $USER:$PASSWORD -X POST -d '{"server":"172.16.0.70:80", "weight":"4", "max_conns":"0","max_fails":"0", "fail_timeout":"10s", "slow_start":"10s", "backup":"true", "down":"true"}' -s 'http://127.0.0.1/api/6/http/upstreams/appservers/servers'
その他、NGINX plus APIのエンドポイントやメソッドの詳細は、以下のドキュメント「https://nginx.org/en/docs/http/ngx_http_api_module.html」記載されています。
また、NGINX plus API に組み込まれているSwagger UIを、URL「http://_NGINX-host_/swagger-ui/」から確認することもできます。(図22)

図21の例では、NGINX Plusのプロセスが設定ファイルの再読み込みを行ったタイミングで、API経由で行った変更は破棄されます。API経由での設定を永続化するには、アップストリームサーバの定義をstateファイルで管理するように設定を変更します。(図23)
1 http {
2 # ...
3 # Configuration of the server group
4 upstream appservers {
5 # 共有メモリにサーバグループ構成を保存するように、ゾーンの設定を行う
6 zone appservers 64k;
7 state /var/lib/nginx/state/appservers.conf;
8 # server appserv1.example.com weight=5;
9 # server appserv2.example.com:8080 fail_timeout=5s;
10 # server reserve1.example.com:8080 backup;
11 # server reserve2.example.com:8080 backup;
12 }
13 }
図23 stateファイルの設定例
図23では、8行目から11行目でアップストリームサーバの設定をコメントアウトしています。一方、7行目で、state
ファイルを指定しています。これらの設定後、API経由でアップストリームサーバを追加すると、state
ファイルに記録され、設定ファイルの再読み込み後も変更内容が維持されます。なお、state
ファイルの直接編集はサポートされていないため、必ず、API経由で設定を行う必要があります。
キーバリューストア
NGINX Plus リリースバージョンR13以降で、任意のキーと値のペアをAPI経由で、メモリ上に保存し、NGINXのプロセスに変数として処理させることで、トラフィック処理等に利用できます。前述のとおり、リリースバージョンR16以降では、クラスタ内のノード間で、このキーバリューストアを同期することができます。キーバリューストアを利用し、送信元IPアドレスやCookieの情報などを保存し、動的IPブラックリストによるアクセス制限や、動的帯域制限を実現することが可能となります。
簡単な設定例を図24に示します。
$remote_address
というキーと、$black_list
という値を持つキーバリューストアを定義しています(4行目)。80
番ポートでリスニングしているサーバは、送信元IPアドレスが、$remote_address
に合致する場合、$black_list
の値を評価し、値が0
である場合、403
エラーを返します。(10行目〜12行目)
1 http {
2 # キーバリューストアの定義
3 keyval_zone zone=blacklist:1M state=/tmp/blacklist.json;
4 keyval $remote_addr $black_list zone=blacklist;
5
6 server {
7 listen 80;
8 location / {
9 root /usr/share/nginx/html;
10 if ($black_list = 0) {
11 return 403;
12 }
13 }
14
15 location /api {
16 # GET以外のメソッドをBasic認証で制限
17 limit_except GET {
18 auth_basic "NGINX Plus API";
19 auth_basic_user_file /etc/nginx/.htpasswd;
20 }
21 # APIを書き込みモードで動作させる
22 api write=on;
23 #アクセス元をローカルホストのみに制限
24 allow 127.0.0.1;
25 deny all;
26 }
27 }
28 }
図24 キーバリューストアの設定例
上記の設定後、以下のコマンドで、API経由で、キーと値を設定します。
($USER
と$PASSWORD
はベーシック認証で設定したものに読み替えてください。)
curl -u $USER:$PASSWORD -X POST -d '{"192.168.1.10":"0"}' http://localhost/api/1/http/keyvals/blacklist
上記コマンドの実行後に、192.168.1.10
からアクセスすると、403
エラーが返るようになります。
その他、キーバリューストアの詳細については、ドキュメント「https://nginx.org/en/docs/http/ngx_http_keyval_module.html」を参照ください。また、キーバリューストアの活用例については以下のブログで紹介されていますので、参照ください。
動的帯域制御での活用例
「https://www.nginx.com/blog/dynamic-bandwidth-limits-nginx-plus-key-value-store/」
動的IPブラックリストでの活用例
「https://www.nginx.com/blog/dynamic-ip-blacklisting-with-nginx-plus-and-fail2ban/」
A/Bテストでの活用例
「https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/」