UbuntuでSAN bootなKVMホストをつくろう。

備忘録もかねてここに記述しておく.

ことの初め

  1. VMwareでできるならUbuntuでもできるはず。証拠?直感。
    1. ちなみにPXEboot(NFS)も試したが、ディスクの見え方とsshの作動状態が怪しく断念。
      1. しかも設定する場所が多すぎる・・・grubとかinitramfs.confとか
    2. もう一つのcasperさんのISOイメージによるbootも鉄板で魅力的だが作るのがそれなりに手間がかかる。
      1. なによりメモリ=ストレージ、swapなんてないのよが結構まずい。
      2. それにセキュリティパッチが出てもアップグレードができない。ヤバい。
  2. なので、SAN bootでちゃれんじする!
メリット
  1. ストレージを集約できる。一台のストレージを見たら全部分かる。
  2. ホストの増減が簡単
    1. 障害が発生してもすぐに別マシーンで起動ができるよ。
      1. ただ、MACアドレスが変わるのがちょっと面倒くさい。
  3. 単位ホストあたりのコストが安く付く。これ重要
デメリット
  1. ネットワークは相当注意しないとすぐ破綻する。
    1. 1Gbpsで直結で出せる速度は論理値Max119MiB/s、で、うちだと70MiB/s,ハブ経由だと40MiB/s
    2. でもレイテンシが低いから結構いい

構想

  1. ネットワークブートでKVMホストを起動
    1. なのでマザーボード(NICが二個※後述)、CPU、メモリでOK!
    2. 電源すらACアダプタ用のものがあるので結構いい感じ
      1. これとかhttp://www.oliospec.com/item_detail/itemCode,picoPSU-160-XT/
流れ
  1. UbuntuのISO(鯖でも机でもOKでも64bitがおすすめ)を用意します。今回は10.04LTS(10.10,11.04はAMDのCPUでKVMが一部動かない。)
  2. VMを一匹作ります。iscsiターゲットにVMホスト機能があるとそっちからも呼べて便利
  3. VMイメージをiscsiディスクとしてiscsiターゲットから公開します。
  4. DHCP3鯖を入れて、そこにgPXEとiscsiから起動するんですよ設定を書く
  5. VMのイメージにiscsiイニシエーターを設定、起動シーケンスの要衝initramfsで起動ディスクとしてiscsiを見るように設定する。
  6. ネットワークから起動してみる。
  7. VMイメージがKVMホストで便利になる様にブリッジの設定を行う。

作り方

  1. VMでイメージを作ってそこにまずインストール
    1. すでに環境があるのでこっちが簡単
  2. ネットワークブートの環境を設定する。
    1. TFTPをインストール、これでネットワークブートになる。

sudo apt-get install tftpd-hpa

    1. 設定

sudo nano /etc/default/tftpd-hpa

      1. 内容は以下のとおり

#Defaults for tftpd-hpa
RUN_DAEMON="yes"
OPTIONS="-l -s /var/lib/tftpboot"

    1. 面倒くさいのでディレクトリを/配下にシンボリックリンクを作っておく

sudo ln -s /var/lib/tftpboot /tftpboot

  1. gPXEの入手
    1. このページを参考にされたしgpxe-1.0.0-gpxe.kpxeというファイルがgetできればOK

http://d.hatena.ne.jp/adsaria/20100622/1277181310

    1. 入手はこちらから

http://rom-o-matic.net/gpxe/gpxe-1.0.0/contrib/rom-o-matic/build.php

      1. これは一度、PXEでbootをしてその後SANbootを行うというもの。これ自身がいわゆるOS。

sudo mkdir /tftpboot/gPXE
sudo cp /home/alfe/gpxe-1.0.0-gpxe.kpxe /tftpboot/gPXE/

      1. ※以上はDHCPの設定で使うディレクトリとして配置
  1. 次にiscsi環境をインストール

apt-get install iscsitarget

  1. iscsi環境を設定

sudo nano /etc/ietd.conf

    1. 内容は下記のとおり、色々ディスクを増やしたい場合はLUNの数字を変えていく。

Target iqn.2011-07.net.lan:p2955be_Lucid64.disk
Lun 0 Path=/mnt/vms/iscsi955beLucidServer.img,Type=fileio

  1. iscsiターゲットサービスの有効化

sudo nano /etc/default/iscsitarget
ISCSITARGET_ENABLE=true

  1. iscsiターゲットサービスを再起動
    1. この時tail -f /var/log/syslogなんかやってると存在しないファイルを指定しているのがメッセージが出てくることで分かる。

sudo service iscsitarget restart

DHCPとTFTP

  1. DHCPサービスを面倒なのでiscsiターゲット鯖上に設定
  2. なお、編集する前に起動するNICMACアドレスを取得しておくこと。
    1. 違うものを設定しておいてもOK。ただ、画面でIPアドレスを探す場面で出てくるはずなのでそれをメモること。

sudo nano /etc/dhcp3/dhcpd.conf

default-lease-time 600;
max-lease-time 7200;

log-facility local7;
allow unknown-clients;

option space gpxe;
option gpxe-encap-opts code 175 = encapsulate gpxe;
option gpxe.no-pxedhcp code 176 = unsigned integer 8;
option gpxe.keep-san code 8 = unsigned integer 8;

ddns-update-style none;
subnet 192.168.0.0 netmask 255.255.255.0 {
        range 192.168.0.64 192.168.0.128;
        option broadcast-address 192.168.0.255;
        option domain-name-servers 192.168.0.1;
        option domain-name "lan.net";           # Domain name
        option routers 192.168.0.1;
}


host diskless-955beEth1 {
        hardware ethernet       00:12:34:56:78:9a;              # Ethernet MAC address
        fixed-address   192.168.0.80;          # Hostname or IP address
        option host-name "phenom2955be";
        if exists user-class and option user-class = "gPXE" {
                filename "";
                option root-path "iscsi:192.168.0.239:::<LUNの番号>:iqn.2011-07.net.lan:p2955be_Lucid64.disk";
                option gpxe.keep-san 1;
        } else {
                filename "/gPXE/gpxe-1.0.0-gpxe.kpxe";
        }
}
host diskless-955beEth2 {
        hardware ethernet       00:12:34:56:78:9b;              # Ethernet MAC address
        fixed-address   192.168.0.81;          # Hostname or IP address
        option host-name "phenom2955be";
}
  1. DHCP鯖再起動

sudo service dhcp3-server restart

以上でサーバー側(SANbootディスク用)の準備はOK

クライアント側の設定

  1. 次のサイトを参考にした

http://etherboot.org/wiki/sanboot/ubuntu_iscsi2

  1. まずBIOSでネットワークブートを出来るように設置する。
    1. またKVMのホストとしても使用するので、仮想化支援機能もONにしておく。
  2. 次に、一度ネットワークブート対象のイメージをKVM経由で起動。
  3. 次のパッケージをインストール

sudo apt-get install ssh open-iscsi open-iscsi-utils libvirt-bin kvm bridge-utils udhcpc sysv-rc-config

  1. 追加設定ファイルの入手

http://etherboot.org/wiki/sanboot/ubuntu_iscsi2
/etc/initramfs-tools/hooks/iscsi

/etc/initramfs-tools/scripts/local-top/iscsi
のファイルをもらってきて(コピペして)
実行権限を与える

sudo chmod +x /etc/initramfs-tools/hooks/iscsi
sudo chmod +x /etc/initramfs-tools/scripts/local-top/iscsi

実行権限を忘れると起動してくれない。

ちなみに(11.04では不要)
  1. /etc/initramfs-tools/scripts/local-top/iscsiにはipconfigと言うdhcpのコマンドが含まれているが状況によっては不安定でdhcpのDHCPOFFERを受け取ってくれない。
    1. したがってこの場合は以下のサイトを参考に別のdhcpクライアントudhcpcを導入して行を入れ替える。

http://www.mail-archive.com/linux-fai@uni-koeln.de/msg03793.html

  1. 内容はudhcpcパッケージは既に上で導入済みなので続けinitramfsにudhcpcを呼べるように追加する。
  2. http://bazaar.launchpad.net/~ltsp-upstream/ltsp/ltsp-trunk/annotate/head:/client/initramfs/hooks/udhcp
    1. →このファイルをdownload fileより取得
    2. 以下のファイルとして保存
      1. /etc/initramfs-tools/hooks/udhcp

sudo chmod +x /etc/initramfs-tools/hooks/udhcp

  1. http://bazaar.launchpad.net/~ltsp-upstream/ltsp/ltsp-trunk/annotate/head:/client/initramfs/scripts/init-premount/udhcp
    1. →このファイルをdownload fileより取得
    2. 以下のファイルとして保存
      1. /etc/initramfs-tools/scripts/init-premount/udhcp

sudo chmod +x /etc/initramfs-tools/scripts/init-premount/udhcp

    1. liveは必要ない。
  1. /etc/initramfs-tools/scripts/local-top/iscsiのipconfigの行(46行目?)を下記のように書き換える。
udhcpc -n -i ${netdev}
さらに(10.10では多分不要)

/etc/initramfs-tools/scripts/init-premount/udhcp
には/temp/dhcp-script.shを生成するが
この内容が受け取った内容のみを表示するようになっているので、実質的なスクリプトになる様に変更する。
135行目のgenerate_dhcp_scriptの内容を
http://d.hatena.ne.jp/katona/20071101/p2
を参考に

#!/bin/sh
echo $1ing...
test -z "$ip" && ip=0.0.0.0
test -n "$subnet" && netmask="netmask $subnet"
ifconfig $interface $ip $netmask
test -n "$router" && route add default gw $router $interface
test -n "$dns" && echo nameserver $dns > /etc/resolv.conf

が出力されるように修正。

    1. ここのところをきちんと作り込めばブリッジでもbondingでもOKなはず。問題はinitramfsの段階でそれを実現する方法がどうなのかは未調査。
  1. /etc/initramfs-tools/scripts/local-top/iscsiのipconfigの行(46行目?)を下記のように書き換える。
udhcpc -n -i ${netdev} -s /temp/dhcp-script.sh
  1. ネットワークの設定:
    1. ここで変なのを書いてしまうと動かない(ブリッジとかbondingとか)

sudo nano /etc/network/interfaces

    1. 全部のloを除いて、ネットワーク接続インターフェイスは下記のmanualのみとする。autoの行もいらない。
auto lo
iface lo inet loopback

iface eth0 inet manual
iface eth1 inet manual
  1. initramfsを更新する

sudo update-initramfs -u -k all

    1. これは今後はアップグレードをしても必要ないはず。
  1. +
  1. 以上が済んだらVMを停止。

sudo shutdown -h now

#--------------------

SAN bootのクライアント側から起動

  1. これで起動するように成るはず
    1. と言うのも不安定で起動する場合としない場合があるため。数回再起動するとうまく行く場合がある。
      1. udhcpcの設定が完璧ならほぼ問題なく起動する。不安定なのはipconfigなの。
    2. 二回連続でしっぱいする(initramfsが表示される)ようならどっか間違ってる。

ブリッジの設定

やっぱり仮想化にはブリッジが便利だよねと言うわけで入れてみる。
sudo apt-get install bridge-utils

問題
  1. これはSANbootでbootディスクが見ている方をブリッジ化しようとするとすぐにフリーズする。
  2. なので、どっちのNICをブリッジにするかは確認して以下のスクリプトを書き直して欲しい。
  3. ちなみに/etc/network/interfaces に通常どおり書くとSANboot自体が失敗するので注意。
  4. で、そのブリッジを自動設定するスクリプトを組んでみる。

sudo nano /etc/network/if-up.d/addip

    1. 内容は以下のとおり
#!/bin/bash

eth="eth0"
br="br0"
mask="255.255.255.0"

cmd="/sbin/ifconfig "${br}" | grep 'inet addr:' | wc -l "

count=`eval ${cmd}`
if [ ${count} -eq 0 ]
then
        cmd="ifconfig "${eth}" 0.0.0.0"
        eval ${cmd}
        sleep 1
        cmd="brctl addbr "${br}
        eval ${cmd}
        cmd="brctl addif "${br}" "${eth}
        eval ${cmd}
        cmd="ifconfig "${br}" up"
        eval ${cmd}
        sleep 10
        cmd="udhcpc -n -i "${br}" "
        eval ${cmd}
        echo ${cmd}
fi
  1. 後処理

$ sudo chmod +x /etc/network/if-up.d/addip
$ sudo -s
# crontab -e

  1. で次の行を追加する。

2 * * * * /etc/network/if-up.d/addip

    1. ※ブリッジでこれはNICが二つある前提なのでもしNICが1個の場合はここではなく、多分initramfsの段階でdhcpしたタイミングで行うしかなさそう。
  1. 起動して数分待つとそこには元気に稼働するbr0が!

プラスアルファ

VMイメージにnfsを使う場合はホスト側にnfs-commonもインストールしておく。

  1. これを忘れているとnfsディスク追加のところでつまづく。あれなんでついかできないんだっけ?みたいな。

sudo apt-get install nfs-common

この方法について

  1. grubさんの設定がいらない
    1. というかudhcpcを使うとgrubの画面が表示されない。→リカバリーモードで起動できない
    2. でもVMとしては起動できるよ!
    3. 最悪そこでgrubのデフォルト起動イメージ指定をリカバリモードにして起動なんかもできなくはない。
    4. SAN bootなので他のマシンからiscsiイニシエーターでマウントしてなども使える。
      1. が、そこでsudo update-initramfs -u -k allなんてやるとなにやら
  2. KVMがどうたら
    1. そうなんだ、Phenomの4コアダイモデルがヤバい。KVMが動かない。6コアモデル大丈夫!
    2. 確認方法は起動したらdmesg | grep KVMでfailなんて単語が出てきたらアウト。もうね。
    3. 原因はKVMカーネルの噛み合わせらしい。だって10.04LTSとか10.10でも古いカーネル(10.04LTS相当)ではOKと言うのが・・・

以上!