EC2-CentOSでルートボリュームを明示的に切り替える方法。

アイキャッチ AWS EC2

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、せーのです。今日はボリュームを複数アタッチした際に起こるちょっとした問題の解決法です。
EC2のボリュームをsnapshotやAMIコピーではなく手動で移動やコピーをしたい場合、ルートボリュームを別のインスタンスにアタッチする事があります。その際Amazon Linuxであれば起動中のEC2にリアルタイムにアタッチできるのですが、CentOS等のMarketplaceにあるボリュームの場合、一旦アタッチ先のインスタンスをSTOPしてからアタッチする必要があります。つまりコピー元のインスタンス、ボリュームをA、アタッチ先のインスタンス、ボリュームをBとしますと

  • 1.インスタンスBをSTOP
  • 2.インスタンスBにボリュームAをアタッチ
  • 3.インスタンスBを立ち上げる

という順番になります。そうしますとインスタンスBを立ち上げた時にボリュームAがルートボリュームと認識されて立ち上がることがあるのです。

現象を再現してみる

まず普通にEC2をCentOSで立ち上げます。わかりやすいようにプロンプト表示を変えます。

echo 'export PS1=TESTHOST$' >> ~/.bash_profile ; source ~/.bash_profile 
TESTHOST$

一旦STOPしてEBSのsnapshotを取得します。

duplicate_root_volume1

snapshotから新たなvolumeを作ります。

duplicate_root_volume2

できました。こちらを別のEC2(CentOS)にアタッチします。この時アタッチ先のインスタンスが起動中だとこのようなエラーが出ます。

duplicate_root_volume3

正常にアタッチできたらSSHでログインしてみます。

$ ssh root@54.65.235.241 -i ~/dev/key/cm_experimentation.pem
Last login: Thu Jan 15 02:22:24 2015 from 182.171.232.237
TESTHOST$

先程表示を変えたプロンプトが出てきました。つまり元々のルートボリュームでログインされず、アタッチしたボリュームをルートボリュームとしてログインされているということです。さあ困った

原因

この現象はインスタンス起動時にボリュームのラベルを参照してルートボリュームの割り当てが行われている動作に起因したものです。
CentOSにはデフォルトでGRUBがインストールされていますが、その設定ファイルである[/boot/grub/menu.lst]にはこのような記述がされています。

kernel /boot/vmlinuz-2.6.32-431.29.2.el6.x86_64 ro root=LABEL=_ console=ttyS0,115200 crashkernel=no

これは簡単に言うと「"_"という名前のラベルでブートしなさい」という意味です。CentOS AMIではルートボリュームに標準で "_" のラベルが割り当てられており、同一のラベルを有する2つのボリュームがアタッチされた状態でインスタンスが起動いたしますと、後に追加された方のボリュームがルートボリュームとしてマウントされます(ラベルはインスタンスタイプ等によって変わります)。なので元々あるルートボリュームではなく新たにアタッチされたボリューム(別のインスタンスのルートボリュームのスナップショットから作っているのでラベルは"_"となる)をルートとして立ち上がったわけです。

解決法

さて、この問題の解決法ですがルートボリュームとして認識されるラベルが2つあるおかげで誤認識してしまうのですから、ルートとして認識させたくない方のラベルを変えてしまえばいいわけです。ラベルを変えるにはe2labelというコマンドを使います。まずは新しくアタッチされているボリュームのパーティションを確認します。

TESTHOST$df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvdq1      7.9G  834M  6.7G  11% /
tmpfs           1.9G     0  1.9G   0% /dev/shm

この[/dev/xvdq1]というのがルートボリュームのパーティションですね。このラベルを確認します。

TESTHOST$e2label /dev/xvdq1
_

このボリュームのラベルは"_"であるのが確認できました。ではこのラベルを変えます。

TESTHOST$e2label /dev/xvdq1 TEST
TESTHOST$e2label /dev/xvdq1
TEST

ラベルをTESTに変えました。サーバーを再起動して再びSSHログインしてみます。

$ ssh root@XXX.XXX.XXX.XXX -i XXXXXXXXXXXXX.pem
The authenticity of host 'XXX.XXX.XXX.XXX' can't be established.
RSA key fingerprint is .
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'XXX.XXX.XXX.XXX' (RSA) to the list of known hosts.
[root@ip-172-31-2-206 ~]#

お、プロンプト名が変わりました。元々あったボリュームでログインできているようです。パーティションを確認してそれぞれのラベルを見てみます。

[root@ip-172-31-2-206 ~]# cat /proc/partitions
major minor  #blocks  name

 202       64    8388608 xvde
 202       65    8387584 xvde1
 202      256    8388608 xvdq
 202      257    8387584 xvdq1
[root@ip-172-31-2-206 ~]# e2label /dev/xvde1
_
[root@ip-172-31-2-206 ~]# e2label /dev/xvdq1
TEST

元々あるルートボリュームは"_"、新しくアタッチされたボリュームは"TEST"というラベルになっていることが確認できます。

まとめ

いかがでしたでしょうか。今回の現象はCentOSのPVインスタンスにあるボリュームをHVMインスタンスに変更する、という作業の途中で起こりました。もし同様の事象で困っている方がいればこちらを参考になさって頂ければ幸いです。