iSCSIとは、TCP/IP上にSCSIプロトコルを流す、ネットワークストレージプロトコルの一種です。ストレージエリアネットワーク(SAN)といえばファイバーチャネルなどが連想されますが、iSCSIは一般的なイーサネット上に構築することが可能なため、非常に手軽かつ安価に導入できるというメリットがあります。
今週のレシピはUbuntuを使ってiSCSIターゲットを構築し、利用する方法を紹介します。
そもそもiSCSIとは?
iSCSIはSambaのような、サーバ側の共有空間を多数のクライアントで同時に使うタイプのサービスとは根本的に異なり、TCP/IPを経由してストレージそのものを提供する仕組みです。ネットワーク越しに接続されているUSBハードディスクのようなものをイメージすると理解しやすいかもしれません。ネットワーク上にあるストレージをiSCSIターゲット、ターゲットに接続するクライアントをiSCSIイニシエータと呼称します。USBハードディスクがPCと1対1で接続されるように、iSCSIターゲットもまた、複数のイニシエータから同時に接続することはできません[1] 。
[1] 厳密に言えば接続することはできますが、他のホストとの競合を解消することが困難なため、データ破損などの危険があります。この問題を解決するにはクラスタ対応のファイルシステムを使うなどの対策を行う必要があります。
iSCSIターゲットの構築
それではUbuntuを使ってiSCSIターゲットを構築しましょう。Ubuntuで利用できるiSCSIターゲットソフトウェアには「iSCSI Enterprise Target」というものがあり、パッケージ名「iscsitarget」で提供されています。iSCSIターゲットには、サーバに接続されているハードディスクやファイルを設定することができます。今回は例としてホームディレクトリにddでイメージファイルを作成し、ターゲットに設定しました。
$ sudo apt-get install iscsitarget
$ dd if=/dev/zero of=iscsi.img count=0 bs=1 seek=10G
iSCSIターゲットの設定は、/etc/ietd.conf[2] に記述します。まずTargetセクションを記述して1つのターゲットを定義し、Targetセクション内に論理ユニット番号(LUN)を定義します。LUNにはターゲットとするファイルやブロックデバイスと、タイプを指定してください。タイプにはfileioの他にblockioが指定できます。詳しくは man 5 ietd.conf が参考になるでしょう。TargetセクションのiqnはiSCSIのターゲットの識別子になりますので、重複しないユニークな名前をつけてください。これはiqnの命名規則より「iqn.年-月.ドメイン名:任意の名前」となります[3] 。これが、ターゲットに最低限必要な設定となります。設定が完了したら、iscsitargetを再起動しましょう。
$ sudo vi /etc/ietd.conf
(末尾に追記)
Target iqn.2010-06.org.rikunet:lucid64.disk
Lun 0 Path=/home/mizuno/iscsi.img,Type=fileio
$ sudo service iscsitarget restart
iSCSIイニシエータの設定
次にイニシエータ側の設定を行いましょう。Ubuntuで使えるiSCSIイニシエータには「Open-iSCSI」があり、パッケージ名はopen-iscsiです。open-iscsiをインストールすると、/sbin/iscsidがデーモンとして動作します。iSCSIデバイスの検出や設定を行うには、iscsidの動作が必要不可欠となっています。
まずはiSCSIターゲットの検出を行ないましょう。iscsiadmコマンドのモード(-mオプション)にdiscoveryを指定し、指定したIPアドレスのマシンで動作しているiSCSIターゲットを検出します。なお一度検出したターゲットは、/etc/iscsi/nodes以下に設定が作成されます。ターゲットの検出に成功してiqnが得られたら、iscsiadmコマンドの--loginオプションを実行してください。loginを行うことで、アクセスに必要なブロックデバイスが作成されます。この状態でdmesgを見ると、/dev/sd*としてブロックデバイスが見えるようになっているのがわかるでしょう[4] 。これでローカルなストレージと同じように、デバイスをマウントして扱うことができるようになりました。
最後に、使い終わったターゲットを切り離す場合はlogoutを行う必要があります。これらオプションの詳細は、iscsiadmのマニュアルを参照してください。
$ sudo apt-get install open-iscsi
$ sudo iscsiadm -m discovery -t sendtargets -p 192.168.1.101
192.168.1.101:3260,1 iqn.2010-06.org.rikunet:lucid64.disk
$ sudo iscsiadm -m node --targetname iqn.2010-06.org.rikunet:lucid64.disk --login
Logging in to [iface: default, target: iqn.2010-06.org.rikunet:lucid64.disk, portal: 192.168.1.101,3260]
Login to [iface: default, target: iqn.2010-06.org.rikunet:lucid64.disk, portal: 192.168.1.101,3260]: successful
$ sudo iscsiadm -m session
tcp: [1] 192.168.1.101:3260,1 iqn.2010-06.org.rikunet:lucid64.disk
$ sudo iscsiadm -m node --targetname iqn.2010-06.org.rikunet:lucid64.disk --logout
$ dmesg
(...略...)
[64138.651423] Loading iSCSI transport class v2.0-870.
[64138.680752] iscsi: registered transport (tcp)
[64138.778495] iscsi: registered transport (iser)
[64257.961268] scsi2 : iSCSI Initiator over TCP/IP
[64258.268368] scsi 2:0:0:0: Direct-Access IET VIRTUAL-DISK 0 PQ: 0 ANSI: 4
[64258.271769] sd 2:0:0:0: Attached scsi generic sg1 type 0
[64258.282679] sd 2:0:0:0: [sda] 20971520 512-byte logical blocks: (10.7 GB/10.0 GiB)
[64258.285488] sd 2:0:0:0: [sda] Write Protect is off
[64258.285493] sd 2:0:0:0: [sda] Mode Sense: 77 00 00 08
[64258.288386] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[64258.293266] sda: sda1 sda2 < sda5 >
[64258.301948] sd 2:0:0:0: [sda] Attached SCSI disk
$ sudo apt-get install lsscsi
$ lsscsi
[0:0:0:0] cd/dvd HL-DT-ST RW/DVD GCC-4247N 1.02 /dev/sr0
[2:0:0:0] disk IET VIRTUAL-DISK 0 /dev/sda
Mac OS XでのiSCSIイニシエータ
iSCSIは当然、Linux以外のOSでも使うことができます。特にMac OS XではTime Machineのバックアップ先にiSCSIを指定することができますので、「 MacBookにUSBハードディスクをぶら下げるのはちょっと……」というような場合に活用できるかもしれません。Mac OS X用のiSCSIイニシエータとして、今回はglobalSAN を試用してみました。
図1 globalSANのインストール画面。通常のアプリケーションと同様、mpkgファイルをダブルクリックしてインストールしよう
globalSANをインストールして再起動すると、[システム環境設定] -> [globalSAN iSCSI]からiSCSIイニシエータの設定を行うことができるようになります。iscsiadmと同様、ターゲットのiqnとIPアドレスを指定して接続しましょう。
図2 [システム環境設定] -> [globalSAN iSCSI]から設定を呼び出せる。ターゲットのiqnとIPアドレスを入力するだけで、簡単に接続できる
図3 接続したターゲットはデスクトップにアイコンも表示され、ローカルディスクと同様に扱える
図4 Time Machineのバックアップ先に設定することも可能。バックアップに失敗しているのは、今回テストで用意したターゲットの容量が小さすぎたため
iSCSIにUbuntuをインストール
Ubuntu Server EditionではインストーラにiSCSIイニシエータが搭載されており、iSCSIターゲットへUbuntuをインストールすることができます。まず、Server EditionのCDから通常通りインストーラを起動してください。パーティション構成の段階で"Configure iSCSI volumes"を選択すると、iSCSIターゲットへのロギングオプションが表示されます。
図5 iSCSIボリュームの使用を選択する
ここで"Log into iSCSI targets"を選択し、ターゲットのIPアドレスを入力してください。ターゲットが標準のポート3260を使用している場合は、ポート番号は省略することができます。IPアドレスが正しく入力されたら、使用できるターゲットのiqnの一覧がリストされますので、インストールしたいターゲットにスペースキーでマークして、"Continue"を選択してください。
図6 iSCSIターゲットへログインする
図7 iSCSIターゲットのIPアドレスとポート番号を入力。ポート番号は省略可能
図8 使用するターゲットのiqnを選択しよう
そのあとは通常のインストール手順と同様、パーティションの作成やマウントポイントの指定を行うことができます。
図9 あとは通常のローカルディスクと同じように扱える
PXEとiSCSIでディスクレス起動
このようにiSCSIターゲットにUbuntuをインストールするのは簡単ですが、それだけではUbuntuを起動させることはできません。ディスクレスでUbuntuを起動させるには、ハードディスク以外の何らかのメディアからカーネルを起動させ、iSCSIイニシエータを起動し、iSCSIターゲット上のルートファイルシステムをマウントする必要があります。そこでDHCPサーバとTFTPサーバを用いて、おなじみのネットワークブートを行うことにします。
DHCPサーバとTFTPサーバのインストールは本連載47回 とほぼ同一です。/var/lib/tftpbootへPXE起動用のnetbootインストーラの配置までを行う必要がありますので、参考にしてください[5] 。
しかし、このnetbootインストーラはあくまでネットワークから起動してメニューを表示させるためだけのもので、netbootインストール用のカーネルでマシンを起動させるわけにはいきません。当然ですがマシンの起動に使うカーネルとinitrdは、先ほどインストールしたサーバのものを使う必要があります。そこでインストールに使用したiSCSIターゲットを別のイニシエータを使ってマウントし、/vmlinuzと/initrd.imgを取り出して、TFTPサーバの/var/lib/tftpbootに配置してください。次に、/var/lib/tftpboot/ubuntu-installer/i386/boot-screens/text.cfgを編集し、以下を追記します。
$ sudo vi /var/lib/tftpboot/ubuntu-installer/i386/boot-screens/text.cfg
label iSCSI initiator
menu label ^iSCSI initiator
kernel vmlinuz
append root=/dev/sda1 iscsi_target_name=iqn.2010-06.org.rikunet:lucid64.disk iscsi_target_ip=192.168.1.101 iscsi_target_port=3260 initrd=initrd.img
rootはルートファイルシステムの場所ですが、これは起動するマシンからiSCSIターゲットがどのようなブロックデバイスとして見えるかを意識して指定してください。例えば、ディスクレスなマシンでしたら/dev/sdaになりますし、HDDを一台内蔵しているマシンでしたら/dev/sdbになるでしょう。iscsi_target_nameやiscsi_target_ipは環境に合わせて変更してください。
また、デフォルトではnetbootのメニューはキー入力を待ちますので、一定時間で自動的に起動するよう/var/lib/tftpboot/pxelinux.cfg/defaultにタイムアウトを指定します。
$ sudo vi /var/lib/tftpboot/pxelinux.cfg/default
timeout 100
図10 netbootの起動画面。ここからiSCSIを使用するカーネルを起動させられる
これで、ネットワークからマシンをブートすることで、iSCSIをルートファイルシステムとしてUbuntuを起動させることが可能になりました。/var/log/messagesを見てみると、起動時に IET VIRTUAL-DISK をマウントしているのがわかります。
Jun 21 16:27:23 ubuntu kernel: [ 3.251786] iscsi: registered transport (tcp)
Jun 21 16:27:23 ubuntu kernel: [ 3.509579] scsi2 : iSCSI Initiator over TCP/IP
Jun 21 16:27:23 ubuntu kernel: [ 3.773183] scsi 2:0:0:0: Direct-Access IET VIRTUAL-DISK 0 PQ: 0 ANSI: 4
Jun 21 16:27:23 ubuntu kernel: [ 3.775033] sd 2:0:0:0: Attached scsi generic sg0 type 0
Jun 21 16:27:23 ubuntu kernel: [ 3.779950] sd 2:0:0:0: [sda] 20971520 512-byte logical blocks: (10.7 GB/10.0 GiB)
Jun 21 16:27:23 ubuntu kernel: [ 3.780861] sd 2:0:0:0: [sda] Write Protect is off
Jun 21 16:27:23 ubuntu kernel: [ 3.782569] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
Jun 21 16:27:23 ubuntu kernel: [ 3.786981] sda: sda1 sda2 < sda5 >
Jun 21 16:27:23 ubuntu kernel: [ 3.795967] sd 2:0:0:0: [sda] Attached SCSI disk
Jun 21 16:27:23 ubuntu kernel: [ 3.939767] EXT4-fs (sda1): mounted filesystem with ordered data mode
Jun 21 16:27:23 ubuntu kernel: [ 12.442224] udev: starting version 151
Jun 21 16:27:23 ubuntu kernel: [ 12.457712] Adding 492536k swap on /dev/sda5. Priority:-1 extents:1 across:492536k