無停止で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`