サーバ大量構築時のキモ ~シリアルコードからIPアドレスを自動設定するスクリプト~

以前、hostnameを引数にIPアドレスを自動的に設定するスクリプトを作成したが、今回はそれをより自動化させた。
基板の持つシリアルコードから各筐体の判断を行わせ、ただコマンドを実行するだけで個別のIPアドレスを実行させるようにする。

1.実現するには

さて、んじゃ実際どうすればいいのか?
まず問題になるのが、各筐体の違いを、OSはどのように認識すればいいのか。

今回は、各対象サーバの持つシリアルコードを利用して違いを認識させる事にした。
このシリアルコードをLinuxが認識するには、「dmidecode」コマンドを利用すれればいい。

「dmidecode」コマンドでは、以下のように入力する事でシリアルコートを確認出来る。

dmidecode -t system | grep "Serial Number:" | awk -F: '/Serial Number/{sub(/^ */,"",$2);s=sprintf("%s,\"%s\"",s,$2)}/^Memory/{print s;s=""}END{print s}' |sed -e 's/,//' | grep -iv "no module" | tr -d ' '

実際に、VMware上のCentOSで実行した結果がこちら。

[root@localhost ~]# dmidecode -t system | grep "Serial Number:" | awk -F: '/Serial Number/{sub(/^ */,"",$2);s=sprintf("%s,\"%s\"",s,$2)}/^Memory/{print s;s=""}END{print s}' |sed -e 's/,//' | grep -iv "no module" | tr -d ' '
"VMware-564da93251495f97-98fc7ec19a2642eb"
[root@localhost ~]#

もしくは、UUIDから取得させる。
UUIDの取得の場合は以下。

dmidecode | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed -e "s/-//g"

実際にCentOSで実行した結果がこちら。

[root@localhost ~]# dmidecode | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed -e "s/-//g"
564DA93251495F9798FC7EC19A2642EB
[root@localhost ~]#

…やっぱ、今回はUUIDから取得させよう。
今回は、このコマンドを用いたスクリプトを作成して、それをKickstartでインストール後に実行させることで自動的に固定IPアドレスの設定を行わせる。

2.スクリプト

さて、それではまずシリアルコードと紐付けてホスト名、IPアドレスを設定させるスクリプトを作成する。
スクリプトは、再利用を考えて外部ファイルとスクリプトファイルの構成にする。

まずは外部ファイルから。
1列目に設定したいホスト名、2列目にシリアルコードを入れる。
3列目にデフォルトゲートウェアを入れ、以降は各NICに設定するIPアドレスだ。

host.list

hostname,serialno,defaultgw,nic0,nic1
Test-CentOS001,564D33C9F632AB40148800E9CA90D059,192.168.0.1,192.168.0.31/24,172.26.0.31/24
Test-CentOS002,564DAB560AE59CD285EDCFE97F5A9E64,192.168.0.1,192.168.0.32/24,172.26.0.32/24
Test-CentOS003,564DF163D810265B56707D081C45716F,192.168.0.1,192.168.0.33/24,172.26.0.33/24

次はスクリプトファイル。

●ipset.sh

#!/bin/sh
LIST="./host.list"
NIC0="eth0"
NIC1="eth1"

SCRIPT_DIR=`dirname $0`
cd $SCRIPT_DIR

MYSERIAL_CD=`dmidecode | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed -e "s/-//g"`

IFCFGNIC0="ifcfg-${NIC0}"
IFCFGNIC1="ifcfg-${NIC1}"

if [ -z `cat $LIST | grep $MYSERIAL_CD` ]; then
    echo "It did not exist in [$ LIST] within [$ MYSERIAL_CD]"
    echo ""
    exit 1
fi

#Host Name
HOSTNAME=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $1 }'`

#Default Gateway
GATEWAY=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $3 }' | awk 'BEGIN {FS="/"} {print $1}'`

#NIC0
NIC0_IPADDR=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC0_PREFIX=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC0_HWADDR=`ifconfig $NIC0 | grep HWaddr | awk '{print $5}'`

#NIC1
NIC1_IPADDR=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC1_PREFIX=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC1_HWADDR=`ifconfig $NIC1 | grep HWaddr | awk '{print $5}'`

#create ifcfg-*
cd /etc/sysconfig/network-scripts

#ifcfg-NIC0
echo "DEVICE=$NIC0" > $IFCFGNIC0
echo "TYPE=Ethernet" >> $IFCFGNIC0
echo "ONBOOT=yes" >> $IFCFGNIC0
echo "NM_CONTROLLED=yes" >> $IFCFGNIC0
echo "BOOTPROTO=none" >> $IFCFGNIC0
echo "IPADDR=$NIC0_IPADDR" >> $IFCFGNIC0
echo "PREFIX=$NIC0_PREFIX" >> $IFCFGNIC0
echo "GATEWAY=$GATEWAY" >> $IFCFGNIC0
echo "DEFROUTE=yes" >> $IFCFGNIC0
echo "IPV4_FAILURE_FATAL=yes" >> $IFCFGNIC0
echo "IPV6INIT=no" >> $IFCFGNIC0
echo "NAME=\"System $NIC0\"" >> $IFCFGNIC0
echo "HWADDR=$NIC0_HWADDR" >> $IFCFGNIC0

#ifcfg-NIC1
echo "DEVICE=$NIC1" > $IFCFGNIC1
echo "TYPE=Ethernet" >> $IFCFGNIC1
echo "ONBOOT=yes" >> $IFCFGNIC1
echo "NM_CONTROLLED=yes" >> $IFCFGNIC1
echo "BOOTPROTO=none" >> $IFCFGNIC1
echo "IPADDR=$NIC1_IPADDR" >> $IFCFGNIC1
echo "PREFIX=$NIC1_PREFIX" >> $IFCFGNIC1
echo "DEFROUTE=yes" >> $IFCFGNIC1
echo "IPV4_FAILURE_FATAL=yes" >> $IFCFGNIC1
echo "IPV6INIT=no" >> $IFCFGNIC1
echo "NAME=\"System $NIC1\"" >> $IFCFGNIC1
echo "HWADDR=$NIC1_HWADDR" >> $IFCFGNIC1

#Network Restart
/etc/init.d/network restart

cd /etc/sysconfig
echo "NETWORKING=yes" > network
echo "HOSTNAME=$HOSTNAME" >> network
echo "GATEWAY=$GATEWAY" >> network

3.スクリプトの実行

さて、それでは実際にスクリプトを実行してみる。

[root@localhost ~]# sh /home/ipset.sh
インターフェース eth0 を終了中: デバイスの状態: 3 (切断済み)
[ OK ]
インターフェース eth1 を終了中: デバイスの状態: 3 (切断済み)
[ OK ]
ループバックインターフェースを終了中
[ OK ]
ループバックインターフェイスを呼び込み中
[ OK ]
インターフェース eth0 を活性化中: アクティブ接続の状態: アクティベート済み
アクティブ接続のパス: /org/freedesktop/NetworkManager/ActiveConnection/2
[ OK ]
インターフェース eth1 を活性化中: アクティブ接続の状態: アクティベート済み
アクティブ接続のパス: /org/freedesktop/NetworkManager/ActiveConnection/3
[ OK ]
[root@localhost ~]#

再起動後、ホスト名が「Test-CentOS001」になっている事が確認出来た。

これで、”シリアルコードさえあれば”一気に構築を進める事が可能になるだろう。

なお、今回のスクリプトはCentOSで開発した。そのため、Ubuntu等のDebian系では少し手を加える必要があるだろう。