IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

クラウド時代のサーバー運用入門

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第4回 クラウド時代の障害対応術 (3) 初見のサーバーを覗いてみよう (濱田康貴) 2018年1月

さて、第1回、第2回目のコラムではコマンドラインからWEBサーバーの外形監視トラブル原因調査を行う方法をご紹介しました。障害対応は当然のことながら、今目の前でおきている状況に手を突っ込んで解決しなければなりません。今回は、WEBサーバーの内側からトラブルシュートを行う方法について、一例をご紹介したいと思います。本稿中、特にことわりがない場合は、RHELまたはCentOS環境を前提としています。

WEBサーバーの原理原則を知り、あるべき姿を理解しよう

今回のタイトルが「初見のサーバーを覗いてみよう」なので、障害がおきたサーバーを今から調査しなければならないのか?と引いてしまった方もいると思います。しかし、そもそものWEBサーバーの原理原則を知っていれば、恐れることはありません。特殊な例外を除き、WEBサーバーは次のように動いています。

  • httpプロトコルはTCP/80ポートで待ち受けている
  • httpsプロトコルはTCP/443ポートで待ち受けている
  • これらの待ち受けポートをバインドするプロセスこそがWEBサーバーである

まず、これが原理原則の一番根幹の部分です。1台のサーバーで複数のWEBサーバープログラムを動かすためなどの理由で、やむを得ず別のポートで待ち受けさせていたりすることもありますが、これは一旦例外としておいておきます。
ブラウザのアドレスバーに入力するURLには、httpやhttpsのポート番号を手入力するケースはほとんどないかと思います。これらのポートはWell-Knownポートといい、インターネット上に公開されるサービスやプロトコルの決まりごとの1つとしてIANA(Internet Assigned Numbers Authority) が管理しています。ですので、特殊なポートでクライアントからの接続を待ち受けているケースを除き、ブラウザに入力するURLにわざわざポート番号を含めなくてよいのです。

いっぽう、WEBサーバーとして動いているホストのほうは、Well-Knownポートに限らず、何らかのポートに着信した接続をどのアプリケーションが受け取り、よしなに処理するかを決めなければなりません。Apacheであれば、httpd.confやssl.confなどのファイルに以下のような記述があれば、Apacheが起動した際にTCP/80やTCP/443ポートで接続を待ち受けるということになります。

設定内容設定箇所備考
Listen 80主に httpd.conf
Listen 443 https主に ssl.confRHELやCentOS等でmod_sslパッケージをインストールした場合、標準でssl.confにSSL/TLSの設定を記述します

本連載の第2回目で、LinuxホストからcurlコマンドでWEBサーバーのステータスコードを確認する方法について少し触れました。もしステータスコードが取得できていなければ、

  • WEBサーバーそのものがOSごとダウンしている(電源が落ちている)
  • OSは起動しているが、WEBサーバー(Apache、Nginx等)の応答がない
  • WEBサーバーには問題ないが、ファイアウォール(iptablesやアプライアンス型ファイアウォール等)によりアクセスが遮断されている

という理由が考えられます。動的なプログラムに不具合が生じていたり、静的なファイルであってもアクセス権がないというケースは、そもそもWEBサーバーがエラーを返すケースですので、このケースには当てはまりません。これらの原因をサーバーの内部から特定するには、次の方法で行います。

WEBサーバーそのものがOSごとダウンしているケース

そもそもWEBサーバーにpingも飛ばずネットワークの到達性がないのか、何らかの理由によりOSごとダウンしているのかを切り分けます。物理サーバーであればコンソールから、クラウドやVPSであれば、クラウド事業者が用意しているVNCやシリアルコンソール、APIなどから起動状況を確認し、シャットダウンしているなら起動しましょう。

OSは起動しているが、WEBサーバーの応答がない

一般的にこうしたケースが多いのかと思いますが、一口に「WEBサーバーの応答がない」といっても、必ずしも原因は1つではありません。
まず、先ほど書きましたように、WEBサーバーはTCP/80ポート、TCP/443ポートの接続を待ち受けます。WEBサーバー上では、ssコマンドで確認してみましょう。

$ ss -lnt | egrep '(80|443)'
LISTEN     0      128                       *:80                       *:* 
LISTEN     0      128                       *:443                      *:*

コマンドの出力結果で可読性を上げるために、ssコマンドの出力結果から80番ポートと443ポートの行だけをegrepコマンドで抜き出しています。PHP-FPMをTCP/9000番ポートで待ち受けている場合は、これだけでは不十分ですので、9000番ポートもegrepコマンドに引っ掛けてみましょう。

$ ss -lnt | egrep '(80|443|9000)'
LISTEN     0      128               127.0.0.1:9000                     *:*
LISTEN     0      128                       *:80                       *:*
LISTEN     0      128                       *:443                      *:*

もしここで本来LISTENすべきポートがLISTENしていなければ、そのポートをバインドしているプロセスが起動していないことになります。

それでは、どのプロセスが80番ポート(http)を待ち受けているかをlsofコマンドで確認しましょう。注意点ですが、他のユーザーがバインドしているプロセスを見るためには、sudoコマンドをつけて実行するか、rootユーザーへ昇格してから実行しないといけません。また、「いざログイン その前に」の章でも述べているように、rootユーザーへ昇格またはsudoコマンドの実行は他ユーザーが実行しているプロセスや他ユーザーが権限を持つファイルへの影響を考慮し、慎重に実行する癖をつけましょう。

$ sudo lsof -i:80
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   6039  root    7u  IPv4  12976      0t0  TCP *:http (LISTEN)
nginx   6041 nginx    7u  IPv4  12976      0t0  TCP *:http (LISTEN)
nginx   6042 nginx    7u  IPv4  12976      0t0  TCP *:http (LISTEN)
nginx   6043 nginx    7u  IPv4  12976      0t0  TCP *:http (LISTEN)

このように、80番ポートをバインドしているプロセス(コマンド)はnginxであることがわかりました。

もしnginxコマンドが起動していなければ、上記コマンドで何も表示されませんので、psコマンドでも確認してみます。

$ ps -aef | egrep '([n]ginx|^UID)'
UID        PID  PPID  C STIME TTY          TIME CMD
nginx     6020  6019  0 Oct19 ?        00:00:06 php-fpm: pool www            
nginx     6021  6019  0 Oct19 ?        00:00:05 php-fpm: pool www            
nginx     6022  6019  0 Oct19 ?        00:00:06 php-fpm: pool www            
nginx     6023  6019  0 Oct19 ?        00:00:05 php-fpm: pool www            
nginx     6024  6019  0 Oct19 ?        00:00:06 php-fpm: pool www            
nginx    16463  6019  0 Oct19 ?        00:00:04 php-fpm: pool www            
root     22020     1  0 21:46 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    22021 22020  0 21:46 ?        00:00:00 nginx: worker process                   
nginx    22022 22020  0 21:46 ?        00:00:00 nginx: worker process                   
nginx    22023 22020  0 21:46 ?        00:00:00 nginx: worker process

上記の例では、psコマンドの出力を、egrepコマンドによりnginxを含む行か、先頭文字がUIDで始まる行でフィルタリングしています。nginxユーザーが起動しているコマンドはnginxとphp-fpmであることがわかりますので、もし全く応答がなければ、コマンド(デーモン)起動に失敗している可能性がありますので、エラーログを確認しましょう。

WEBサーバーには問題ないが、ファイアウォール(iptablesやアプライアンス型ファイアウォール等)によりアクセスが遮断されている

先ほどの例示のように、WEBサーバープログラムを実行しているホストにおいてssコマンドやpsコマンドでNginxがTCP/80を待ち受けていることが確認でき、外部ホストからWEBサーバーへpingが飛んでいるにもかかわらず、外部ホストからcurlを実行してもステータスコードが返ってこない(000である)場合、

  • 外部ファイアウォールやACL等で遮断されている
  • ロードバランサーの配下にある場合、ロードバランサーが故障しているか電源が落ちている
  • iptablesで遮断されている

といった理由が考えられます。これらはNginxやApache等のWEBサーバープログラムより下位層のプロトコルで遮断されているためにおきている障害ですので、WEBサーバーからステータスコードを返しようがない、そもそもクライアントからのリクエストをWEBサーバープログラムが受け取っていないという言い方もできます。この場合、WEBサーバープログラム側でやみくもに設定を変更したり再起動をしたりしても意味がなく、ファイアウォールやロードバランサー、あるいはiptablesの調査から着手するべきです。
WEBサーバーホストのiptables設定を確認する場合、rootユーザーで、またはsudoが実行できるユーザーで iptables コマンドか firewall-cmdコマンドで確認しましょう。

いざログイン その前に!

本稿のタイトルにも示したように、今回は「初見のサーバー」にログインします。言い換えますと、「普段の姿を知らないはじめて見るサーバー」にログインするということでもあります。お客様にサービスを提供している場合は特に、以下のことを心がけましょう。

  • ターミナルソフトのロギング機能またはscriptコマンドでログを保存する
  • 無闇に設定を弄らない
  • 設定変更を行う場合、顧客や上司にその理由と期待する結果を説明できるか自問自答する
  • 無闇にrootユーザーへ昇格またはsudoコマンドを実行しない

今回のコラムで取り上げたコマンドのほとんどは、一般ユーザーで実行可能、つまりrootユーザーへ昇格したりsudoコマンドを実行したりせずに実行できるコマンドばかりです。sudoコマンド実行時にパスワードを求められる際、このような表示を見たことがあるかと思います。

$ sudo lsof -i:443
あなたはシステム管理者から通常の講習を受けたはずです。
これは通常、以下の3点に要約されます:

#1) 他人のプライバシーを尊重すること。 #2) タイプする前に考えること。 #3) 大いなる力には大いなる責任が伴うこと。
[sudo] hamada のパスワード:

出典が不明なので引用することに恐縮してしまうのですが、何かの読み物で「UNIX(のようなマルチユーザーOS)は自分の爪先を拳銃で撃ち抜くような自由があるOSだ」という言説を読んで納得した記憶があります。そして上記に引用したsudoコマンド実行時のメッセージを読むと、自ずとその重要性を理解していただけるはずです。

原因特定のおさらい

ここまでの原因特定についておさらいしてみましょう。

• 障害被疑部位はどこか

▸ WEBサーバー自身

√ そもそもOSが起動していない

√ OSは起動しているがWEBサーバープログラムが起動していない

√ WEBサーバープログラムは起動しているが、PHP-FPMなどのWEBアプリケーション・サーバープログラムが起動していない

√ WEBサーバープログラムおよびWEBアプリケーション・サーバープログラムは起動しているが、iptables等の設定不備で外部からの接続を拒否している

√ ネットワークインターフェイスがダウンしている

▸ クライアント<- -> WEBサーバー間のネットワークにおいて、ダウンしているノードがあるか設定に不備がある

√ ルーター

√ スイッチ

√ ロードバランサー

√ ファイアウォール

▸ クライアント

√ そもそもアドレスを間違えて入力していた

√ hostsファイルに違うサーバーのアドレスを記述していた

• WEBサーバー側の原因切り分け方法

▸ ssコマンド

▸ lsofコマンド

▸ psコマンド

▸ iptablesコマンドまたはfirewall-cmdコマンド

いかがでしたでしょうか。初見のWEBサーバーであっても、本稿に示したコマンドと心構えをセットにすることで、勇気をもって立ち向かうことができれば幸いです。次回は、もう少し実践的な内容に踏み込んでみたいと思います。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes