サーバ大量構築時のキモ ~VMware ESXiの自動インストール 初期設定自動化バージョン~

以前、Kickstartを用いてVMware ESXi 5.5の自動インストールを行ったが、今回は更に「%firstboot」でスクリプトを実行させることで導入時の初期設定を同時に行わせる事にした。

導入時の初期設定といっても多々あるので、今回は以下の内容を初期設定内容と仮定して進める。

  1. インストールは一つ目として認識されるディスクに行う
  2. NICが2ポートあり、それぞれにvSwitchが接続される(vmnic0にvSwitch0、vmnic1にvSwitch1が接続され、チーミングは行われない)
  3. 各vSwitchにはESXiのマネジメントポートおよび仮想マシンのポートグループが1つ接続される
  4. SSHは有効とする
  5. IPアドレスは各筐体ごとに固定の静的IPアドレスを設定する

とりあえずこんなところだろうか。

1.下準備

とりあえず、まずは下準備としてスクリプトに各筐体の違いを認識させるため、サーバ筐体のBIOSのUUIDを取得しホストの一覧を作成する。 BIOSのUUIDについては、こちらのスクリプトを用いてIPMI経由で取得するか、工場から一覧をもらうなどしてもらいたい。

その上で、各vmknicに割り当てるIPアドレスを記述したhost.listを作成する。まぁ、LinuxやWindowsの筐体ごとに違う固定IPアドレスを割り当てるスクリプトで使っているものと同じなんだけど…。 以下にサンプルを作成したので掲載。なお、NIC数が変動する場合はこのリストと後述するスクリプトの修正が必要なので注意。

●host.list

hostname,serialno,defaultgw,nic0,nic1
Test-ESXi001,564D33C9F632AB40148800E9CA90D059,192.168.0.1,192.168.0.31/24,172.26.0.31/24
Test-ESXi002,564DAB560AE59CD285EDCFE97F5A9E64,192.168.0.1,192.168.0.32/24,172.26.0.32/24
Test-ESXi003,564DF163D810265B56707D081C45716F,192.168.0.1,192.168.0.33/24,172.26.0.33/24
Test-ESXi004,564DC8A6D8F477D20B15335663B0FB98,192.168.0.1,192.168.0.34/24,172.26.0.34/24
Test-ESXi005,4DA8DC674CF8B9F1D63C00224D377953,192.168.0.1,192.168.0.35/24,172.26.0.35/24
Test-ESXi006,564D9239403DE9D51BEB3C6800D5A883,192.168.0.1,192.168.0.36/24,172.26.0.36/24

2.スクリプトファイルの作成

次に、インストール後に実行させるスクリプトファイルを作成する。 今回は、vSwitchの作成などの基本的な設定を行う「setip1.sh」と、host.listに基づき各サーバの固定IPアドレスを設定する「setip2.sh」の2種類を作成する。

まずは「setip1.sh」から。

●setip1.sh

#!/bin/sh
# This Script is VMware ESXi Set Config Script
######################################################
# 1. Enable SSH
# 2. Enable ESX Shell
# 3. Create vSwitch
######################################################

######################################################
# 1.Enable SSH
######################################################
vim-cmd hostsvc/enable_ssh
vim-cmd hostsvc/start_ssh

######################################################
# 2.Enable ESX Shell
######################################################
vim-cmd hostsvc/enable_esx_shell
vim-cmd hostsvc/start_esx_shell

######################################################
# 3.Create vSwitch
######################################################
esxcfg-vswitch -a vSwitch1
esxcfg-vswitch -A "VM Network 1" vSwitch1
esxcfg-vswitch -A "Management Network 1" vSwitch1
esxcfg-vswitch -L vmnic1 vSwitch1

次に「setip2.sh」。

#!/bin/sh
# This Script is VMware ESXi Set Config Script
######################################################
# Set IP Address fpr vmknic
######################################################

cidr2mask ()
 {
 # Number of args to shift, 255..255, first non-255 byte, zeroes
 set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
 [ $1 -gt 1 ] && shift $1 || shift
 echo ${1-0}.${2-0}.${3-0}.${4-0}
}

######################################################
# Set IP Address for vmknic
######################################################

# Set Var
LIST=./host.list
NIC0=vmknic0
NIC1=vmknic1

NIC0PORTG="Management Network"
NIC1PORTG="Management Network 1"

# Get UUID
GUID=`smbiosDump | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/"`

GUID_16=`echo $GUID | cut -c1-2`
GUID_15=`echo $GUID | cut -c3-4`
GUID_14=`echo $GUID | cut -c5-6`
GUID_13=`echo $GUID | cut -c7-8`
GUID_12=`echo $GUID | cut -c9-10`
GUID_11=`echo $GUID | cut -c11-12`
GUID_10=`echo $GUID | cut -c13-14`
GUID_09=`echo $GUID | cut -c15-16`
GUID_08=`echo $GUID | cut -c17-18`
GUID_07=`echo $GUID | cut -c19-20`
GUID_06=`echo $GUID | cut -c21-22`
GUID_05=`echo $GUID | cut -c23-24`
GUID_04=`echo $GUID | cut -c25-26`
GUID_03=`echo $GUID | cut -c27-28`
GUID_02=`echo $GUID | cut -c29-30`
GUID_01=`echo $GUID | cut -c31-32`

UUID=`echo $GUID_01$GUID_02$GUID_03$GUID_04$GUID_05$GUID_06$GUID_07$GUID_08$GUID_09$GUID_10$GUID_11$GUID_12$GUID_13$GUID_14$GUID_15$GUID_16`

# Get HostName,IP Address,Default Gateway
HOSTNAME=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $1 }'`
GATEWAY=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $3 }'`

# NIC0
NIC0_IPADDR=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC0_PREFIX=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC0_SUBNET=`cidr2mask $NIC0_PREFIX`

# NIC1
NIC1_IPADDR=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC1_PREFIX=`cat $LIST | grep $UUID | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC1_SUBNET=`cidr2mask $NIC1_PREFIX`

cd /tmp/

esxcli system hostname set --host="$HOSTNAME"
esxcfg-route -a default $GATEWAY

esxcfg-vmknic    -i $NIC0_IPADDR -n $NIC0_SUBNET -p "$NIC0PORTG"
esxcfg-vmknic -a -i $NIC1_IPADDR -n $NIC1_SUBNET -p "$NIC1PORTG"

/sbin/services.sh restart

これらのファイルは、インストールDVDの「/work」フォルダに設置する。

3.キックスタート定義ファイルの作成

キックスタートの定義ファイルとして、「ks.cfg」というファイルを作成する。

#
 # Sample scripted installation file
 #
 # Accept EULA
 vmaccepteula
 # Set root password
 rootpw password
 #Install on local disk overwriting any existing VMFS datastore
 install --firstdisk --overwritevmfs
 # Network configuration
 network --bootproto=dhcp --device=vmnic0

 # Reboot after installation completed
 reboot --noeject

 %firstboot --interpreter=busybox
 vmkload_mod iso9660
 /sbin/vsish -e set /vmkModules/iso9660/mount mpx.vmhba32:C0:T0:L0
 cp -r /vmfs/volumes/CDROM/WORK/ /vmfs/volumes/datastore1/
 mv /vmfs/volumes/datastore1/WORK/SETIP1.SH /tmp/setip1.sh
 mv /vmfs/volumes/datastore1/WORK/SETIP2.SH /tmp/setip2.sh
 mv /vmfs/volumes/datastore1/WORK/HOST.LIS /tmp/host.list
 rm -r /vmfs/volumes/datastore1/WORK
 cd /tmp
 sh /tmp/setip1.sh
 sh /tmp/setip2.sh
 reboot

ポイントとなるのは16行目から。 内容の解説は以下。

%firstboot --interpreter=busybox

"最初に起動した際に、以下の処理を実行させる"という指定。

vmkload_mod iso9660
/sbin/vsish -e set /vmkModules/iso9660/mount mpx.vmhba32:C0:T0:L0
cp -r /vmfs/volumes/CDROM/WORK/ /vmfs/volumes/datastore1/

14行目の指定で、インストール完了後もディスクをリジェクトしないように指定している。 スクリプトファイルをコピーするため、再起動後に再度CD-ROMをマウントし「/WORK」配下のファイル全てを「/vmfs/volumes/datastore1/」にコピーしている。

mv /vmfs/volumes/datastore1/WORK/SETIP1.SH /tmp/setip1.sh
mv /vmfs/volumes/datastore1/WORK/SETIP2.SH /tmp/setip2.sh
mv /vmfs/volumes/datastore1/WORK/HOST.LIS /tmp/host.list
rm -r /vmfs/volumes/datastore1/WORK

「/vmfs/volumes/datastore1/」に設置したファイルを「/tmp」にリネームし移動している。 移動後、包括的にコピーした「/vmfs/volumes/datastore1/WORK」は削除している。

cd /tmp
sh /tmp/setip1.sh
sh /tmp/setip2.sh

ファイルをコピーした「/tmp」フォルダに移動し、各スクリプトを実行している。

4.インストールディスクの作成

上記で作成したファイルを用いて、インストールディスクを作成する。 ディスクの作成方法及び「isolinux.cfg」の内容については以前書いたこちらの内容と同一のため、割愛する。

5.インストール実行

後は、作成した自動インストールディスクを用いてインストールを実行するだけだ。

なお、検証は自宅に保有しているESXi上の仮想マシンにて行っている。 その他物理サーバについては、UUIDの順序入れ替え方法が異なるため、検証機を用いてアルゴリズムを確認して順序を入れ替えてもらいたい。

一例として、自宅にあったPRIMERGY RX 100 S6 でのソースを以下に示す。 なお、この順序はIPMIから一括取得させるスクリプトの順序に合わせている。

# Get UUID
GUID=`smbiosDump | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/"`

GUID_11=`echo $GUID | cut -c1-2`
GUID_10=`echo $GUID | cut -c3-4`
GUID_09=`echo $GUID | cut -c5-6`
GUID_08=`echo $GUID | cut -c7-8`
GUID_07=`echo $GUID | cut -c9-10`
GUID_06=`echo $GUID | cut -c11-12`
GUID_05=`echo $GUID | cut -c13-14`
GUID_04=`echo $GUID | cut -c15-16`
GUID_03=`echo $GUID | cut -c17-20`
GUID_02=`echo $GUID | cut -c21-24`
GUID_01=`echo $GUID | cut -c25-32`

UUID=`echo $GUID_01$GUID_02$GUID_03$GUID_04$GUID_05$GUID_06$GUID_07$GUID_08$GUID_09$GUID_10$GUID_11`
echo $UUID

このUUIDの取得アルゴリズムについては、他のOSでも同様に順序入れ替えが違う可能性が高いので、実際に利用する際は一度検証だけは行ってもらいたい。