お仕事を通して知り合った IT 企業の社長さん(とってもコンピュータに詳しいお方)と、その協力会社のネットワークエンジニアさんから様々なネットワーク知識を取得しました。
Kernel Panic CentOS 6.3 で
「yum update」 を実行したところ、ややサーバの動きがおかしくなりました。改善のために CentOS を試みましたが……なんと
「Kernel Panic」 という文字が画面に表示され、CentOS が起動しなくなってしまいました。
↑Kernel Panic
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0.0) Pid: 1, comm: swapper Not tainted 2.6.32-358.23.2.el6.x86_64 #1 どうやら
「カーネル」 がおかしいようです。
不具合が発生した原因は二の次として、まず先に改善方法を以下にメモします。
以下手順です。
1.CentOS 本体に電源を入れ
GRUB に入る。
2.GRUB 画面から過去のカーネルバージョンを指定して CentOS を起動する。
3.
「/etc/grub.conf」 の 「default=0」 を 「default=1」 に変更する。 4.CentOS を再起動する。
上記の改善方法は、インターネット上の IT ブログから見つけました。どうやら僕だけじゃなく、他の方々も同じ症状に悩まされているようです。ただ 「Kernel Panic」 といっても様々な原因があるはず。上記の方法だけで解決しない場合もあると思いますが、僕の場合はコレで大丈夫でした。
……さて、口すっぱく書きますけども。。
「Kernel Panic が起きた。言われたとおり /etc/grub.conf を書き換えたら直った。なんで直ったのかよく分かんないけど、まぁ直ったからいいや」
これではイケマセン。インフラまわりのプロを目指すためにも、ここで
「根本の原因」 や
「動作概念」 を理解しておく必要があります。解決方法は前述しましたとおりですが、以下からは Kernel Panic についてのメモを残したいと思います。
カーネルとは そもそも 「カーネル」 ってなんでしょうか。
調べ直してみたところ、カーネルとは
「OS の核となるところ」 といった説明文が多く見られました。しかし僕自身、漠然としたイメージしか思い浮かばなかったので、ここでは
「カーネル=ハードウェアの制御に特化したプログラム群」 としてイメージします。
アプリケーションを動かすときにハードウェアを利用するのはもちろんのことですが、基本的に
アプリケーションはハードウェアを直接制御することはできません。 ハードウェアの機能を使うには、Windows や Linux などの OS に制御を依頼する必要があります。様々な機能の集合体ともいえる OS の機能の中で、ハードウェアの制御を担当するのが、前述にもありますようこのカーネルです。
↑図1:カーネルの位置づけ
カーネルはハードウェアとアプリケーションの仲介役を担っていますので、カーネルはとても重要な部分であることが分かります。今回の Kernel Panic は、このカーネルに問題が発生してしまったようです。
Kernel Panic の原因 ハードウェアの制御を担当するカーネルに
致命的なエラー が発生した場合に、この Kernel Panic が起こります。原因はそれぞれですが、今回の場合は
「yum update」 コマンドを実行したタイミングで発生しました。
yum update コマンドは、CentOS 内にインストールされているパッケージをアップデートするコマンドですが、このコマンドを実行すると
カーネルのバージョン もバージョンアップされます。ごく稀にですがカーネルをバージョンアップすると、今回のような Kernel Panic を引き起こしてしまうことがあります。
しかし、カーネルのバージョンアップそのものが
「悪」 というわけではなく、必要なモジュールを使うためにはカーネルのバージョンアップが必要なときもあります。これは僕の経験談ですが、Hyper-V 2.0 の時代に Ubuntu 10.04 を仮想化したときは、Ubuntu 10.04 のカーネル(Linux Kernel 2.6.32以前)が 「統合サービス (Linux Integration Services)」 に対応していませんでした。こういった場合、カーネルのバージョンアップが必要になるのです。
↑図2:Hyper-V 用のモジュールが古いカーネルには組み込まれていない
しかし今回のような
「特に目的の無いバージョンアップ」 はあまりオススメしません。Kernel Panic の発生により、
「新しいバージョンが必ずしも良い」 という考えが覆された瞬間でした。
ブートまでの流れ Kernel Panic が発生したあとに
「/etc/grub.conf(/boot/grub/grub.conf)」 の
「default=0」 を
「default=1」 に変更したところ、起動しなくなった CentOS が立ち上がってくれました。この動作の意味をメモしていきますが、まずはその前に
「ブート」 の仕組みを理解しておいた方が良いでしょう。
ブートとはコンピュータ用語で
「起動」 を意味します。パソコンの電源ボタンを押すと、ハードディスクから Windows などの OS が読み込まれた後、マウスやキーボード操作ができる
「いつもの」 パソコンが立ち上がるのはご存じだと思いますが、この
「いつもの」 パソコンが立ち上がる(ブート)までに、マシンの内部では以下のような動作が行われています。
1.パソコンの電源を入れる
2.「BIOS」 がハードウェアの初期設定を行う(ハードウェアが認識する)
3.ハードディスクから 「ブートローダー」 が読み込まれる
4.ブートローダーがカーネルを読み込む
5.パソコンが使える
↑図3:ブートの流れ(簡易的)
ここで、上記の 「1~5」 までの流れを順に追っていきます。
(1~2) まずパソコンの電源を入れると
「BIOS (Basic Input Output System)」 が起動します。これは名前の通り、ハードウェアの基本的な入出力を行なう機能です。BIOS にはハードウェアを初期設定するプログラムが書き込まれており、そのプログラムによってハードウェアが認識します。また BIOS のプログラムは
ROM に書き込まれているため、ファームウェアのバージョンアップなどしない限り、プログラムを書き換えることはできません。
↑図4:一般的な BIOS 管理画面 (VMware Player の BIOS)
(3~4) 次に、ハードウェアが認識したあと CPU が HDD の
MBR に保存された
「ブートローダー」 を読み込みます。ブートローダーとは 「カーネルを立ち上げるプログラム」 のことを指します。その後 CPU はブートローダーが持つ
「カーネルの保存場所の情報」 をもとに HDD に保存されたカーネルを読み込みます。
ちなみに、カーネルそのものは圧縮されており、そのカーネルを展開するのもカーネルの自身が行います。カーネルのバージョンが 「2.6.30.7」 の場合、
init/main.c というファイルからあらゆる初期化プログラムを実行していきますが、これらは再起処理のように自身で展開していきます。自身の力だけで起動することから 「ブートストラップ」 という呼び方もあるようです。うまいですね。(※技術評論者:Linuxエンジニア育成本参考)
(5) こうして、カーネルが自身を展開していくことで OS が読み込まれていき、我々がよく目にするログイン画面などの操作が可能になります。
以上の流れから PC が起動します。
電源ボタンを押すと PC 内部ではこういった動きをしています。スゴイの一言に尽きますね。
ブートローダー ブートローダーについて、もう少し詳しくメモしていきます。
前述しましたが、ブートローダーは HDD の
「MBR (Maste Boot Record)」 に保存されています。MBR は HDD の 「先頭セクタ」 とも呼ばれ、BIOS は
このセクタを一番最初に読み込みます。 またこのセクタは 「512バイト」 と決まっており、その中身には
「カーネルの保存位置」 が記録されています。最初からこの位置にカーネルをロードできれば良いのですが、さすがに512バイトの領域にはカーネルは収まりきりませんので、MBR にはカーネルの保存位置を格納させるだけに留めています。また、このセクタ位置が 「固定」 されていることで、BIOS はピンポイントにこのセクタを読みに行きます。
↑図5:セクタと MBR のイメージ
続いてブートローダーは MBR のカーネル保存位置を参照して、
カーネルを RAM にロードします 。ロードされたカーネルは、自身で自身を展開していきます。これはすなわち RAM にカーネルがロードされたタイミングで、
ブートローダーからカーネルへ制御が移った ことを意味します。よってこの時点でブートローダの役割は終わります。
↑図6:カーネルを RAM へロード
ブートローダーのメモはこのあたりで十分だと思います。
なぜここまでブートローダーについてのメモを残したのかと言いますと、今回 Kernel Panic を回避するために設定した
「GRUB」 こそが、このブートローダーだからです。
さて、ではそろそろ今回の本題である
「Kernel Panic の改善方法の理解」 についてまとめます。
Kernel Panic まとめ 本記事の冒頭にも書きましたが、今回の Kernel Panic は以下の方法で回避しました。
1.CentOS 本体に電源を入れ GRUB に入る。
2.GRUB 画面から過去のカーネルバージョンを指定して CentOS を起動する。
3.「/etc/grub.conf」 の 「default=0」 を 「default=1」 に変更する。
4.CentOS を再起動する。
この問題が発生した当初は、全くもってトラブルの原因や解決法が分かりませんでしたが、本記事を書いている今はだいぶ理解ができてきました。ということで、整理とおさらいを兼ねて以下にまとめをメモします。
- トラブル発生 - まず 「yum update」 によって、カーネルがバージョンアップ
(2.6.32-279 → 2.6.32-358) しました。このカーネルのバージョンアップに失敗したのか、カーネルに致命的なエラーが発生しました。この Kernel Panic によって OS が一切立ち上がらなくなってしまいました。
- 1.CentOS 本体に電源を入れ GRUB に入る - マシンに電源を入れると
「BIOS → ブートローダー → カーネル」 の順に起動します。PC はカーネルよりも MBR に入ったブートローダーを先に起動する仕組みになっているため、たとえどれだけカーネルが破壊されていても、GRUB を先に立ち上げて操作ができるのです。
- 2.GRUB 画面から過去のカーネルバージョンを指定して CentOS を起動する - カーネルはバージョンアップの際に、
古いバージョンのカーネルを残すことができます。 CentOS ではデフォルトで古いカーネルを残すのでしょうかね。今回は古いカーネルが残ってましたから、幸運としか言いようがなかったです。
↑図7:ロードするカーネルの選択
- 3.「/etc/grub.conf」 の 「default=0」 を 「default=1」 に変更する - CentOS では GRUB の設定を 「/etc/grub.conf(または/boot/grub/grub.conf)」で設定します。この設定ファイルの設定によって、マシン起動時の GRUB の動きを操作できます。この
「default=n」 とは
「n番目のカーネルをマシン起動時にロードする」 ための選択でした。今回は 「default=1」 と書きましたので、古いカーネルが選択されたことになります。
↑図8:2.6.32-279 と 2.6.32-358 が確認できる
また、以下の図は 「yum update」 を実行する前の /etc/grub.conf ファイルです。カーネルのバージョンアップをしていないため、カーネル情報が1つしかありません。
↑図9:2.6.32-279 のみ存在する
default=0 の他に 「timeout=5」 という項目がありますが、これはブートメニューを表示させたときに、自動でカーネルが選択されるまでの時間でした。他にも色々と探してみると面白いかもしれませんね。
- 4.CentOS を再起動する - 「default=1」 に変更したことで、次回からはデフォルトで古いカーネルをロードするようになりました。これで一件落着……といいたいところですが、あくまで新しいカーネルが不具合を起こしたから、再び古いカーネルを使い続けることになっただけに過ぎません。しかし前述もしましたが、とくに必要なモジュールや機能が無い限り、古いカーネルを使い続けてもさほど問題ありません。ムリにバージョンアップする必要もないのです(触らぬ神に祟りなし?)
長くなりましたが、以上で Kernel Panic のまとめは終わりです。かなりフラフラな文章を打ってしまいましたが、個人的には結構理解が深まりました(笑)。最後まで読んでくださり、ありがとうございました。
大反省 実は今回のトラブルは、
客先で引き起こしてしまったモノでした。 客先のサーバメンテナンスを任されまして、あるパッケージを導入したところ………カーネルまでもがアップデートされてしまい、今回のようなサーバ停止を引き起こしてしまいました。本来なら1時間弱で終わるメンテナンスの予定でしたが、サーバを再び復旧できたのはトラブル発生から
6時間後 でした。。
トラブルを引き起こした原因はただ一つ。
僕の配慮が足りなかったことです。 もっと動作検証を繰り返す、または本記事のような知識を持ち合わせていたら、おそらく yum update を使わずにソースファイルからのパッケージインストールを施していたでしょう。
今回の出来事は、あらゆる面で本当にいい経験となりました。
「知識も身に付けつつ、現場の場数を踏むことで、地に足のついた本当のエンジニアになれる」 という冒頭の社長さんからのお言葉が、まさに真理であることが身にしみました。
インフラまわりのプロへの道のりは、まだまだ長そうです。その日が来るまで…日々精進です。。
スポンサーサイト