vCenterとかないと使えない機能だけど、複数の環境を作りたいときはやっぱりクローンはほしい。
といっても、普通にデータストアにディレクトリ作って、vmdkとvmxをコピペすればいいんだけども、
この場合、vmdkの名称が変更できないのがイケてなかったので、却下。
vmdkの複製はESXiでも出来るので、そこから無理やり設定ファイルを反映させて、インベントリに追加します。
でも、ESXiにsshで入ってコンソール操作しないとだめだし、
複製した仮想ディスクとvmxファイルはインベントリに追加しないと仮想マシンとして動かせないし、
追加後のネットワーク設定はコンソール上で設定しないとだめ、などなど制約はあるけれど。
(上2つに関しては、PerlのSDK使えば出来そうだけど、調べるのがめんどうでやっていない)
(12/06/14:追記)
複製スクリプトの自動化度がレベルアップしました。
ベースとなる仮想マシンを作る。
(設定例) /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0" HWADDR="00:0C:29:4E:A2:65" NM_CONTROLLED="yes" ONBOOT="yes" IPADDR="192.168.11.130" NETMASK="255.255.255.0" GATEWAY="192.168.11.1" BOOTPROTO="static"
あとはミドルウェア入れるなり、VMWareTools入れるなりします。
あと、複製後のネットワーク設定をちょっとラクにするツールを置いておきます。
複製前に入れておくと、複製後にこいつを1回叩けば複製で問題があったネットワーク周りの設定が完了するのでラクです。
使い方は後で説明します。
ethxto0.sh
#!/bin/bash if [ $# -ne 2 ]; then echo "usage: $0 ethX IPADDR" exit 0 fi ETH=$1 IP=$2 # ethXのMACアドレスを取得 MAC_ADDRESS=`ifconfig -a | grep $ETH | awk '{print $5}'` # 取得できないなら、多分必要ない if ["$MAC_ADDRESS" == "" ]; then echo "必要ありません"; exit 0 fi # NICのなにか NET_RULES=/etc/udev/rules.d/70-persistent-net.rules # NICのなにかをバックアップ & 古いものを削除扱いにする(再起動で反映) BAK_SUFFIX=`date +%Y%m%d-%H%m%S`.bak mv $NET_RULES $NET_RULES.$BAK_SUFFIX # ifcfg-eth0の編集...といっても、めんどっちいので、sed置換. MAC_ADDRESSとIPADDRを置き換える echo "updating ifcfg-eth0 ..." IFCFG_ETH0=/etc/sysconfig/network-scripts/ifcfg-eth0 mv $IFCFG_ETH0 $IFCFG_ETH0.$BAK_SUFFIX sed "s/HWADDR=\"[0-9A-Fa-f:]*\"/HWADDR=\"$MAC_ADDRESS\"/" $IFCFG_ETH0.$BAK_SUFFIX | sed "s/IPADDR=\"\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}\"/IPADDR=\"$IP\"/" > $IFCFG_ETH0 # IF再起動 echo "done." reboot
用が済んだらシャットダウンしておきます。
vmdk複製ツールを書く
やるべきことはこのあたりです
vmdk自体にOSとかの情報が入っていて、vmxにCPUとかメモリとかのハードウェアの情報とか、vmdkの位置情報とかいろいろ入ってます。
vmdkはcpするよりも、vmkfstoolsを使ったほうが早くておいしいです。
vmxは単純に複製元のVM名を複製後のVM名へ置き換えます(普通に仮想マシンを作れば問題ないはず)
起動とかのvSphereでやるような操作はだいたいvim-cmdを使うと出来ます。
あと、vmxの修正はVM名について置き換えているだけなので、uuidなどの置き換えは行われていません。
そのためか、初回起動時に「仮想マシンの質問」と評して確認メッセージが出てくるので、
これはコピーしたものです、と答える必要があります。
このへんを全部やる複製スクリプトを書きました。
vmdkclone.sh
#!/bin/sh if [ $# -lt 3 -o $# -gt 4 ]; then echo "usage $0 BASE_VOLUME BASE_VM_HOSTNAME [STORE_VOLUME] VM_HOSTNAME" exit 0 fi OPTION="-d thin" BASE_VOLUME=$1 BASE_VM_HOSTNAME=$2 STORE_VOLUME=$3 VM_HOSTNAME=$4 if [ "$VM_HOSTNAME" == "" ] ; then VM_HOSTNAME="$STORE_VOLUME" STORE_VOLUME="$BASE_VOLUME" fi BASE_DIR="`dirname $BASE_VOLUME`/`basename $BASE_VOLUME`/$BASE_VM_HOSTNAME" BASE_VMDK="$BASE_DIR/$BASE_VM_HOSTNAME.vmdk" STORE_DIR="`dirname $STORE_VOLUME`/`basename $STORE_VOLUME`/$VM_HOSTNAME" STORE_VMDK="$STORE_DIR/$VM_HOSTNAME.vmdk" if [ -e $STORE_DIR ]; then echo "error: exists directory: $STORE_DIR"; exit 1; fi mkdir $STORE_DIR echo "cloning $STORE_VMDK ..." vmkfstools -i "$BASE_VMDK" $OPTION "$STORE_VMDK" echo "copy setting files" cp "$BASE_DIR/$BASE_VM_HOSTNAME.vmx" "$STORE_DIR/$VM_HOSTNAME.vmx" sed -i "s/$BASE_VM_HOSTNAME/$VM_HOSTNAME/g" "$STORE_DIR/$VM_HOSTNAME.vmx" echo "register vm..." vim-cmd "solo/registervm" "$STORE_DIR/$VM_HOSTNAME.vmx" VMID=`vim-cmd vmsvc/getallvms | grep "\[$(basename $STORE_VOLUME)\] $VM_HOSTNAME" | awk '{print $1}'` vim-cmd "vmsvc/power.on" $VMID & echo "waiting VM startup ..." sleep 5; RETRY=5 MSGID= echo "getting Virtual machine message" while [ $RETRY -ne 0 ]; do sleep 3; MSGID=`vim-cmd vmsvc/message $VMID | grep "^Virtual machine message" | awk '{print $4}' | cut -d : -f 1` if [ "$MSGID" != "" ]; then break fi RETRY=`expr $RETRY - 1` done if [ $RETRY -eq 0 ]; then echo "could not get message. VMID=$VMID" exit 0 fi echo "vim-cmd vmsvc/message $VMID $MSGID 2" vim-cmd vmsvc/message $VMID "$MSGID" 2 echo "done."
使い方はこんな感じです。
# TemplateVMと同じデータストアへ、CloneVM1を複製する
/usr/local/bin/vmdkclone.sh /vmfs/volumes/datastore_small1 TemplateVM CloneVM1
# TemplateVMを別データストアのCloneVM2へ複製する
/usr/local/bin/vmdkclone.sh /vmfs/volumes/datastore_small1 TemplateVM /vmfs/volumes/datastore_big1 CloneVM2
空白が入っていたりしても、ダブルクォートで囲めば多分大丈夫。
これで、vmdkの複製からインベントリの追加、起動までやってくれます。
(2013/01/14 同名のゲストOS名を指定すると起動されなかったりするのを修正。)
ネットワーク設定
MACアドレスが変わってしまうので、複製元のときにあったNICがなくなった状態になります。
ネットワーク設定も古いままなので、新しいものに変える必要があります。
変更箇所は以下の2箇所です。
- /etc/sysconfig/network-scripts/ifcfg-eth0
- /etc/udev/rules.d/70-persistent-net.rules
ifcfg-eth0は、ネットワークの設定情報が入ってます(IPとかSUBNETMASKとか)
70-persistent-net.rulesは接続されているNICとその識別名の情報を記録してます。
新しいNICが追加されると、eth1...というように登録されます。
ここで複製前に入れたツールを使います。
NICが1枚であれば、古いeth0と、複製で作られたeth1があるので、eth1をeth0に置き換えます。
# eth1の情報をeth0に置き換え、IPADDRに192.168.11.131を設定する
./ethxto0.sh eth1 192.168.11.131
reboot後、疎通がとれたら完了です。
クローンの挙動とかなり近い感じになってると思います(OSの設定とかやってくれないけど。)