こんにちは!「LINUX工房」メインライターの「リナックス先生」よ。
今日から全8回にわたって、AlmaLinux 9環境における「LAMP(Linux, Apache, MariaDB, PHP)構成の完全トラブルシューティング」のカリキュラムをスタートするわ。インフラエンジニアとして、システムをゼロから構築できるのは素晴らしいこと。でも、真の腕前が試されるのは「動かなくなった時」よ。エラー画面を前にしてフリーズする初心者から、論理的なアプローチで迅速にシステムを復旧させる頼れるプロフェッショナルへと、あなたを確実に引き上げてみせるわ。
先生、助けてください!昨日まで完璧に動いていたWebサイトが、今朝見たら突然アクセスできなくなっていたんです。ブラウザで開いても「サイトにアクセスできません」って出るだけで……。とりあえずApacheの設定ファイル(httpd.conf)を色々書き換えて再起動を繰り返しているんですが、全然直りません!どうしたらいいですか!?
ちょっと待ちなさい!状況も分かっていないのに、闇雲に設定ファイルを書き換えるのは一番やってはいけない「愚者のデバッグ」よ!余計に状況を悪化させて迷宮入りするだけ。Webサイトが見れない原因は、Apacheの設定だけとは限らないわ。ネットワークが切れているのか、ファイアウォールで弾かれているのか、データベースが落ちているのか。まずは冷静に「どこが壊れているか」を見極める【障害の切り分け】から始めるのよ!
AlmaLinux 9 LAMP構成の完全トラブルシューティング(全8回)
- 【今回】第1回:LAMP障害の切り分け術!「どこが壊れているか」を見極める初期対応の極意
- 第2回:Webサーバーが起動しない!?Apache (httpd) のログ解読と設定トラブルシューティング
- 第3回:データベース接続エラーの恐怖!MariaDBの起動失敗とソケット問題の解決法
- 第4回:画面が真っ白に!PHP-FPMの500エラーと「死の真っ白画面」完全撃退法
- 第5回:最強の壁を味方にせよ!AlmaLinux 9のSELinuxとパーミッション設定トラブル解決
- 第6回:突然の激重・アクセス不可!OOM Killerの恐怖とリソース枯渇の特定
- 第7回:WordPressを止めない!LAMP連携(Apache×PHP×MariaDB)の高度なトラブル対応
- 第8回:夜中も安眠するための運用術!障害を未然に防ぐログ監視とLAMP最適化
目次
1. 障害の全体像を把握する「外堀を埋める」ネットワークアプローチ
① 概念と背景(Why)
Webサイトにアクセスできないという障害報告を受けたとき、多くの初心者は反射的にサーバーへSSHログインし、すぐに `httpd.conf` や `php.ini` といったアプリケーション層(OSI参照モデルのレイヤー7)の設定ファイルを疑い始めます。しかし、インフラエンジニアの鉄則は「外側から内側へ」、あるいは「下位レイヤーから上位レイヤーへ」順番に確認していくことです。これを「外堀を埋める」アプローチと呼びます。
なぜこの順序が絶対なのか。それは、大前提となる通信経路(ネットワーク)や名前解決(DNS)が破綻している状態で、どれほどApacheの設定を完璧にチューニングしても、パケットは永遠にサーバーに到達しないからです。「サーバー自体がダウンして応答不能になっているのか(Ping応答なし)」「ドメイン名が正しいIPアドレスに変換されていないのか(DNS障害)」「サーバーのOSまでは到達しているがWebサービスが応答していないのか(TCPポート拒否)」という、パケットがどの段階で迷子になっているかを特定しなければ、戦うべき相手すら分かりません。
特にクラウド環境(AWS, VPSなど)を利用している場合、サーバー内部のOS設定だけでなく、クラウドプロバイダ側が提供する仮想ルーターやセキュリティグループといった外部要因によって通信が遮断されているケースも多々あります。これを見極めるためには、自分自身のPC(クライアント側)から対象サーバーに向けて段階的な通信テストを行い、ネットワークの疎通性という「事実」を積み上げていく必要があります。この初動調査をサボると、何時間も間違った場所を探し続けるという悲劇を引き起こします。インフラのデバッグにおいて推測は敵であり、確認された事実のみがあなたを解決へと導くのです。
② 実践手順と完全なコード(How)
クライアント端末(あなたの手元のMacやWindows、または踏み台サーバーのターミナル)から、対象となるAlmaLinux 9サーバーへ向けてネットワークレベルの切り分けを行います。以下のコマンドを順番に実行し、どこで通信が途絶えるかを確認します。
# 1. IPアドレスレベルでの疎通確認(ICMP Echo Request) # サーバーのグローバルIPアドレス(ここでは 192.0.2.10 とします)へPingを送信 ping -c 4 192.0.2.10 # 2. DNSの名前解決の確認(ドメイン名からIPアドレスが正しく引けるか) # 対象のドメイン名(ここでは example.com とします)を問い合わせる dig example.com +short # 3. Webサービスレベルでの通信確認(HTTPリクエストの詳細確認) # ブラウザのキャッシュを無視し、純粋なHTTPレスポンスヘッダを取得する curl -I -v http://example.com/
③ プロによるコードの「1行・1オプション」徹底解説
- ping:ICMPというプロトコルを使用して、対象ホストまでのIPレベルの到達性を確認します。ここで応答がなければ、サーバーがシャットダウンしているか、途中のネットワークが切断されているか、あるいはサーバー側でICMPパケットを意図的にドロップ(破棄)している可能性を示します。
- -c 4:`ping` コマンドのオプションで、「パケットを送信する回数(count)」を指定します。Linuxの `ping` はデフォルトで無限に送信し続けるため、`-c 4` と指定して4回だけ送信し、自動終了させるのがスクリプトや手動確認時の定石です。
- dig:DNSサーバーに対して直接問い合わせを行い、名前解決(ドメイン名からIPアドレスへの変換)の結果を取得するコマンドです。古い解説記事にある `nslookup` よりも詳細な情報が得られるため、現代のLinuxエンジニアは `dig` を使用します。
- +short:`dig` コマンドのオプションで、余計な出力(ヘッダ情報や問い合わせ時間など)を全て省略し、結果となるIPアドレスの文字列のみをシンプルに出力させます。スクリプトに組み込む際や、素早く結果だけを知りたい場合に非常に便利です。
- curl:コマンドラインから様々なプロトコル(HTTP, HTTPS, FTPなど)でデータを転送するツールです。ブラウザとは異なりキャッシュを持たないため、「本当にサーバーがその応答を返しているか」という生の挙動を確認するのに最適です。
- -I(大文字のアイ):HTTPリクエストメソッドをGETからHEADに変更し、サーバーからのレスポンスボディ(HTMLの中身)をダウンロードせず、HTTPレスポンスヘッダ情報だけを取得します。ステータスコード(200 OK や 500 Internal Server Error 等)の確認に特化させます。
- -v:verbose(詳細)モードを有効にします。これをつけることで、TCPの3ウェイハンドシェイク(接続確立処理)の過程や、サーバーとやり取りした生のリクエスト・レスポンスヘッダの全貌が可視化され、どこで接続が拒否されたのかが明確になります。
④ 現場のリアル(失敗談とノウハウ)
💡 プロのノウハウ:ブラウザのキャッシュという最悪の罠
初心者がよく陥るのが「設定を直したのにブラウザで再読み込みしても直らない!」とパニックになる現象です。現代のブラウザは非常に賢く、パフォーマンス向上のために強固なキャッシュを持っています。特に、一度 301 Redirect(恒久的な移動)などの応答を受け取ると、サーバーの設定を修正してもブラウザ側が過去の記憶だけで画面を描画し続けます。現場のプロは、Webサーバーの動作確認において絶対に常用ブラウザを使用しません。必ずターミナルから `curl` コマンドを叩くか、シークレットウィンドウ(プライベートブラウズ)を毎回立ち上げ直して、完全にキャッシュの存在しない環境で検証を行います。ブラウザの表示を信用せず、`curl` の生ヘッダだけを真実として扱うのがトラブルシューティングの絶対ルールです。
2. ファイアウォールとポートの開放状況を完全掌握する
① 概念と背景(Why)
ネットワークレベルの到達性(Ping)が確認でき、DNSの名前解決も正しいIPアドレスを指している。それなのに `curl` コマンドを実行すると `Connection refused`(接続拒否)や `Connection timed out`(接続タイムアウト)というエラーが返ってくる場合、次に疑うべきは「ポート」と「ファイアウォール」という門番の存在です。
サーバー内部では、Apache(httpd)というプロセスが「80番ポート(HTTP)」や「443番ポート(HTTPS)」という特定の扉の前で、外部からの訪問者を待ち構えています。これを「リッスン(待ち受け)状態」と呼びます。もしApacheが何らかの理由で起動に失敗していれば、扉の前に誰もいないため、OSは訪問者に対して即座に `Connection refused` を突き返します。
一方で、Apacheが正しく待ち構えていても、サーバーの周囲を強固な城壁(ファイアウォール)が囲んでおり、その扉へと続く道自体を封鎖している場合があります。AlmaLinux 9では `firewalld` という強力なファイアウォール管理システムが標準で稼働しており、デフォルトの設定ではSSH(22番)以外の外部からの通信を容赦なくすべて破棄(Drop)します。このファイアウォールによって通信が破棄された場合、クライアント側には何も応答が返らないため、パケットが宇宙の果てに消えたかのように `Connection timed out` となります。
したがって、「Apacheプロセスが指定したポートで確実に待ち受けているか(内部の確認)」と、「firewalldがそのポートへの外部からのアクセスを許可しているか(城壁の確認)」の2つの事実を、別々のコマンドを用いてサーバー内部から正確に把握する必要があります。これらの一致を確認して初めて、パケットがアプリケーション層まで到達する経路が確立されたと断言できるのです。
② 実践手順と完全なコード(How)
対象のAlmaLinux 9サーバーにSSHでログインし、特権ユーザー(root)権限を用いて、ネットワークソケットの待受状態と、ファイアウォールの許可ルールを徹底的に検査します。
# 1. プロセスがTCPポートをリッスン(待ち受け)しているか確認 sudo ss -nlpt # 2. firewalldの現在の稼働状態を確認 sudo firewall-cmd --state # 3. firewalldの「現在メモリ上で適用されている」全ルールを確認 sudo firewall-cmd --list-all # 4. firewalldの「再起動後も永続的に適用される」全ルールを確認 sudo firewall-cmd --list-all --permanent
③ プロによるコードの「1行・1オプション」徹底解説
- ss:Socket Statisticsの略で、Linuxカーネル内部のネットワーク接続状態やポートの待受状態を高速かつ詳細に表示する現代の標準コマンドです。古いCentOS時代に使われていた `netstat` コマンドは非推奨となっているため、AlmaLinux 9では必ず `ss` を使用します。
- -n:numericオプションです。ポート番号を「http」や「ssh」といったサービス名に変換せず、「80」や「22」といった純粋な数値のまま出力します。名前解決のオーバーヘッドを防ぎ、正確なポート番号を把握するために必須です。
- -l:listeningオプションです。現在確立されている通信ではなく、外部からの接続を「待ち受けている」ソケットだけを抽出して表示します。サーバーデーモンの死活監視に用います。
- -p:processオプションです。そのポートを開いているプロセス名(httpdやmariadbなど)とプロセスID(PID)を表示します。この情報を表示させるためには、管理者権限(sudo)での実行が必須となります。
- -t:tcpオプションです。UDPソケットなどを除外し、Web通信の根幹であるTCPソケットのみに絞り込んで出力をスッキリさせます。
- firewall-cmd:AlmaLinux 9の標準ファイアウォール管理ツールである `firewalld` を操作し、設定を確認・変更するためのコマンドです。
- –state:firewalldのデーモン自体が起動して動いているか(running)、あるいは停止しているか(not running)を一言で確認します。
- –list-all:現在アクティブになっているゾーン(通常はpublic)に対して、どのサービス(http, https等)やポートが許可されているかの一覧を表示します。ここで表示されるのは「現在メモリ上で実際に稼働している(ランタイムの)ルール」です。
- –permanent:永続化(パーマネント)されたルールを表示するオプションです。設定ファイルに書き込まれ、サーバーを再起動しても維持されるルール群を確認します。
④ 現場のリアル(失敗談とノウハウ)
⚠️ トラブルシューティング / 注意点:再起動で消える幻のファイアウォール設定
サーバー構築時に初心者が100%踏み抜く最悪の地雷が「ファイアウォールの永続化忘れ」です。一時的に firewall-cmd --add-service=http を実行して「よし、Webサイトが見れた!」と安心し、そのまま本番運用に突入。そして数ヶ月後、カーネルアップデートに伴うサーバー再起動が発生した瞬間、Webサイトがパタリと死にます。これは --permanent オプションをつけずに設定を追加したため、再起動時にメモリ上のルールが消滅し、初期状態の「全拒否」に戻ってしまったことが原因です。現場のプロは、現在の状態(--list-all)と永続化された状態(--list-all --permanent)の出力結果が完全に一致しているかを必ず比較確認します。この2つのコマンドはセットで実行する癖をつけてください。
3. サービス(デーモン)の起動状態とプロセス生存確認
① 概念と背景(Why)
ポートが正しく開き、ファイアウォールも許可されている。しかし、それでもWebサイトが正常に表示されない、あるいは「502 Bad Gateway」や「503 Service Unavailable」といったHTTPエラーステータスが返ってくる状態に直面したとします。この段階に到達したならば、ついにサーバー内部で稼働する各種ミドルウェア(Apache, PHP-FPM, MariaDB)の動作状況という、アプリケーション層のトラブルシューティングへと足を踏み入れます。
AlmaLinux 9をはじめとする現代のLinuxディストリビューションでは、システムの起動処理から個別のサービスの死活監視まで、システム全体のプロセス管理を `systemd` という強大なプログラムが単独で取り仕切っています。RPMパッケージ(dnfコマンド)を用いてインストールされたApache(httpd)やMariaDBは、すべてこの `systemd` の配下に組み込まれ、「ユニット」として厳格に管理されることになります。
ここで重要なのは、「プロセスがただメモリ上に存在していること」と「サービスとして正常に稼働し、要求に応えられる状態であること」は全く異なるという事実です。例えば、設定ファイルのシンタックスエラー(構文間違い)が原因で、Apacheが起動処理の途中でパニックを起こして停止した場合、メモリ上には中途半端なプロセスがゾンビのように残る事がありますが、サービスとしては完全に機能不全に陥っています。この乖離を見抜くためには、`ps` コマンドで単にプロセスの有無を見るだけではなく、`systemd` の総元締めである `systemctl` コマンドを用いて、「OSから見てこのサービスはどのような健康状態にあると認識されているか」を正確に把握しなければなりません。この「プロセスの状態(Status)」の確認こそが、内部障害を切り分けるための最初のメスとなるのです。
② 実践手順と完全なコード(How)
LAMP環境を構成する主要な3つのサービス(Apache, PHP-FPM, MariaDB)に対して、`systemctl` コマンドを用いて現在の稼働ステータスを詳細に確認します。
# 1. Apache (httpd) サービスのステータス確認 sudo systemctl --no-pager status httpd # 2. PHP-FPM (PHP FastCGI Process Manager) サービスのステータス確認 sudo systemctl --no-pager status php-fpm # 3. MariaDB (MySQL互換データベース) サービスのステータス確認 sudo systemctl --no-pager status mariadb # 4. OS全体でのプロセスの生の存在確認(systemctlで不明瞭な場合の裏付け) ps aux | grep -E 'httpd|php-fpm|mariadb' | grep -v grep
③ プロによるコードの「1行・1オプション」徹底解説
- systemctl:`systemd` システムおよびサービスマネージャーを制御するための中心となるコマンドです。サービスの起動(start)、停止(stop)、再起動(restart)、そして状態確認(status)を行います。
- –no-pager:`systemctl status` を実行すると、出力が長い場合に `less` コマンドのような対話型のページャー画面に切り替わり、コマンドプロンプトが奪われてしまいます。このオプションをつけることで、ページャーを無効化し、標準出力としてそのままターミナルにテキストを吐き出させます。出力結果をコピー&ペーストしたり、ログファイルにリダイレクトして保存する際に必須のオプションです。
- status:指定したサービス(ユニット)の現在の状態、メモリ使用量、メインPID、そして直近のエラーログの一部をまとめて表示する、極めて情報量の多いサブコマンドです。
- httpd, php-fpm, mariadb:AlmaLinux 9における各RPMパッケージの正式なサービス名です。Debian/Ubuntu系ではApacheが `apache2`、MariaDBが `mysql` というサービス名になることがありますが、Red Hat系のAlmaLinuxではこの名称が絶対となります。
- ps:Process Statusの略で、現在OS上で動作している生のプロセス情報を一覧表示する古典的かつ強力なコマンドです。
- aux:`ps` コマンドに対する定番のオプション組み合わせです。`a` は他のユーザーのプロセスも表示、`u` はユーザー名やCPU/メモリ使用率などの詳細フォーマットで表示、`x` は制御端末を持たないデーモンプロセス(バックグラウンドで動くサービス)も表示します。
- grep -E ‘…’:拡張正規表現(-E)を用いて、httpd, php-fpm, mariadb のいずれかの文字列が含まれる行だけを抽出します。複数サービスのプロセスを一撃で確認するためのプロの書き方です。
- grep -v grep:`grep` コマンド自身のプロセスが検索結果にノイズとして混入するのを防ぐための除外(-v)処理です。シェルスクリプトに組み込む際の定石中の定石です。
④ 現場のリアル(失敗談とノウハウ)
| systemctlのステータス表示 | 現場での意味と解釈 | プロの次なる行動 |
|---|---|---|
| active (running) | 正常稼働中。プロセスも生きており問題なし。 | これでもエラーが出るなら、設定内容のミスか権限(SELinux)を疑う。 |
| inactive (dead) | 管理者が手動で停止したか、意図的に起動していない状態。 | systemctl start で起動を試み、エラーが出ないか注視する。 |
| failed | エラーにより異常終了。致命的な問題が発生している。 | ステータス画面下部のログを読むか、journalctl で原因を追求する。 |
| activating (auto-restart) | クラッシュと再起動の無限ループに陥っている最悪の状態。 | サーバーのリソース(CPU/メモリ)を急激に消費するため、即座に systemctl stop で止めてから原因調査に移る。 |
4. ログの海に潜る前の準備「journalctlとdmesg」の全体俯瞰
① 概念と背景(Why)
サービスが `failed`(異常終了)状態になっていることを突き止めたとします。ApacheやMariaDBが「なぜ起動できなかったのか」という理由を知るためには、彼らが残したダイイングメッセージ、すなわち「ログ」を読むしかありません。ここで初心者は、インターネットの古い記事に導かれて `cat /var/log/messages` を実行したり、`/var/log/httpd/error_log` を必死に探したりします。しかし、これもまた現代のトラブルシューティングにおいては遠回りとなるアプローチです。
AlmaLinux 9をはじめとする最新のシステムでは、`systemd` の一部である `systemd-journald` というログ管理機構が導入されています。これは、OSのカーネルログ、初期ブートプロセス、各ミドルウェアの標準出力・標準エラー出力、そしてSyslogの全てを一箇所に集約し、「バイナリ形式」で強固に保存する中央集権的なログシステムです。テキストファイルとして分散していた従来のログとは異なり、改ざん耐性が高く、メタデータ(時刻、プロセスID、重要度)による強力なフィルタリング検索が可能なのが最大の特徴です。
Apacheの独自エラーログ(error_log)には、Webアプリケーションの動作に関する情報(PHPの文法エラーやファイルが見つからない等)は詳細に記録されます。しかし、「メモリ不足(OOM)でOSによってプロセスが強制的に抹殺された(Killされた)」というような、OSレベルでの致命的な事象は、Apache自身のログファイルには一切記録されません。自分が殺された瞬間に日記を書ける人間がいないのと同じです。このようなOSレベルの暴挙やハードウェアのエラーを見逃さないために、個別のログファイルに潜る前に、まずは全システムログを俯瞰できる `journalctl` とカーネルの生ログである `dmesg` を使用して、「OSレベルで異常が起きていないか」をチェックすることが、トラブル対応における絶対的なセーフティネットとなるのです。
② 実践手順と完全なコード(How)
障害発生時刻の周辺で、OS全体や対象サービスに対して「深刻なエラー」が発生していないかを、`journalctl` および `dmesg` コマンドを用いて精密に抽出します。
# 1. 過去1時間以内に発生したOS全体の「エラーレベル(err)以上」のログを抽出 sudo journalctl -p err --since "1 hour ago" --no-pager # 2. Apache (httpd) サービスに関連するログだけを抽出し、最新から過去へ遡って表示 sudo journalctl -u httpd -e --no-pager # 3. OSのカーネルログ(ハードウェアエラーやメモリ枯渇による強制終了情報)を確認 # タイムスタンプを人間が読める形式に変換して表示 sudo dmesg -T | grep -i -E 'kill|oom|error|fault'
③ プロによるコードの「1行・1オプション」徹底解説
- journalctl:`systemd-journald` によって収集されたバイナリログデータを読み出し、強力なフィルタリングをかけてターミナルに表示するための専用コマンドです。
- -p err:priority(優先度)オプションです。システムログには情報(info)から緊急事態(emerg)まで様々なレベルがあります。`-p err` と指定することで、単なる情報や警告(warning)を除外して、「エラー(error)以上」の深刻な事象だけに情報を削ぎ落とします。ノイズを消すための必須テクニックです。
- –since “1 hour ago”:時刻によるフィルタリングです。障害が起きたと報告された時間帯にフォーカスします。”yesterday”(昨日)や “2024-04-24 10:00:00” といった具体的な日時指定も可能です。数カ月分のログをすべて読み込むのを防ぐ安全装置でもあります。
- -u httpd:unit(ユニット)オプションです。システム全体のログから、`httpd` サービス(Apache)から吐き出されたログメッセージだけに完全に絞り込みます。`grep` を使うよりも高速かつ正確です。
- -e:endオプションです。ログの最も古い部分(上部)から表示するのではなく、最も新しい最新のログ(末尾)へ瞬時にジャンプして表示を開始します。直近のエラーを確認したい場合に有効です。
- dmesg:Display Messageの略で、Linuxカーネルが出力する「リングバッファ(メモリ上の循環ログ領域)」の内容を表示するコマンドです。ハードウェアの認識エラーや、OOM Killer(メモリ不足時のプロセス強制終了機構)の発動など、システム最深部の悲鳴を聞き取るために使用します。
- -T:Timeオプションです。デフォルトの `dmesg` のタイムスタンプは「OSが起動してからの秒数([ 12.345678])」という人間には解読不可能な形式ですが、`-T` をつけることで `[Thu Apr 24 10:00:00 2024]` のような通常の時刻表記に変換して出力してくれます。
- grep -i -E ‘…’:大文字小文字を区別せず(-i)、指定した複数の危険なキーワード(kill, oom, error, fault)を含む行だけをカーネルログの中からピックアップします。
④ 現場のリアル(失敗談とノウハウ)
💡 プロのノウハウ:「Out of memory: Killed process」の絶望と発見
サーバーが突然重くなり、Webサイトへのアクセスが途絶え、SSHすら数分間反応しなくなる。そしてやっとログインしてApacheのエラーログ(error_log)を見ても、何の痕跡も残っていない……。この怪奇現象の正体の9割は「OOM Killer(Out of Memory Killer)」です。サーバーの物理メモリが完全に枯渇した時、Linuxカーネルはシステム全体がクラッシュするのを防ぐため、最もメモリを食っているプロセス(多くの場合、MySQLや大量にプロセスを生成したApache/PHP-FPM)を無慈悲に、そして無言で強制終了させます。この「カーネルによる処刑記録」は、各アプリケーションのログには絶対に残りません。プロのインフラエンジニアが障害対応の第一手として必ず dmesg -T | grep -i kill を打つのは、この「見えない死因」を真っ先に除外するためなのです。
先生、言われた通りに順番に確認してみました! Pingは通るし、ポート80番も待受状態になっていました。でも、systemctl status httpd を叩いたら、ステータスが真っ赤な文字で failed になっていました! その後 journalctl -u httpd -e を見たら、設定ファイルの72行目に構文エラーがあるってバッチリ書いてありました。そこを直したら一瞬で復旧しました……!
よくやったわ!それが「論理的な切り分け」の力よ。当てずっぽうに設定ファイルをいじるのではなく、ネットワークからOS、プロセス、そしてログへと確実にステップを踏むことで、問題の核心に最短距離で到達できるの。これがプロのトラブルシューティングの基本中の基本。次回・第2回は、このApacheの起動エラーや設定トラブルについて、さらに深く深く潜っていくわよ。覚悟しておきなさい!
▼ サーバー構築・開発を学ぶならVPSで ▼
エンジニア必須の環境
「おすすめVPS」
技術スキルを活かす
「ITエンジニア転職」

コメント