こんにちは!「LINUX工房」管理人の「リナックス先生」です。
最新の「Ubuntu 26.04 LTS」を用いたサーバー運用において、前回のトラブルシューティング記事では「ディスクフル」や「APTエラー」「SSHの締め出し」といった基礎的なインシデントの解決法を解説しました。
しかし、サーバー運用の現場でエンジニアを待ち受けているのは、OSの基礎トラブルだけではありません。
Webサイトを暗号化する「SSL証明書の自動更新の失敗」、突然死する「MySQLデータベースの破損」、VPSのプランをアップグレードしたのに容量が増えない「ストレージ拡張の罠」、そして「Dockerネットワークの競合」など、ミドルウェアやアーキテクチャに深く根ざした「中級・上級のトラブル」が必ず発生します。
先生、大変です!今朝起きたら、Let’s Encryptから「SSL証明書の期限が切れますよ!」って警告メールが来ていました。
それに、WordPressを開いたら「データベース接続確立エラー」って表示されて、もうパニックです!前回のディスク容量やメモリの確認はしたんですが、異常はなくて……一体どうやって直せばいいんですか!?
コウ君、落ち着いて!基礎的なOSトラブルを卒業して、ついにミドルウェアのトラブルに直面したわね。これがインフラエンジニアとしての真の成長のチャンスよ!
SSLの更新失敗も、データベースのクラッシュも、原因は必ずログに残っているし、正しい復旧プロセスが存在するの。今日はUbuntu 26.04環境における「高度な実践的トラブルシューティング」を、プロの視点で徹底的に解剖していくわよ!
本記事は、前回とは全く異なる「ミドルウェア・アーキテクチャ特化型」のトラブルシューティング大全です。対象バージョンをUbuntu 26.04 LTSに完全準拠させ、8000文字を超える圧倒的な情報量と豊富な図表で、あなたを「どんな障害でも解決できる一人前のSRE(サイト信頼性エンジニア)」へと導きます。
目次
- 1. Webサーバーの暗号化トラブル:Let’s Encrypt (Certbot) 更新失敗の完全解決
- 2. データベースの悲劇:MySQL (InnoDB) クラッシュからの復旧とパスワードリセット
- 3. ストレージの限界突破:ダウンタイムなしの LVM 容量拡張術
- 4. メモリの「見せかけの枯渇」:buff/cache 肥大化の謎と正しいメモリ管理
- 5. コンテナ通信の迷宮:DockerネットワークのIP競合とDNSエラー
- 6. 認証とAPI通信の異常:時刻同期 (systemd-timesyncd) のズレが引き起こす障害
- 総まとめ:アーキテクチャの深淵を理解し、真のプロフェッショナルへ
1. Webサーバーの暗号化トラブル:Let’s Encrypt (Certbot) 更新失敗の完全解決
現代のWebサイトにおいて、HTTPS化(SSL/TLS暗号化)は必須です。無料で利用できる「Let’s Encrypt」と更新ツール「Certbot」は非常に便利ですが、90日の有効期限が切れる前に「自動更新(renew)」が失敗し、ある日突然Webサイトに「この接続ではプライバシーが保護されません」と警告画面が出るトラブルが後を絶ちません。
1-1. 更新失敗の原因を探る「Dry Run」テスト
証明書の更新が失敗している場合、まずは本番環境を汚さずにシミュレーションを行う --dry-run コマンドを実行し、エラーの全貌を把握します。
# Certbotの更新シミュレーションを実行する sudo certbot renew --dry-run
このログに出力される内容によって、原因を特定します。プロのエンジニアは以下の表のようにエラーを切り分けます。
| エラーメッセージのキーワード | プロの診断(根本原因) | 具体的な解決アクション |
|---|---|---|
Connection refusedまたは Timeout |
Let’s Encryptのサーバーからあなたのサーバーの 80番ポート(HTTP) に到達できていません。ファイアウォール(UFW)で80番が閉じられているか、クラウド側のセキュリティグループで遮断されています。 | sudo ufw status を確認し、sudo ufw allow 80/tcp を実行する。HTTPS(443)だけでなく、HTTP(80)も更新の認証(HTTP-01チャレンジ)に必須です。 |
404 Not FoundInvalid response from ... /.well-known/acme-challenge/ |
サーバーには到達できましたが、Nginxが認証用の隠しファイル(.well-known ディレクトリ)を正しく返却できていません。Nginxのリバースプロキシ設定などが邪魔をしています。 |
Nginxの設定ファイル(/etc/nginx/sites-available/...)に、location ^~ /.well-known/acme-challenge/ { root /var/www/html; } のような専用のルーティングを追記し、Nginxをリロードします。 |
DNS problem: NXDOMAIN looking up A for ... |
ドメインのDNSレコード(Aレコード)が、現在稼働しているサーバーのIPアドレスと一致していません。サーバー移転後によく発生します。 | ドメインの管理画面(お名前.comやRoute53など)にログインし、Aレコードが現在のUbuntuサーバーのグローバルIPを向いているか確認します。 |
なるほど!「WebサイトはもうHTTPS(443番ポート)に完全移行したから、HTTP(80番ポート)は塞いじゃえ!」と思ってUFWで閉じたら、Let’s Encryptの更新審査員(ボット)が80番ポートから入ってこれなくなって、更新に失敗していたんですね……。盲点でした!
1-2. Nginxの再起動設定漏れの修正
無事に証明書が更新されても、「Nginxが古い証明書をメモリに読み込んだままになっている」と、ブラウザには期限切れと表示され続けます。
Ubuntu 26.04のCertbotでは、証明書更新後に自動でNginxをリロードするフック(Hook)を設定するのがプロの常識です。
# 更新設定ファイル(例:/etc/letsencrypt/renewal/example.com.conf)を確認 sudo nano /etc/letsencrypt/renewal/example.com.conf # ファイルの末尾に [renewalparams] セクションがあれば、以下の1行を追記します post_hook = systemctl reload nginx
これにより、次回からは証明書が更新された瞬間にNginxが無停止でリロードされ、完全自動化が達成されます。
2. データベースの悲劇:MySQL (InnoDB) クラッシュからの復旧とパスワードリセット
WordPressなどのCMSが「データベース接続確立エラー」を吐き出している場合、原因の多くはMySQLサーバー(またはMariaDB)のダウンです。
単なるプロセス停止なら再起動で直りますが、サーバーの不意の電源断(ハードウェア障害やOOM Killerによる強制終了)が原因で「InnoDBエンジンのデータファイルが破損して起動しなくなる」という、背筋が凍るような事態が発生することがあります。
2-1. MySQLが起動しない原因の特定
まずはMySQLサービスの状態と詳細ログを確認します。
sudo systemctl status mysql sudo journalctl -u mysql -n 50 --no-pager
ログの中に InnoDB: Database page corruption や InnoDB: Assertion failure といった恐ろしい文字列が見えた場合、データファイルが物理的に破損しています。
2-2. innodb_force_recovery による強制復旧術
破損したMySQLを通常起動することはできません。被害を最小限に食い止め、なんとかデータ(SQLダンプ)を吸い出すための「セーフモード」で強制起動させる必要があります。
設定ファイル /etc/mysql/mysql.conf.d/mysqld.cnf を編集します。
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf # [mysqld] セクションの中に、以下の1行を追記します innodb_force_recovery = 1
| Recovery Level | 挙動の解説とプロの判断 |
|---|---|
| 1 (SRV_FORCE_IGNORE_CORRUPT) | 破損したページを無視して起動します。まずは 1 から試します。これで起動すれば御の字です。 |
| 2 〜 3 | バックグラウンドのパージ処理やトランザクションのロールバックを無効化します。1でダメなら段階的に数字を上げます。 |
| 4 〜 6 | データ破壊の危険性が極めて高い最終手段です。DBは「読み取り専用」になり、起動したら即座に mysqldump で全データを抽出し、MySQL自体を再インストールしてデータを流し直す必要があります。 |
設定を書き換えたら sudo systemctl start mysql で起動を試みます。無事に起動したら、一秒でも早く mysqldump を実行して全データのバックアップを取ってください。 その後、innodb_force_recovery の行を削除し、データベースを初期化・再構築してバックアップをリストアするのが完全な復旧手順です。
2-3. rootパスワードを忘れた場合の強制リセット
もう一つの「あるある」が、MySQLのrootパスワード紛失です。これもセーフモードの一種で解決できます。
# 1. MySQLを停止 sudo systemctl stop mysql # 2. 権限チェックをスキップするモードで一時的に起動(バックグラウンド実行) sudo mysqld_safe --skip-grant-tables --skip-networking & # 3. パスワードなしでrootログイン sudo mysql -u root # 4. パスワードの再設定(MySQL 8.0以降の構文) mysql> FLUSH PRIVILEGES; mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword123!'; mysql> exit; # 5. 一時プロセスをキルして通常起動 sudo killall mysqld sudo systemctl start mysql
3. ストレージの限界突破:ダウンタイムなしの LVM 容量拡張術
VPSやクラウドサーバーを運用していてディスク容量が足りなくなった際、コントロールパネルから「プランをアップグレード(ディスク容量追加)」することがあります。
しかし、サーバーを再起動して df -h コマンドを打っても、「容量が前のままで全く増えていない!」という罠に必ずハマります。
そうなんです!高いお金を払って50GBから100GBのプランに上げたのに、Ubuntu上では「50GB中50GB使用(100%)」のままで、結局エラーが直りませんでした。
クラウドの会社に騙されたんでしょうか!?
騙されてないわよ!クラウド側が提供したのはあくまで「物理的なハコ(ハードディスク)のサイズを広げた」だけ。
OSの中に引かれている「パーティションの仕切り壁」や、LVM(論理ボリュームマネージャー)、そして「ファイルシステムの枠」は、自分自身でコマンドを打って拡張してあげないと、OSは使える容量が増えたことに気づけないのよ。
Ubuntu 26.04なら、システムを一切止めずにオンラインのまま容量を拡張できるわ!
3-1. LVM(論理ボリュームマネージャー)の3つの層
容量を拡張するには、LVMの階層構造(下から上)を理解し、順番に広げていく必要があります。
- PV(Physical Volume:物理ボリューム): 実際のハードディスクのパーティション。
- VG(Volume Group:ボリュームグループ): 複数のPVをまとめた巨大な「仮想的なディスクプール」。
- LV(Logical Volume:論理ボリューム): VGから切り出してOSに提供される「仮想パーティション」。これにext4などのファイルシステムが乗ります。
3-2. 無停止容量拡張の完全ステップ
以下の手順で、追加された物理容量をOSのルートディレクトリ(/)に適用します。
| ステップ | 実行コマンドと解説 |
|---|---|
| 1. パーティションの拡張 | sudo growpart /dev/sda 3(例:sdaディスクの3番パーティションに、増えた分の空き領域をすべて割り当てて拡張します。※クラウド環境で必須) |
| 2. PV(物理ボリューム)の拡張 | sudo pvresize /dev/sda3(LVMに「物理的な壁が広がったよ」と認識させ、VGの空き容量を増やします) |
| 3. LV(論理ボリューム)の拡張 | sudo lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv(増えたVGの空き容量を、すべてルート論理ボリュームに割り当てます) |
| 4. ファイルシステムの拡張 | sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv(論理ボリュームに乗っているext4ファイルシステムを拡張します。XFSの場合は xfs_growfs を使用します。これで初めて df -h の表示が増えます!) |
これらの一連のコマンドは、WebサーバーやDBを稼働させたままで安全に実行できます。インフラエンジニアの必須スキルです。
4. メモリの「見せかけの枯渇」:buff/cache 肥大化の謎と正しいメモリ管理
「サーバーのメモリが足りないみたいです!」と相談を受けた際、プロがサーバーに入って free -h コマンドを打つと、実は全く問題がないケースが多々あります。
4-1. Linuxのメモリ管理哲学「Free RAM is Wasted RAM」
free -h コマンドの出力を正しく読めるかどうかが、プロと素人の分かれ目です。
total used free shared buff/cache available
Mem: 7.8Gi 1.2Gi 0.5Gi 0.1Gi 6.1Gi 6.2Gi
Swap: 2.0Gi 0.0Gi 2.0Gi
📝 プロのステータス解読
素人は free (0.5Gi) を見て「空きメモリが500MBしかない!メモリ不足だ!」とパニックになります。しかし、それは大きな勘違いです。
絵で見てわかるLinuxカーネルの仕組み 【電子書籍】[ 市川 正美 ] 価格:3058円 |
Linuxカーネルは「余っているメモリ(RAM)をそのまま遊ばせておくのはもったいない」という思想を持っています。
そのため、一度ディスクから読み込んだファイルデータを、メモリ上の buff/cache 領域(上記の例では6.1GB)に一時保存(ページキャッシュ)し、次に同じファイルが要求された時にディスクへアクセスせず超高速で返却できるように最適化しています。
そして、もしアプリケーション(NginxやDB)が「本物のメモリを要求」してきたら、Linuxはこのキャッシュを瞬時に破棄してアプリに明け渡します。
つまり、本当に見るべきは free ではなく、「今すぐアプリに明け渡せる実質的な空き容量」を示す available(上記の例では6.2GB)なのです。このサーバーは非常に健康です。
4-2. キャッシュの強制解放(ドロップキャッシュ)
基本的にカーネルに任せておけば問題ありませんが、巨大なログファイルを検索した直後など、意図的にキャッシュを手動で解放してメモリをクリーンにしたい場合があります。
その際は、カーネルの drop_caches フラグに数値を書き込みます。
# 念のためデータをディスクに書き出す(同期) sync # ページキャッシュ、dentry、inodeのキャッシュをすべて解放する(ルート権限) echo 3 | sudo tee /proc/sys/vm/drop_caches
これを実行した直後に free -h を打つと、buff/cache が激減し、free が激増しているのが視覚的にわかります。(※本番稼働中のDBサーバー等で行うと、キャッシュが消えて一時的にディスクI/Oが跳ね上がるため、計画的に実施してください)。
5. コンテナ通信の迷宮:DockerネットワークのIP競合とDNSエラー
第7回でDockerの素晴らしさを解説しましたが、実運用に入るとDocker特有のネットワークトラブルに見舞われます。「コンテナの中からインターネット(aptや外部API)に繋がらない」「会社の社内LANとDockerが干渉して通信が途絶えた」といった問題です。
5-1. 恐怖の「172.17.0.0/16」IP競合問題
Dockerはインストールされると、ホストOS上に docker0 という仮想ブリッジネットワークを自動作成し、デフォルトで 172.17.0.0/16 などのIP帯域をコンテナに割り当てます。
しかし、もしあなたのサーバーが置かれているオフィスやデータセンターのLAN環境が、たまたま同じ 172.17.X.X 帯域を使用していた場合、「ルーティングの競合」が発生します。サーバーはパケットを社内LANではなくDocker内部に流してしまい、結果としてサーバーがネットワークから孤立します。
5-2. daemon.json によるブリッジIPの変更
この競合を避けるため、プロのインフラエンジニアはDockerを本番導入する際、Dockerが使用するデフォルトのIP帯域(bip: Bridge IP)を、絶対に社内LANと被らないマイナーな帯域(例:10.200.0.1/24 など)に明示的に変更します。
# Dockerのデーモン設定ファイルを作成/編集 sudo nano /etc/docker/daemon.json
以下のようにJSON形式で記述します。
{
"bip": "10.200.0.1/24",
"default-address-pools": [
{
"base": "10.201.0.0/16",
"size": 24
}
]
}
設定を保存したら、sudo systemctl restart docker で再起動します。これで、Dockerが作成するネットワークはすべて 10.20X.X.X 帯域になり、競合の悪夢から解放されます。
5-3. コンテナ内のDNS解決エラー
「ホストOSからは curl google.com が通るのに、コンテナの中からだと名前解決ができずエラーになる」場合、Dockerが参照するDNS設定が壊れている可能性があります。
同じく daemon.json にGoogleのパブリックDNSなどを強制指定することで解決します。
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
6. 認証とAPI通信の異常:時刻同期 (systemd-timesyncd) のズレが引き起こす障害
「AWS S3へのバックアップが急に失敗するようになった」「多要素認証(MFA / Google Authenticator)のコードが一切通らなくなった」「SSL通信のハンドシェイクでエラーが出る」。
これらのまったく関係なさそうなトラブルの背後にある、たった一つの共通原因をご存知でしょうか?
それは「サーバーのシステム時刻のズレ(Clock Drift)」です。
6-1. 時刻同期の重要性
現代の暗号化通信やクラウドAPIは、セキュリティの観点から「リクエストが発行された時刻」を厳密にチェックしています。サーバーの時計が数分ズレているだけで、「このリクエストは古すぎる(Replay攻撃の疑いがある)」と判断され、すべて拒否されてしまいます。
6-2. systemd-timesyncd による正確な時刻管理
Ubuntu 26.04では、軽量な時刻同期デーモンである systemd-timesyncd が標準で稼働しています。まずは現在の同期状態を確認します。
timedatectl timesync-status
もし同期先サーバー(Server)が表示されない、またはエラーになっている場合は、日本の正確なNTP(Network Time Protocol)サーバーを参照するように設定ファイルを書き換えます。
sudo nano /etc/systemd/timesyncd.conf # [Time] セクションのコメントアウトを外し、NICT(情報通信研究機構)の公開NTPサーバーを指定 [Time] NTP=ntp.nict.jp FallbackNTP=ntp.ubuntu.com
設定後、サービスを再起動して強制同期させます。
sudo systemctl restart systemd-timesyncd timedatectl status
出力の中に System clock synchronized: yes と表示されていれば、あなたのサーバーの時間は原子時計レベルで正確に保たれるようになり、謎のAPIエラーや認証エラーは二度と起こりません。
※より高度な金融システムなどでマイクロ秒単位の精度が求められる場合は、軽量な systemd-timesyncd ではなく、より高機能な chrony パッケージを導入して運用するのがプロの定石です。
総まとめ:アーキテクチャの深淵を理解し、真のプロフェッショナルへ
特大ボリュームでお届けした「Ubuntu 26.04 LTS サーバー運用トラブルシューティング大全(実践編)」、いかがでしたでしょうか。
SSL証明書更新時のルーティングの罠、MySQLのデータ破損という最悪のシナリオからの生還、LVMによる無停止の容量拡張、Linuxメモリ管理哲学の理解、Dockerネットワークの競合回避、そして時刻同期の重要性。
これらはすべて、「OSをただインストールしただけ」では決して気づけない、現場で血と汗を流したエンジニアだけが知っている深淵の知識(ノウハウ)です。
トラブルが発生した時、「なんとなく再起動する」のは素人です。
プロは、エラーログを読み、アーキテクチャの構造(Nginxのリバースプロキシ、LVMの階層、Linuxのページキャッシュ)を脳内に描きながら、一つ一つのボトルネックを論理的に切り分けていきます。
このトラブルシューティングの知識を持った皆さんは、もうインフラの表面を撫でるだけの初心者ではありません。どんな複雑なシステム障害が起きても、冷静に、そして確実にシステムを復旧させることができる「本物のSRE(サイト信頼性エンジニア)」です。
サーバー構築と運用に終わりはありません。これからも発生するであろう未知のトラブルを恐れず、「システムをより深く理解するためのチャンス」として楽しんでください。
「LINUX工房」は、これからも皆さんのインフラエンジニアとしての挑戦を全力で応援します。リナックス先生でした!
▼ トラブル対応力を実践環境で磨くなら ▼
LVM構成やDocker競合のテストに最適
「スナップショット機能付き国内VPS」
高度なトラブルシューティング技術を武器に
「SRE・クラウドエンジニアへ転職」

コメント