にゃははー

はへらー

さくらのVPSを借りたので苦労したことを忘れないうちに備忘録

私個人のオレオレconfigなので他の人にはあまり意味がないかもですが、VPS上でxenを動かしたいと思ってる人(特にネットワークとかあんま詳しくない人)は私と同じような状況にあると思うので参考までに。

今回の目標はホストをルータ代わりにして、xenの上にあるゲストで実サービスを提供するというものです。直接的にゲストにつなぐことはできない様にします。この構成の利点はvmでサービスを提供するので鯖移動がイメージファイルの移動で済む点にあります。また、ルータを簡易ファイアウォールとして使用できます。

さくらのVPS自体がkvmで動作してるので我々が直接触れるのはvmm上のゲストですが、やってることがxen on kvmなので用語が混同する可能性がありますので、vmm上のゲストをホストとし、その上のxen上で動いているのをゲストと呼ぶことにします。

ホスト・ゲスト共にCentOS 5.5 x86_64を前提としています。環境に応じて適宜読み替えてください。
また、ゲストが存在するネットワークアドレスを192.168.1.0に、デフォルトゲートウェイを192.168.1.1にします。またDHCPは使用しませんが、後述の設定でこれも有効にすることができます。

xenのインストール

とりあえず先にyum updateでOSを最新にしとく。

※ /etc/yum.repos.d/CentOS-Base.repoを編集すればさらなるカーネルアップデートがかかるのだが、それをしてしまうとカーネルの起動に失敗するだけでなく、コンソールを用いても操作できないレベルで乙るので、ホストはあまりいじらない様にしたほうがいい模様。やはり保守的に。その変わりゲストはいくらでも触れるので好きなようにカスタマイズしてもらって構わない。

で、xenのインストール
http://www.gitco.de/repo/ の下にある.repoを引っ張ってくるわけだが、私のやった限り4.0.1は動いていたので多分問題はない。以下のコマンドを実行。

# cd /etc/yum.repos.d
# wget http://www.gitco.de/repo/GITCO-XEN4.0.1_testing_x86_64.repo
# yum install xen

次に起動するカーネルを変更。vim(コマンドにvimは無いのでviでvimを起動)などで/etc/sysconfig/kernelの

DEFAULTKERNEL=kernel

DEFAULTKERNEL=kernel-xen

に修正。

※ さくらのVPSのデフォルトで入っているCentOSカーネルではxenの起動に失敗する模様。必ずyum updateを行なってください。
※ 追記(20101104): /etc/sysconfig/kernelの修正をxenインストールの前にやるかあとにやるかで/boot/grub/menu.lstが反映されるか変わるっぽいので一応確認して下さい。

ネットワークインターフェイスの設定

xenがデフォルトで幾つか提供しているネットワーク設定を行うスクリプトの使用するスクリプトを変更するので、/etc/xen/xend-config.sxpをvimか何かで編集する。

(network-script network-bridge)
...
(vif-script vif-bridge)

を#でコメントアウトし、

#(network-script network-nat)
#(vif-script vif-nat)

のコメントを外す。

次に、xendが起動している必要があるのでホストの再起動。

まず、デフォルトの設定をベースにするので

# mkdir -p /etc/virnet
# cp /etc/libvirt/qemu/network/default.xml /etc/virnet

でコピー。そしたらコピーしたファイルを適当に修正するわけだが、今回の構成の場合以下のようにする。ただしはそれぞれのデフォルトを使用してもらいたい。

<network>
  <name>default</name>
  <uuid>implementation-define</uuid>
  <bridge name="virbr0" stp="off" forwardDelay='0' />
  <forward mode="nat" dev="eth0" />
  <ip address="192.168.1.1" netmask="255.255.255.0">
<!-- DHCPを利用する場合はこのブロックを有効にする
    <dhcp>
      <range start="implementation-define" end="implementation-define" />
    </dhcp>
-->
  </ip>
</network>
</name>

設定ファイルを書いたらこれらを反映させるので、

# virsh net-destroy default
# virsh net-undefine default
# virsh net-define /etc/virnet/default.xml
# virsh net-start default
# virsh net-autostart default

反映し終わったらifconfigでvirbr0に192.168.1.1が割り当てられていることを確認。

ルーティングの設定

この段階で実はある程度xenがルーティングの設定をしてくれているが、外からゲストに接続するのが無いので、これを加える必要がある。
そのまえに現在の設定を書き出して、バックアップをとっておく。

# iptables-save > /etc/sysconfig/iptables.default
# cp /etc/sysconfig/iptables.default /etc/sysconfig/iptables

/etc/sysconfig/iptables.defaultがバックアップ。/etc/sysconfig/iptablesを編集してルーティングを書き加える。

ルーティングは上から適用されるので、末尾に追加してもあんまり意味はない。とりあえず私のところでは以下のようになった。

 *nat
PREROUTING ACCEPT [374
21215]
POSTROUTING ACCEPT [6
450]
OUTPUT ACCEPT [6
450]
# HTTP server -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.127 # xen default settings -A POSTROUTING -s 192.168.1.0/24 -d ! 192.168.1.0/24 -j MASQUERADE COMMIT *filter
INPUT ACCEPT [996
78620]
FORWARD ACCEPT [0
0]
OUTPUT ACCEPT [576
80602]
# HTTP server -A FORWARD -d 192.168.1.127 -o virbr0 -p tcp --dport 80 -j ACCEPT # xen default settings -A FORWARD -d 192.168.1.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.1.0/24 -i virbr0 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable COMMIT

HTTP serverというコメントの直下の各1行がルーティングに使う部分だ。今回はホストのtcpの80番ポートに来たパケットをゲスト(192.168.1.127)にフォワーディングしている。フォワード先のポートを変えたいとかそう言うことであれば、--to-destination 192.168.1.127:8080とかにすれば8080ポートに転送することができる。
詳しいことはiptablesの解説サイトを参照されたい。

/etc/sysconfig/iptablesを書き終えたなら

# service iptables restart

で設定を反映させる。何事もなくOKがでれば完了だ。もしどこかでFAILと出るなら今一度typoを確認してもらいたい。

ゲストのインストール

ゲストにはインストールが楽なCentOS5.5を用いる。とりあえず

# virt-install --nographics --prompt -p --noapic --noacpi --vcpus=2

とすると対話的にインストールに必要な事項が聞かれるので適当に回答していく。
オプションの意味はGUIを使用せずに(--nographics --prompt)、準仮想化(-p)で、電源関係のインターフェイスを無効に(--noapci --noacpi)。vm上でacpiとか無駄すぎるので。

RAMの容量は256MB以上あればとりあえずは大丈夫だろう。さくらのVPSの場合は200MBぐらいじゃないとそもそもが無いのでインストールできない。まぁCentOSは32MBあれば起動できる優秀なOSだから問題はないだろう。あとでいらないサービスをどんどん削る方向で。
※ 追記(20101104): CentOSの起動自体は100MBあればできるのですが、インストーラのanacondaが200MBぐらい無いと進んでくれないのでインスコ時は200MB程度にしてください。
イメージファイルのインストール先は/var/lib/xen/imagesの下がいいだろう。拡張子は.imgで。
Linuxは窓とかっていうのと違ってOSに1GBも使用しないのでイメージサイズは3〜5GBぐらいあれば問題はないだろう。ストレージ鯖にするのであっても、vm上のストレージへの読み書きは遅くなるのでNFSなりでまた別に用意する方が健全だ。そもそもVPSじゃそんなにストレージ使えないけど。
ディストリのダウンロード元は今回理研を使用させてもらった。アドレスはhttp://ftp.riken.jp/Linux/centos/5.5/os/x86_64だ。大学内や近くにもっと早い鯖があればそっちを使ってもらって構わない。

あとはcentosのインストールを行う今回のネットワーク設定だとIPアドレスを192.168.1.127に固定し、ネットマスクを255.255.255.0に、ゲートウェイは192.168.1.1にする。
DNSはホストの/etc/resolv.confを見ても構わないし、覚えやすい8.8.8.8(Googleに感謝)を使わせてもらっても構わない。(が、知り合いの某氏によると、「鯖にpublic DNSを使うのは負けた気がする」だそうだ。)

ネットワークが正しく動作していれば滞りなくインストールは行われるだろう。インストールが終わり、起動したらサービスやらSELinuxやらのことを聞かれるが好きなように設定してもらって構わない。強いて言うならsshdは切ってもいいかもしれない。というのもxenのコンソール経由で操作できるからだ。無駄にポート開いて脆弱にする理由もないし、なんと言ってもメモリを浪費したくない。

ここで重要なことがある。私もはまってしまって困った。どうやらcentosはデフォルトでiptablesファイアウォールを設定するらしい。これによってフォワーディングされたパケットがゲストの外に流れなかった。つまり外からするとパケットが帰ってこない。ホストのiptablesをいくらいじっても無理なはずだ。
つまり/etc/sysconf/iptablesにルールを書けばいいわけだが、現在はホストがファイアウォールになってるので多分大丈夫だろうと思い、私は設定を全て消した。読者はコメントアウトするなりルールの追加なりをしてもらえば問題ない。

あとはよしなに。

とりあえずここまででxenのインストールからvmのインストール、ネットワークの設定を一通り行なった。xenの操作は難しく、ここで説明するのも面倒なので適当に探して欲しい。また、ホストと同時にゲストも立ちあげたいところだが、私がうまく出来ていないので割愛させていただく。
とりあえずホストのsshdのポート変更や/etc/ssh/sshd_configの設定をまっさきにしておくといいだろう。