ダイナミックモジュールを使用している場合、NGINXまたはNGINX Plusの新しいリリースへのアップグレード中に、次のようなエラーが表示されることがあります。
Setting up nginx-plus (1.11.10-1~xenial) ...
nginx: [emerg] module "/etc/nginx/modules/ngx_http_geoip_module.so" version 1011005 instead of 1011006 in /etc/nginx/nginx.conf:7
nginx: configuration file /etc/nginx/nginx.conf test failed
invoke-rc.d: initscript nginx, action "upgrade" failed.最も可能性の高い原因は、指定された動的モジュール(.soファイル)をアップグレードしていないことです:
- NGINX Open Sourceを実行している場合、動的モジュールはアップグレード先のバージョンに合わせてコンパイルする必要があります。
- NGINX Plusを実行している場合、動的モジュールは、アップグレード先のNGINX Plusリリースに対応するNGINX Open Sourceバージョンに対してコンパイルする必要があります。
以降は簡潔にするため、NGINX Plusのみを取り上げます。
慌てないでください!
このエラーメッセージは、NGINX Plusサーバーが停止していることを示すものではありませんので、ご安心ください。NGINX Plusはシームレスにアップグレードされるため、アップグレードに失敗しても旧バージョンは引き続き稼働します。ただし、アップグレードは完了しておらず、システムは不整合な状態にあります。
- メモリ内のNGINX Plusプロセスは旧バージョンで実行されています
- ディスク上のNGINX Plus関連ファイルはすべて新しいバージョンに対応しています
- エラーメッセージに記載されている動的モジュールは、旧バージョン向けにコンパイルされています
手動でnginxを再起動したり、システムを再起動したりしないでください。新しいNGINX Plusリリースと同期していない動的モジュールがある場合、新しいNGINX Plusプロセスを起動できないため、これらの操作を行うとダウンタイムが発生します。
このエラーメッセージは、アップグレード中に最初に検出された互換性のないモジュールについてのみ示すものです。そのため、設定内のすべての「load_module」ディレクティブを特定し、各モジュールが適切なNGINXバージョン向けにコンパイルされていることを確認することが重要です。すべての「NGINXが開発した動的モジュールおよび認定済みのサードパーティ製動的モジュール」について、各NGINX Plusリリースに対応する正しいバージョンが提供されているため、再コンパイルが必要なのは認定されていないモジュールのみです。この記事では、アップグレードプロセスを安全に完了する方法について説明します。
何が問題だったのか?
NGINX 1.11.5とNGINX Plus R11では、NGINX Open Source向けにダイナミックモジュールをコンパイルし、NGINX Plusにロードできるようになりました。このバイナリ互換性を確保するには、モジュールとNGINX Plusで同じベースのオープンソースバージョンを使用する必要があります。対応するNGINX Open Sourceバージョン向けにビルドされたダイナミックモジュールを先にインストールせずにNGINX Plusをアップグレードすると、バージョンの不一致により失敗します。
ダイナミックモジュールがサードパーティベンダーから提供されたものである場合は、そのベンダーに連絡し、アップグレード先のNGINX Plusリリースで使用されているNGINXバージョンに対応した新しいバージョンを入手する必要があります。ダイナミックモジュールをソースからコンパイルしており、そのソースにアクセスできる場合は、引き続きお読みください。
復旧への道のり
ステップ0:ビルド環境を準備する
動的モジュールは、ここで「ビルド環境」と呼ぶ別のシステムでコンパイルすることを強く推奨します。これにより、動的モジュールを使用してNGINX Plusを実行するシステム(ここでは「本番環境」と呼びます)のリスクと複雑さを最小限に抑えられます。ビルド環境では、本番環境と同じオペレーティングシステムおよびバージョンを使用する必要があります。さらに、以下のコンポーネントをインストールする必要があります。
- UnZipユーティリティ
- コンパイラおよびmakeユーティリティ
- Perl互換正規表現ライブラリ(開発用ファイル)
- Zlib圧縮ライブラリ(開発用ファイル)
ビルド環境にこれらの前提条件がインストールされていることを確認するには、次のコマンドを実行します。
- Ubuntu/Debianの場合:
buildenv$ sudo apt-get install unzip gcc make libpcre3-dev zlib1g-dev- CentOS/RHEL/Oracle Linuxの場合:
buildenv$ sudo yum install unzip gcc make pcre-devel zlib-develステップ1:NGINX Open Sourceを入手
- 本番環境で次のコマンドを実行し、稼働中のNGINX Plusリリースに対応するNGINX Open Sourceのバージョンを確認します。この出力では、NGINX Plus R12に対応するNGINX 1.11.10がオレンジ色で強調表示されています。
production$ nginx -vnginx version: nginx/1.11.10 (nginx-plus-r12)- ビルド環境で、該当するバージョンのNGINX Open Sourceのソースをダウンロードします。
build-env$ wget -qO - http://nginx.org/download/nginx-1.11.10.tar.gz | tar zxfv -ステップ2:動的モジュールのソースを取得
ダイナミックモジュールのソースコードを任意のビルドディレクトリにコピーします。ここでは、NGINXのサンプル「hello world」モジュールをGitHubリポジトリからコピーします。
buildenv$ git clone https://github.com/perusio/nginx-hello-world-module.git
Cloning into 'nginx-hello-world-module'...ステップ3:動的モジュールをコンパイル
- ダイナミックモジュールをコンパイルするには、まずNGINXの「
configure」スクリプトを「--with-compat」引数を指定して実行し、ダイナミックモジュールにNGINX Plusとのバイナリ互換性を持たせます。次に「makemodules」を実行して、モジュールのみをコンパイルします。
buildenv$ cd nginx-1.11.10/buildenv$ ./configure --with-compat --add-dynamic-module=../nginx-hello-world-module
buildenv$ make modules- ビルドプロセスによって動的モジュールが .soファイルとしてobjsサブディレクトリに作成されていることを確認します。
buildenv$ ls objs/*.soobjs/ngx_http_hello_world.so- モジュールファイルをコピーし、ファイル名にNGINX Open Sourceのバージョンを含めます。これにより、本番環境で複数バージョンの動的モジュールを管理しやすくなります。
buildenv$ cp objs/ngx_http_hello_world.so ./ngx_http_hello_world_1.11.10.soステップ4:ダイナミックモジュールを本番環境にコピーする
ファイル名にNGINX Open Sourceのバージョンを含めて動的モジュールを作成したため、運用に影響を与えることなく本番環境に安全にコピーできます。
buildenv$ scp ./ngx_http_hello_world_1.11.10.so production:/etc/nginx/modulesステップ5:動的モジュールを切り替える
本番環境で、現在のファイルを新しい「.so」ファイルに置き換えます。この時点で置き換えても問題ありません。動的モジュールがメモリに読み込まれるのは、「nginx」の再起動時または設定の再読み込み時のみであるためです。
production$ cd /etc/nginx/modulesproduction$ cp ngx_http_hello_world.so ngx_http_hello_world_ROLLBACK.so
production$ ln -fs ngx_http_hello_world_1.11.10.so ngx_http_hello_world.so
production$ ls -gG
-rw-r--r-- 1 243576 Jan 31 16:18 ngx_http_hello_world_1.11.10.so
-rw-r--r-- 1 243576 Oct 20 10:40 ngx_http_hello_world_ROLLBACK.so
lrwxrwxrwx 1 24 Jan 31 16:26 ngx_http_hello_world.so -> ngx_http_hello_world_1.11.10.soステップ6:NGINX Plusのアップグレードを完了する
- 次のコマンドを実行して、モジュールのバージョンが正しいこと、およびNGINX Plusでアップグレードプロセスを完了する準備が整っていることを確認します。
production$ nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful- アップグレードプロセスを完了し、NGINX Plusで新しいリリースと動的モジュールが使用されていることを確認します。
production$ service nginx upgradeStarting new master nginx: [ OK ]
Graceful shutdown of old nginx: [ OK ]アップグレードの失敗を防ぐ
次回NGINX Plusをアップグレードする際は、アップグレード前にこちらの手順に従ってください。アップグレードプロセスの開始時に更新済みの動的モジュールが利用可能な状態となるため、時間を節約し、エラーを回避できます。
著者について

関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります