今回は61回 で紹介したubuntu-vm-builderで構成した仮想マシンを、「 ターミナル内で」動作させる方法を紹介します。
サーバーにおけるビデオカードの必然性(仮想マシンに限らない話)
仮想マシンを「ターミナルで」動作させる前に、少しだけ「ビデオカードの存在しないマシン」の話について触れてみましょう。
一般的なPCの利用形態では、ビデオカード(もしくはノースブリッジ等に内蔵されたビデオチップ機能)の存在は欠かせません。モニタに画面を表示するためにはこれらのチップを用いてアナログ、ないしはデジタルで出力する必要があります。
しかし、ほとんどのサーバーはネットワーク越しに利用されるものですし、管理者が行うべき作業のほとんどもSSH越しに操作できますから、なんらかの緊急時や、初期セットアップ時といったネットワークが利用できない時にのみモニタが必要になります。
逆にいえば、初期セットアップさえ済ませれば、緊急時以外はモニタは不要になるはずです。多くのUnix/Linuxではこうした考えのもとに、モニタ機能を使用せず、RS-232C(シリアル)接続など[1] で最低限のコンソールを確保し、ディスプレイを使わない、といった運用が行われることがあります。こうした構成は「ヘッドレス」と呼ばれます。
設定方法さえ把握しておけば、サーバー装置に電源ケーブルとネットワークケーブルだけ[2] を接続した状態で利用することができるでしょう[3] 。
これは仮想化にどう関係するのでしょうか? 答えは単純で、“ 仮想化環境であっても、実際のハードウェアと同じように、「 ヘッドレス」状態で動作させることができる” ということです。ubuntu-vm-builderで構成したKVM仮想マシンは、起動するとQEMUが提供するコンソール画面が表示されていたはずです。が、サーバーとして利用するのであれば、ほとんどの場合GUIは利用しませんから、あのようなウインドウは不要で、マシンを実行したターミナルでそのまま動作してくれれば便利なはずです。なにより、ああしたウインドウはX環境でしか利用できませんし、SSHから接続した場合はX転送を行わなければ起動できません。これは十分な帯域がなければ利用できませんし、レスポンスも悪く、あまり快適とは言い難いはずです(その一方で、SSHのようにコマンドラインベースの環境であれば、帯域もほとんど要りませんし、比較的快適に利用できます) 。
今回は「仮想マシンをヘッドレスで」起動し、ターミナルだけで仮想マシンを利用するレシピを紹介します。
[1] 現在の多くのサーバーではIPMIなどの遠隔管理機能を内蔵しているため、IP接続で利用可能なKVM機能を使うことがほとんどです。さらに、IPMIの機能を使うことで「内部でRS-232Cに接続し、そのセッションをIP越しに接続できるようにする(SoL; Serial over LANと呼ばれます) 」こともできます。
Ubuntuをヘッドレスで運用する
……ということで、仮想マシンをヘッドレス構成にする前に、Ubuntuをヘッドレス構成にする手順を見ていきましょう。
Ubuntuをヘッドレス構成にし、シリアルポート(RS-232C)を用いてログインできるようにするには、次の3つの設定が必要です。
GRUBの出力デバイスをシリアルポートにする。
カーネルのコンソール出力をシリアルポートに向ける。
シリアルポートからログインできるようにする。
順番に見ていきましょう。
GRUBの出力デバイスをシリアルポートに設定する
最初に、GRUBが出力するブートスプラッシュをシリアルコンソールに出力するように変更します。/boot/grub/menu.lstに以下のように、「 serial」と「terminal」の2行を追加します。
# password --md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
# password topsecret
--unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=5 console serial
#
# examples
#
これにより、GRUBのカウントダウンや、起動時スプラッシュ(図1 )がシリアルポートに出力されるようになります。
図1 GRUBの起動時スプラッシュ
カーネルのコンソール出力をシリアルポートに設定する
次に、カーネルの起動オプションを変更し、コンソールをシリアルポートに設定します。これもGRUBの設定ファイルである/boot/grub/menu.lstから設定します。
/boot/grub/menu.lstに存在する、「 kopt」行に、「 console=tty0 console=ttyS0,115200n8」を追加します。
# kopt=root=UUID=4ead8965-89b4-43da-8849-3e8fee00c1c2 ro console=tty0 console=ttyS0,115200n8
このままでは既存のカーネルの起動オプションが修正されませんので、以下のようにupdate-grubを実行して起動オプションに反映します。
$ sudo update-grub
update-grub実行後、menu.lstの下部にある各kernel行に指定したオプションが追加されたことを確認してください。
title Ubuntu 8.10, kernel 2.6.27-11-server
uuid 4b42d9eb-8925-4a8f-ac79-d24e8fa88309
kernel /boot/vmlinuz-2.6.27-11-server root=UUID=4b42d9eb-8925-4a8f-ac79-d24e8fa88309 ro console=tty0 console=ttyS0,115200n8 quiet splash
initrd /boot/initrd.img-2.6.27-11-server
これにより、Kernelの起動メッセージ(Ubuntuの起動時に表示される各種メッセージ)がシリアルポートに出力されるようになります。
シリアルポートからログインできるように設定する
さらに、シリアルポートにログインのためのインターフェースを設ける必要があります。ここまでで行った設定により、GRUBの起動縲弑buntuの起動完了までのメッセージがシリアルポートに出力されるようになりましたが、このままではシリアルポートからログインすることができないためです。
古典的なLinuxでは、シリアルポートからログインできるようにするための設定は、/etc/inittabで行いますが。が、UbuntuではinitデーモンとしてUpstartを利用しているため、inittabで設定すべきではありません[4] 。
Upstartに即した設定を行うため、/etc/event.d/tty1を以下のように書き換えてください。
# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.
start on stopped rc2
start on stopped rc3
start on stopped rc4
start on stopped rc5
stop on runlevel 0
stop on runlevel 1
stop on runlevel 6
respawn
exec /sbin/getty -L ttyS0 115200 vt100
このように設定することで、そのマシンのシリアルポートにクロスケーブルを接続すれば、シリアル経由でログインすることができるようになるはずです。
今回はシリアル接続で操作することが主眼ではないので軽く触れるだけに留めますが、接続するマシンがWindowsであればTeraTermやPuTTYで、UbuntuからであればGNU Screenを利用し、screen /dev/ttyS0 115200などとすればログインプロンプトが表示されるでしょう。
[4] /etc/inittabに対する互換性も維持されていますので、inittab経由の設定も可能です。が、これはあくまで後方互換性として維持されているだけなので、遠い将来には無効になるはずです(なぜ遠い将来なのかといえば、まだまだ当分の間こうした設定が生き残るからです。少なくとも数年間といった単位では有効なままでしょう) 。
ubuntu-vm-builderで作成した仮想マシンをヘッドレス起動する
さて、61回 で紹介した、KVMによる仮想マシンの使い方を思い出してみましょう。
ubuntu-vm-builderでKVM仮想マシンを作成した場合、run.shというラッパースクリプトが用意され、これを実行することで仮想マシンを起動することが可能でした。ヘッドレス起動を行う場合、このスクリプトに以下のように「-nographic」という引数をつけて起動します[5] 。
$ ./run.sh -nographic
-nographicが与えられた場合、KVM(QEMU)仮想マシンは仮想ビデオカードを構成せず、起動されたコンソールをRS-232C接続に見立てて動作します。つまり、起動後に何らかのキー入力を行うと、あたかもRS-232C接続した環境からキー入力を行ったのと同じ動作を行います。
言い換えれば、この方法で起動した場合、ターミナルがそのままシリアルコンソールになる、ということです。そこで、前述の3つの手順を./run.sh(引数なし)で起動した仮想マシン環境で行ってください。設定はRS-232Cの場合と完全に同じです。
GRUBの出力デバイスをシリアルポートにする。
カーネルのコンソール出力をシリアルポートに向ける。
シリアルポートからログインできるようにする。
その上で「-nographic」起動を行いましょう。
こうすることで、run.shを実行したターミナルにそのままブートメッセージが出力され(図2 ) 、さらにログインプロンプトも表示されます(図3 ) 。
図2 ターミナルに出力される起動メッセージ
図3 ログインプロンプト
当然、このプロンプトからログインして操作することもできます(図4 ) 。
図4 実際にログインした画面
こうすることで、純粋にターミナルの中だけで仮想マシンを起動することが可能になります。GNU Screenと併用することで、Screenを切り替えるごとに異なる仮想マシンのコンソール、などといったことも可能ですし、SSH越しにログインして仮想マシンを起動、などといったことも容易に行え、仮想マシンの利用の幅が大きく広がるはずです。
次週はゴールデンウィーク中ということで、『 Japanese TeamのメンバーがどのようにUbuntuを使っているか』を中心にお届けする予定です。筆者のような邪道っぽい使い方ではないはずですので、そのまま適用して楽しめるはずです。