SUZ-LAB謹製 CentOS AMI (6.0.0 32bit ap-northeast-1)で紹介したように、久しぶりに「0」からAMIを作成したので、作り方をメモしておきます。

○EC2の起動とAMI作成イメージ用EBSの作成&アタッチ

はじめに、いろいろと参考になる下記のRHEL-6.0でEC2を起動しておきます。

そしてCentOS 6.0のイメージとなるEBSを下記のように作成してアタッチします。

ここでは、/dev/sdb1でアタッチしてますが、RHEL-6.0では、/dev/xvdb1となっているので注意が必要です。

○EBS(/dev/xvdb1)にファイルシステム(ext4)を作成

アタッチしたEBS(/dev/xvdb1)を下記のように、mkfs.ext4を利用してファイルシステムを作成します。

# ls /dev/xvdb1
/dev/xvdb1

# mkfs.ext4 /dev/xvdb1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
393216 inodes, 1572864 blocks
78643 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1610612736
48 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

Writing inode tables: done                           
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 31 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

○EBS(/dev/xvdb1)をマウントしてデバイスファイルを作成

上記のEBS(/dev/xvdb1)を適当なディレクトリにマウントし、その中に、下記の通りデバイスファイルを作成します。

# mkdir /mnt/ami

# mount -t ext4 /dev/xvdb1 /mnt/ami/

# /sbin/MAKEDEV -d /mnt/ami/dev -x console
MAKEDEV: mkdir: File exists
MAKEDEV: mkdir: File exists

# /sbin/MAKEDEV -d /mnt/ami/dev -x null

# /sbin/MAKEDEV -d /mnt/ami/dev -x zero

# ls /mnt/ami/dev/
console  null  tty  zero

○/etc/fstabを作成してprocファイルシステムをマウント

下記のように、/mnt/ami/etc/fstabを作成し、/mnt/ami/procにprocにファイルシステムをマウントします。

# mkdir /mnt/ami/etc

# cat /mnt/ami/etc/fstab
/dev/xvda1  /         ext4    defaults        1 1
none        /proc     proc    defaults        0 0
none        /sys      sysfs   defaults        0 0
none        /dev/pts  devpts  gid=5,mode=620  0 0
none        /dev/shm  tmpfs   defaults        0 0

# mkdir /mnt/ami/proc

# mount -t proc none /mnt/ami/proc

○yumでCentOS 6.0のパッケージ(Core)とカーネルをインストール

CentOS 6.0用のyum.confを作成し、yumでCoreパッケージをインストールし、User Provided Kernelで利用するカーネルもインストールしておきます。

# mv /etc/yum.repos.d /etc/yum.repos.d.bak

# yum clean all
Loaded plugins: amazon-id, security
Cleaning up Everything

# cat /mnt/yum.conf
[base]
name=CentOS-6 - Base
baseurl=http://mirror.centos.org/centos/6/os/i386/
[updates]
name=CentOS-6 - Updates
baseurl=http://mirror.centos.org/centos/6/updates/i386/

# yum -c /mnt/yum.conf --installroot=/mnt/ami/ -y groupinstall Core

# cp /mnt/ami/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 /etc/pki/rpm-gpg/

# yum --installroot=/mnt/ami/ -y install kernel

○User Provided Kernelの設定(/boot/grub/menu.lst)

上記のカーネルを利用するように/mnt/ami/boot/grub/menu.lstの記述を下記のように設定します。

下記のカーネルイメージ(AKI)を利用すると/boot/grub/menu.lstに記載された、ユーザーが提供するカーネルが利用されます。

pv-grub-hd0_1.02-i386.gz.manifest.xml

# cat /mnt/ami/boot/grub/menu.lst
default=0
timeout=0
hiddenmenu
title SUZ-LAB CentOS 6
root (hd0)
kernel /boot/vmlinuz-2.6.32-71.29.1.el6.i686 ro root=/dev/xvda1
initrd /boot/initramfs-2.6.32-71.29.1.el6.i686.img

○ネットワークの設定

ネットワークの設定は、下記のようにDHCPを利用するようにし、IPv6は無効にします。

# cat /mnt/ami/etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=localhost.localdomain

# cat /mnt/ami/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=on

# cat /mnt/ami/etc/hosts
127.0.0.1   localhost localhost.localdomain

○SELinuxの設定

SELinuxは、下記のように無効にしておきます。

# cat /mnt/ami/etc/sysconfig/selinux
SELINUX=disabled
SELINUXTYPE=targeted

○SSHの設定

起動時にAWSから公開鍵を取得し、事前に作成した秘密鍵でログインできるようにし、sshdの設定も秘密鍵でしかログインできないようにしておきます。

cat /mnt/ami/etc/rc.local
...
# For AWS
PUB_KEY_URI=http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
PUB_KEY_FROM_HTTP=/tmp/openssh_id.pub
ROOT_AUTHORIZED_KEYS=/root/.ssh/authorized_keys
curl --retry 3 --retry-delay 0 --silent --fail -o $PUB_KEY_FROM_HTTP $PUB_KEY_URI
if [ $? -eq 0 -a -e $PUB_KEY_FROM_HTTP ] ; then
    if ! grep -q -f $PUB_KEY_FROM_HTTP $ROOT_AUTHORIZED_KEYS
    then
        cat $PUB_KEY_FROM_HTTP >> $ROOT_AUTHORIZED_KEYS
        echo "New key added to authrozied keys file from parameters" | logger -t "aws"
        dd if=/dev/urandom count=50 | md5sum | passwd --stdin root
        echo "The root password randomized" | logger -t "aws"
    fi
    chmod 600 $ROOT_AUTHORIZED_KEYS
    rm -f $PUB_KEY_FROM_HTTP
fi

# cp -r /root/.ssh /mnt/ami/root/

# cat /mnt/ami/root/.ssh/authorized_keys

# cat /mnt/ami/etc/ssh/sshd_config
...
PermitRootLogin without-password
PasswordAuthentication no
UseDNS no
...

○アンマウントとスナップショットの取得

上記で作成したEBSをAMI作成用のスナップショット取得のため、下記のようにアンマウントし、EBSをEC2からデタッチして、スナップショットを取得します。
(デタッチとスナップショットはAWS Management Consoleで実施しました)

# umount /mnt/ami/proc

# umount /mnt/ami

○AMIの作成(登録)

上記で作成したスナップショット(snap-951eb8fe)を指定し、下記PHPスクリプトにてAMIを作成(登録)します。

require_once("/opt/aws/php/sdk.class.php");

define("AWS_KEY"       , "AAAAAAAA");
define("AWS_SECRET_KEY", "XXXXXXXX");

$ec2 = new AmazonEC2();
$ec2->set_region(AmazonEC2::REGION_APAC_NE1);

$response = $ec2->register_image(array(
    "Name"               => "suz-lab_ebs_centos-core-i386-6.0.0",
    "Architecture"       => "i386",
    "KernelId"           => "aki-ec5df7ed",
    "RootDeviceName"     => "/dev/sda1",
    "BlockDeviceMapping" => array(
        array(
            "DeviceName" => "/dev/sda1",
            "Ebs"        => array(
                "SnapshotId" => "snap-951eb8fe"
            )
        )
    )
));

var_dump($response);

カーネルID(AKI)も上記で紹介した、pv-grub-hd0_1.02-i386.gz.manifest.xml(aki-ec5df7ed)を指定します。
上記のカーネル(AKI)はリージョン、プラットフォームごとにIDが違うので、User Provided Kernelで使うpv-grub-hd0/00が1.02にアップデートにまとめておきました。

下記のように、AWS Management Consoleで確認できれば成功です。

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら