More than 1 year has passed since last update.

無停止でnginxのupgradeを行う手順

無停止でnginxを新しいバージョンへアップグレードする手順です。

だいたいここに書いてあります。
http://nginx.org/en/docs/control.html#upgrade

作業内容

nginx 1.7.3 -> 1.9.9 へアップグレード

環境

  • OS
    CentOS 6.6
  • nginx1.7.3が起動している
    nginx.confなどがすでに存在
    nginx1.7.3 は ソースからインストールされている(/usr/local/nginx/以下)
  • php-fpm等は起動していない

作業はすべてrootユーザで実施します

kill/make install等でsudoが必要な場合があります。
rootユーザで実施するためその辺りは考慮していません。

nginx 1.9.9 のバイナリの用意

configureオプションは適当に。

# wget http://nginx.org/download/nginx-1.9.9.tar.gz
# tar zxf nginx-1.9.9.tar.gz
# cd nginx-1.9.9 ; pwd
# ./configure
# make
# make install

この状態では、まだアップグレードされていません。

# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.7.3

この状態でmake upgradeすると自動で置き換わります。
すごいですね。

アップグレード手順

最初に手順だけをあげると下記となります。

# /usr/local/nginx/sbin/nginx -t
# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# /usr/local/nginx/sbin/nginx -V

挙動を見ていきます

  • アップグレード前の状態
    masterプロセスのpidは4388です。
# ps auxww | grep 'nginx'
root      4388  0.1  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4389  0.0  0.1 106228  2836 ?        S    02:29   0:00 nginx: worker process
nginx     4390  0.0  0.1 106228  2904 ?        S    02:29   0:00 nginx: worker process
nginx     4391  0.0  0.1 106228  2884 ?        S    02:29   0:00 nginx: worker process
root      4397  0.0  0.0   6388   680 pts/2    S+   02:29   0:00 grep --color=auto nginx
#

1.config test

# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
#

2.USR2シグナル送信

  • 新しいバイナリのnginxプロセスが起動
  • アップグレード前nginxのpidファイルがnginx.pid.oldbinとなる
  • アップグレード後のnginxが処理を開始
# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
# ps auxwwf | grep 'ngin[x]'
root      4388  0.0  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4389  0.0  0.1 106228  2836 ?        S    02:29   0:00  \_ nginx: worker process
nginx     4390  0.0  0.1 106228  2904 ?        S    02:29   0:00  \_ nginx: worker process
nginx     4391  0.0  0.1 106228  2884 ?        S    02:29   0:00  \_ nginx: worker process
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00  \_ nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00      \_ nginx: worker process                                        
#
#
# ls -la /usr/local/nginx/logs/nginx.pid*
-rw-r--r-- 1 root  root         5 Feb  4 02:31 nginx.pid
-rw-r--r-- 1 root  root         5 Feb  4 02:29 nginx.pid.oldbin
#

アップグレード後nginxのmasterプロセスが起動しています。pid4464のものになります。
アップグレード前nginxのmasterプロセス4388の方も起動しているのが分かります。

USR2を送ると

  • アップグレード後masterプロセスとアップグレード前masterプロセスが混在する事に
  • アップグレード後nginxのpid -> nginx.pid
  • アップグレード前nginxのpid -> nginx.pid.oldbin

以降、nginx.pid.oldbinへシグナルを送信することでアップグレード前nginxを、
nginx.pidへシグナルを送る事でアップグレード後nginxを操作できます。

3.WINCHシグナルの送信

  • アップグレード前masterプロセスがworkerプロセスを終了し、アップグレード後のnginxのみで処理を開始
# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
#
# ps auxwwf | grep 'ngin[x]'
root      4388  0.0  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00  \_ nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00      \_ nginx: worker process                                        
#

アップグレード前masterプロセスであるpid4388が存在し、workerプロセスが無くなっています。

WINCHシグナルを送ると

アップグレード前masterプロセスが管理下にあるworkerプロセスを終了させます。
この状態では、すべてのリクエストを新しいnginxが処理することになります。
この状態で、Web閲覧が不可能等である場合は切り戻す事になります。
切り戻し手順は後述します。

4.QUITシグナルをアップグレード前nginxに送信

  • アップグレード前nginxのマスタープロセスが完全に終了
# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# ps auxwwf | grep 'ngin[x]'
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00  \_ nginx: worker process
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00  \_ nginx: worker process
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00  \_ nginx: worker process
#
# ls -l /usr/local/nginx/logs/nginx.pid
-rw-r--r-- 1 root root 5 Feb  4 02:31 /usr/local/nginx/logs/nginx.pid
#
#
# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.9.9
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
#

アップグレード前のmasterプロセスが完全に終了しています。
これでアップグレードは完了となります。

切り戻し手段

途中で問題が発生した場合は切り戻す事になります。方法は2つです。

  • アップグレード前masterプロセスへHUPシグナルを送信
    アップグレード後masterプロセスを終了し、アップグレード前masterプロセスがworkerプロセスを作成します。

  • アップグレード後TERMシグナルを送信
    アップグレード前masterプロセスがアップグレード後masterプロセスの終了を検知すると、workerプロセスを作成します。

# kill -s HUP `cat /usr/local/nginx/logs/nginx.pid.oldbin`
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.