[CentOS]nginxを1.9.2にしたらmuninでnginxとphp-fpmのグラフが取れなくなったときの対処


CentOS 6と7でnginxを1.9.2にアップデートした後から、muninでnginxとphp-fpmのグラフが取得できなくなったので、対処したときのメモを残します。nginxは公式サイトのyumリポジトリ(mainline)からインストールおよびアップデートしています。

アップデート前のnginxは1.9.1でした。

$ rpm -q nginx
nginx-1.9.1-1.el7.ngx.x86_64

アップデート後のnginxは1.9.2です。

$ rpm -q nginx
nginx-1.9.2-1.el7.ngx.x86_64

アップデート直後のmunin-run実行結果はこんな感じで値が取得できていません。アクセスログを見ても404でした。

$ munin-run nginx_status
total.value U
reading.value U
writing.value U
waiting.value U
127.0.0.1 - - [02/Jul/2015:08:31:26 +0900] "GET /nginx_status HTTP/1.1" 404 168 "-" "munin/2.0.25 (libwww-perl/5.833)" "-"
$ munin-run phpfpm_connections
accepted.value U
127.0.0.1 - - [02/Jul/2015:08:32:05 +0900] "GET /phpfpm_status HTTP/1.1" 404 168 "-" "libwww-perl/5.833" "-"
$ munin-run phpfpm_status
idle.value U
active.value U
total.value U
127.0.0.1 - - [02/Jul/2015:08:32:44 +0900] "GET /phpfpm_status HTTP/1.1" 404 168 "-" "libwww-perl/5.833" "-"

ただし、一部値が取得できているのもあり。

$ munin-run phpfpm_average
php_average.value 5600051
$ munin-run phpfpm_memory
ram.value 28000256
$ munin-run phpfpm_processes
php_processes.value 5

いろいろ調べているうちに、munin-runではなくcurlでURLを突ついてみたらどうなるか、切り分けてみました。

※ アップデート前

$ curl -LIs http://127.0.0.1/nginx_status
HTTP/1.1 200 OK
Server: nginx/1.9.1
Date: Thu, 02 Jul 2015 09:14:38 GMT
Content-Type: text/plain
Connection: keep-alive
$ curl -LIs http://localhost/nginx_status
HTTP/1.1 200 OK
Server: nginx/1.9.1
Date: Thu, 02 Jul 2015 09:14:54 GMT
Content-Type: text/plain
Connection: keep-alive
$ curl -LIs http://127.0.0.1/phpfpm_status
HTTP/1.1 200 OK
Server: nginx/1.9.1
Date: Thu, 02 Jul 2015 09:17:45 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.9
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
$ curl -LIs http://localhost/phpfpm_status
HTTP/1.1 200 OK
Server: nginx/1.9.1
Date: Thu, 02 Jul 2015 09:17:50 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.9
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0

アップデート後、何もしないとこうなります。

$ curl -LIs http://127.0.0.1/nginx_status
HTTP/1.1 200 OK
Server: nginx/1.9.2
Date: Thu, 02 Jul 2015 09:19:56 GMT
Content-Type: text/plain
Connection: keep-alive
$ curl -LIs http://localhost/nginx_status
HTTP/1.1 404 Not Found
Server: nginx/1.9.2
Date: Thu, 02 Jul 2015 09:19:59 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive
$ curl -LIs http://127.0.0.1/phpfpm_status
HTTP/1.1 200 OK
Server: nginx/1.9.2
Date: Thu, 02 Jul 2015 09:20:06 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.9
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
$ curl -LIs http://localhost/phpfpm_status
HTTP/1.1 404 Not Found
Server: nginx/1.9.2
Date: Thu, 02 Jul 2015 09:20:10 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive

おわかりいただけましたでしょうか。curlでアクセスするURLが127.0.0.1だとnginxはステータス200を返すのですが、localhostだと404を返すため、munin-runでも値が取得できず、muninでグラフが生成されなくなってしまうのです。

これまでは、nginxのメインのバーチャルホストのserverディレクティブに設定をしていました。

server {
    listen       80 default_server;
    server_name  www.example.com;
(略)
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
    location /phpfpm_status {
        include fastcgi_params;
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        allow 127.0.0.1;
        deny all;
    }
}

変更後はこんな感じです。

server {
    listen       80 default_server;
    server_name  www.example.com;
(略)
# /nginx_status と /phpfpm_status のlocation設定を削除
}
server {
    listen       127.0.0.1:80;
    listen       [::1]:80;
    server_name  localhost localhost.localdomain 127.0.0.1 [::1];
    location / {
        root   /home/vhosts/www.example.com/public_html;
        index  index.php index.html index.htm;
    }
    location /nginx_status {
        stub_status on;
        access_log off;
        allow ::1;
        allow 127.0.0.1;
        deny all;
    }
    location /phpfpm_status {
        include fastcgi_params;
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        allow ::1;
        allow 127.0.0.1;
        deny all;
    }
    location ~ \.php$ {
        root   /home/vhosts/www.example.com/public_html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
        client_max_body_size 256M;
        include        fastcgi_params;
    }
    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

新たにserverディレクティブを作ってあげました。ポイントは以下の通りです。

  • listenはIPv4とIPv6のアドレスを書く。
    listen       127.0.0.1:80;
    listen       [::1]:80;
  • server_name は名前とIPアドレス両方でアクセスできるように併記しておく。
    server_name  localhost localhost.localdomain 127.0.0.1 [::1];
  • locationのallow設定は自ホストからのみアクセスを許可し、その他のホストはdenyする。
        allow ::1;
        allow 127.0.0.1;
        deny all;

なお、ここでのIPv6アドレスは[]で囲わないことに注意です。

最初はIPv6のアドレスを書かずに設定していたのですが、curlで確認してみると、最初にIPv6で接続を試み、接続できなければIPv4でリトライするようでしたので、無駄なリトライを避けるためにlistenでIPv6とIPv4のアドレスを併記しています。

$ curl -vv http://localhost/nginx_status
* About to connect() to localhost port 80 (#0)
*   Trying ::1...
* 接続を拒否されました
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /nginx_status HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.9.2
< Date: Thu, 02 Jul 2015 09:27:23 GMT
< Content-Type: text/plain
< Content-Length: 97
< Connection: keep-alive
< 
Active connections: 1 
server accepts handled requests
 6 6 6 
Reading: 0 Writing: 1 Waiting: 0 
* Connection #0 to host localhost left intact

また、locationの中で「allow ::1;」を書き忘れるとこうなります。

$ curl -vv http://localhost/nginx_status
* About to connect() to localhost port 80 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 80 (#0)
> GET /nginx_status HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Server: nginx/1.9.2
< Date: Thu, 02 Jul 2015 09:33:11 GMT
< Content-Type: text/html
< Content-Length: 168
< Connection: keep-alive
< 
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.9.2</center>
</body>
</html>
* Connection #0 to host localhost left intact

というわけで、localhost専用のserverディレクティブを書いてあげると、curlでこのように綺麗なアクセスができました。

$ curl -vv http://localhost/nginx_status
* About to connect() to localhost port 80 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 80 (#0)
> GET /nginx_status HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.9.2
< Date: Thu, 02 Jul 2015 09:38:02 GMT
< Content-Type: text/plain
< Content-Length: 97
< Connection: keep-alive
< 
Active connections: 1 
server accepts handled requests
 1 1 1 
Reading: 0 Writing: 1 Waiting: 0 
* Connection #0 to host localhost left intact
$ curl -vv http://localhost/phpfpm_status
* About to connect() to localhost port 80 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 80 (#0)
> GET /phpfpm_status HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.9.2
< Date: Thu, 02 Jul 2015 09:38:10 GMT
< Content-Type: text/plain;charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/5.6.9
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Cache-Control: no-cache, no-store, must-revalidate, max-age=0
< 
pool:                 www
process manager:      dynamic
start time:           02/Jul/2015:18:26:32 +0900
start since:          698
accepted conn:        39
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       5
active processes:     1
total processes:      6
max active processes: 2
max children reached: 0
slow requests:        0
* Connection #0 to host localhost left intact

それでは肝心のmunin-runで最終確認してみましょう。

$ munin-run nginx_request
request.value 4837
$ munin-run nginx_status
total.value 2
reading.value 0
writing.value 1
waiting.value 1
$ munin-run phpfpm_average
php_average.value 101467136
$ munin-run phpfpm_connections
accepted.value 2262
$ munin-run phpfpm_memory
ram.value 811737088
$ munin-run phpfpm_processes
php_processes.value 8
$ munin-run phpfpm_status
idle.value 7
active.value 1
total.value 8

バッチリ値が取得できていますね。(∩´∀`)∩ワーイ