Oracle Linux 5 のカスタムAMIを作る(EC2)

検証によく使ってたAMI Oracle Linux 5.6 x86_64 - Amazon Xen (ami-72bf0873)が残念ながら、消されてしまったようです。
それどころか、現在VPCで使えるタイプ(非OVMタイプ)のOracle Linux AMIが見つかりません。
Oracle Linux 5.6/Oracle Linux 6.1を最後に非OVMタイプのAMIの公開が止まっていたので、
なんだか嫌な予感がしつつ使い続けていたのですが、非常に残念です。


Oracle RAC on Amazon EC2自体は、RedHat Linuxインスタンスでもできるので、なんとかなるのですが、
RedHat Linuxインスタンスは残念ながら、spotインスタンスが使えません。
それだと検証用の費用がかさんでしまうので、
Oracle Linux 5 のカスタムAMIを作ってみることにします。


手順自体は、様々な方がCentOSのカスタムAMI作成手順を公開してくださっているので、
Oracle Linuxもほとんど一緒)そこまで大変ではありませんが、適当にやるとハマります。


ポイントは以下の3つです。


rpmデータベースのバージョンに注意
 rpmデータベースはRedhat/CentOS/OracleLinux 5系と6系でバージョンが異なります。
 Amazon Linux(CentOS6と一部互換?)で5系のカスタムAMIを作ろうとするとrpmデータベースのバージョンが異なるため、手間が増えます。


xen用のドライバを組み込んでinitrdを作成する必要がある。
 yumでkernelをインストールするとあまり意識しないのですが、(kernelインストールの延長でinitrdも作られるため)、
 xen用のドライバを組み込まないと、bootできないAMIになってしまいます。



ssh 公開鍵の読み込み
 EC2では基本的にsshは公開鍵/秘密鍵で接続しますので、公開鍵をAMIインスタンスに読み込ませる仕組みが必要です。


前置きが長くなりましたが、以下手順です。

1. 作業用のAMIインスタンスとして、 ami-3d7cc63c(RedHat 5.9 x86_64)を起動。/dev/sdbに12GB割り当てる。
上述のとおり、rpmデータベースのバージョンが絡むのでOracle Linux 5系と同じRedHat 5.xを作業用のAMIインスタンスとします。
t1.microで構いません。


2.以下のようなシェルを作成し、実行
すいません。時間がまた足りなくなったので、細かい解説端折ります。
ポイントだけコメントいれてます。

create_oraclelinux.sh

#!/bin/sh
mkfs.ext3 -F -L / /dev/sdb

mkdir /mnt/ami
mount -t ext3 /dev/sdb /mnt/ami
/sbin/MAKEDEV -d /mnt/ami/dev -x console
/sbin/MAKEDEV -d /mnt/ami/dev -x null
/sbin/MAKEDEV -d /mnt/ami/dev -x zero
mkdir /mnt/ami/etc
cp /etc/fstab /mnt/ami/etc
mkdir /mnt/ami/proc
mount -t proc none /mnt/ami/proc
mkdir /mnt/ami/etc/yum.repos.d/
mv /etc/yum.repos.d /etc/yum.repos.d.bak
curl -L -o /mnt/ami/etc/yum.repos.d/public-yum-el5.repo http://public-yum.oracle.com/public-yum-el5.repo
cp /etc/yum.conf /mnt/ami/etc/
yum -c /mnt/ami/etc/yum.repos.d/public-yum-el5.repo --installroot=/mnt/ami/ -y groupinstall Core Base

#modprobe.confにxen用のドライバを記載しておくと、kernel-xenインストールの延長で作成されるinitrdにもドライバが組み込まれる
cat > /mnt/ami/etc/modprobe.conf <<EOF
alias eth0 xennet
alias scsi_hostadapter xenblk
EOF
yum -c /mnt/ami/etc/yum.repos.d/public-yum-el5.repo --installroot=/mnt/ami/ -y install kernel-xen
yum -c /mnt/ami/etc/yum.repos.d/public-yum-el5.repo --installroot=/mnt/ami/ -y remove kernel

cat /etc/sysconfig/network-scripts/ifcfg-eth0 > /mnt/ami/etc/sysconfig/network-scripts/ifcfg-eth0
cat /etc/hosts > /mnt/ami/etc/hosts
cat /etc/sysconfig/network > /mnt/ami/etc/sysconfig/network
sed -i "s/enforcing/disabled/" /mnt/ami/etc/sysconfig/selinux
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

#redhat linuxAMIでは、rc.localで/root/.ssh/authorized_keysがなければ、ssh公開鍵の読み込みをする作りになっているが、
#(1度AMIを作成したら、公開鍵は2度と変わらないことを想定)。今回作成のAMIをベースに色々カスタマイズする予定なので、毎回公開鍵を読み込み直すようにする。
cat /etc/rc.local > /mnt/ami/etc/rc.local
sed -i '/# Fetch public key using HTTP$/a rm -rf /root/.ssh/authorized_keys' /mnt/ami/etc/rc.local

cat  > /mnt/ami/boot/grub/menu.lst <<EOF
default=0
timeout=0
hiddenmenu

title oracle linux
root (hd0)
kernel /boot/`ls /mnt/ami/boot | grep vmlinuz` ro root=LABEL=/
initrd /boot/`ls /mnt/ami/boot | grep initrd`
EOF

sync;sync;sync;


3.マネジメントコンソールにて/dev/sdbのvolumeからからスナップショットを作成する。


4.マネジメントコンソールにて作成したスナップショットから、「create image from snapshot」を実行
その際、Architectureはx86_64,Kernel IDはaki-44992845、Root Device Nameは/dev/sda1、Ramdisk IDはdefaultを指定する。


iscsiとの競合のからみもあるので、本当は、Root Device Nameは/dev/sde1あたりにしたかったのですが、
それだと、何故かc1.mediumが起動してこないので、/dev/sda1にしています。


このカスタムAMIをベースにOracle RACの作成は出来たので、
検証に使う分には大丈夫だと思います。(ご利用は計画的に)


参考文献
http://blog.cloudpack.jp/2011/08/aws-news-suz-lab-centos-ami-600.html
http://sandbox4me.org/2012/03/create-ami-for-centos5/
http://gmt-24.net/archives/892
http://d.hatena.ne.jp/zsiarre/20121118/1353247925