Apr 152012
 

CentOS 5.0 x86_64のAMIベースになるディスクイメージを作成してみました。

最初Amazon Linuxでも使われているcloud-initをrpm化してインストールしておこうと思ったのですが、Python2.6の敷居が思いのほか高く、ssh鍵の配置のみrc.localに記述する方式にしています。
CentOS 6以上ならrpm化してcloud-initを入れておくと便利だと思います。

■2012/12/03追記:cloud-initはEPELリポジトリでパッケージが提供されています。手元の環境(CentOS 5.2)で使えました。

  1. 作業用のCentOS 5.0環境を準備(VMware Player上に用意)
  2. ディスクイメージファイルを作成してCentOS 5.0を最小構成インストール
  3. PV-GRUBでブートできるようにinitrdやgrub.confを構成

作成したディスクイメージファイルをEBSに書き出してスナップショットからEBSなAMIを作成することもきますし、そのままInstance StoreなAMIを作成することもできます。
作業用のCentOS 5環境をAWS上に用意できれば、ディスクイメージファイルではなく直接EBSボリュームに構築することもできます。

今回参考にした情報は以下です。
From a Loopback – Amazon Elastic Compute Cloud
AWS Developer Forums: CentOS 5, ID# ami-07ca2f6e, can not SSH …
Enabling Your Own Linux Kernels – Amazon Elastic Compute Cloud

作業用ディレクトリ作成
ディスクイメージ配置用に~/ami、ディスクイメージマウント先は/mnt/ec2-fsを作成します。

[root@localhost ~]# mkdir ~/ami /mnt/ec2-fs

ディスクイメージ準備
2GBのディスクイメージを作成して、フォーマット後ループバックマウントします。

[root@localhost ~]# dd if=/dev/zero of=ami/centos-5-0-x86_64-core.img bs=1M count=2048
[root@localhost ~]# mke2fs -F -j ami/centos-5-0-x86_64-core.img
[root@localhost ~]# mount -o loop ami/centos-5-0-x86_64-core.img /mnt/ec2-fs

yumインストール用の設定ファイルを作成
5.0素の最小構成しますので、baseリポジトリのみ有効(updatesは無効)にしています。
5.0のリポジトリは既にvaultに移っていますので、baseurlではそちらを指定します。

[root@localhost ~]# vi ami/centos-5-0-x86_64-yum.conf
[root@localhost ~]# cat ami/centos-5-0-x86_64-yum.conf
[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
exclude=*-debuginfo
gpgcheck=0
obsoletes=1
reposdir=/dev/null

[base]
name=CentOS-5.0 - Base
baseurl=http://vault.centos.org/5.0/os/x86_64/

[updates]
name=CentOS 5.0 - Updates
baseurl=http://vault.centos.org/5.0/updates/x86_64/
enabled=0

必要最低限のパッケージをインストール
パッケージグループCoreとkerel-xen、そしてssh鍵の配置に必要なcurlをインストールします。curlインストール時はi386パッケージがインストールされないよう、curl.x86_64と指定しています。

[root@localhost ~]# yum -c ami/centos-5-0-x86_64-yum.conf --installroot=/mnt/ec2-fs -y groupinstall Core
[root@localhost ~]# yum -c ami/centos-5-0-x86_64-yum.conf --installroot=/mnt/ec2-fs -y install kernel-xen
[root@localhost ~]# yum -c ami/centos-5-0-x86_64-yum.conf --installroot=/mnt/ec2-fs -y install curl.x86_64

クリーンアップ

[root@localhost ~]# yum -c ami/centos-5-0-x86_64-yum.conf --installroot=/mnt/ec2-fs clean all

デバイスファイルの作成

[root@localhost ~]# /mnt/ec2-fs/sbin/MAKEDEV -d /mnt/ec2-fs/dev -c /mnt/ec2-fs/etc/makedev.d -x console
[root@localhost ~]# /mnt/ec2-fs/sbin/MAKEDEV -d /mnt/ec2-fs/dev -c /mnt/ec2-fs/etc/makedev.d -x null
[root@localhost ~]# /mnt/ec2-fs/sbin/MAKEDEV -d /mnt/ec2-fs/dev -c /mnt/ec2-fs/etc/makedev.d -x zero

/etc/fstab作成
mkinitrdでのinitrd生成時に、fstabの記述に従ってrootパーティションのマウント指定が決定されます。

[root@localhost ~]# vi /mnt/ec2-fs/etc/fstab
[root@localhost ~]# cat /mnt/ec2-fs/etc/fstab
/dev/sda1       /               ext3    defaults,noatime        1 1
devpts          /dev/pts        devpts  gid=5,mode=620          0 0
tmpfs           /dev/shm        tmpfs   defaults                0 0
proc            /proc           proc    defaults                0 0
sysfs           /sys            sysfs   defaults                0 0

/etc/modprobe.conf作成
mkinitrdでのinitrd生成時にxennetとxenblkが含まれるようにモジュールの記述を追加します。

[root@localhost ~]# cat >> /mnt/ec2-fs/etc/modprobe.conf << EOF
alias eth0 xennet
alias scsi_hostadapter xenblk
EOF
[root@localhost ~]# tail -2 /mnt/ec2-fs/etc/modprobe.conf
alias eth0 xennet
alias scsi_hostadapter xenblk

initrdを生成
chrootしてmkinitrdします。

[root@localhost ~]# chroot /mnt/ec2-fs /bin/bash
[root@localhost /]# mkinitrd initrd.new 2.6.18-8.el5xen
[root@localhost /]# mv initrd.new /boot/initrd-2.6.18-8.el5xen.img
[root@localhost /]# exit

/boot/grub/grub.conf作成
EBS内のkernelで起動できるように用意しておきます。

[root@localhost ~]# vi /mnt/ec2-fs/boot/grub.conf
[root@localhost ~]# cat /mnt/ec2-fs/boot/grub.conf
default=0
timeout=0
hiddenmenu
title CentOS (2.6.18-8.el5xen)
        root (hd0)
        kernel /boot/vmlinuz-2.6.18-8.el5xen ro root=/dev/sda1
        initrd /boot/initrd-2.6.18-8.el5xen.img
[root@localhost ~]# cd /mnt/ec2-fs/boot
[root@localhost boot]# ln -s grub.conf menu.lst
[root@localhost boot]# cd

/etc/hosts作成

[root@localhost ~]# vi /mnt/ec2-fs/etc/hosts
[root@localhost ~]# cat /mnt/ec2-fs/etc/hosts
127.0.0.1               localhost.localdomain localhost

/etc/sysconfig/network作成

[root@localhost ~]# vi /mnt/ec2-fs/etc/sysconfig/network
[root@localhost ~]# cat /mnt/ec2-fs/etc/sysconfig/network
NETWORKING=yes

/etc/sysconfig/network-scripts/ifcfg-eth0作成

[root@localhost ~]# vi /mnt/ec2-fs/etc/sysconfig/network-scripts/ifcfg-eth0
[root@localhost ~]# cat /mnt/ec2-fs/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
IPV6INIT=no

/etc/resolv.conf作成

[root@localhost ~]# touch /mnt/ec2-fs/etc/resolv.conf

SELinux無効化
/etc/selinux/configのSELINUXをdisabledに変更します。

[root@localhost ~]# vi /mnt/etc/selinux/config
[root@localhost ~]# grep ^SELINUX= /mnt/etc/selinux/config
SELINUX=disabled

/usr/local/sbin/get-credentials.sh作成

[root@localhost ~]# vi /mnt/ec2-fs/usr/local/sbin/get-credentials.sh
[root@localhost ~]# chmod 700 /mnt/ec2-fs/usr/local/sbin/get-credentials.sh
[root@localhost ~]# chown 0:0 /mnt/ec2-fs/usr/local/sbin/get-credentials.sh
[root@localhost ~]# cat /mnt/ec2-fs/usr/local/sbin/get-credentials.sh
#!/bin/bash

# Retreive the credentials from relevant sources.

# Fetch any credentials presented at launch time and add them to
# root's public keys

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
PUB_KEY_FROM_EPHEMERAL=/mnt/openssh_id.pub
ROOT_AUTHORIZED_KEYS=/root/.ssh/authorized_keys



# We need somewhere to put the keys.
if [ ! -d /root/.ssh ] ; then
        mkdir -p /root/.ssh
        chmod 700 /root/.ssh
fi

# Fetch credentials...

# First try http
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 "ec2"
    fi
    chmod 600 $ROOT_AUTHORIZED_KEYS
    rm -f $PUB_KEY_FROM_HTTP

elif [ -e $PUB_KEY_FROM_EPHEMERAL ] ; then
    # Try back to ephemeral store if http failed.
    # NOTE: This usage is deprecated and will be removed in the future
    if ! grep -q -f $PUB_KEY_FROM_EPHEMERAL $ROOT_AUTHORIZED_KEYS
    then
            cat $PUB_KEY_FROM_EPHEMERAL >> $ROOT_AUTHORIZED_KEYS
            echo "New key added to authrozied keys file from ephemeral store"|logger -t "ec2"

    fi
    chmod 600 $ROOT_AUTHORIZED_KEYS
    chmod 600 $PUB_KEY_FROM_EPHEMERAL

fi

if [ -e /mnt/openssh_id.pub ] ; then
        if ! grep -q -f /mnt/openssh_id.pub /root/.ssh/authorized_keys
        then
                cat /mnt/openssh_id.pub >> /root/.ssh/authorized_keys
                echo "New key added to authrozied keys file from ephemeral store"|logger -t "ec2"

        fi
        chmod 600 /root/.ssh/authorized_keys
fi

/etc/rc.localにget-credentials.sh実行を追加

[root@localhost ~]# cat >> /mnt/ec2-fs/etc/rc.local <<EOF
# Get your chosen keypair credentials
/usr/local/sbin/get-credentials.sh
EOF
[root@localhost ~]# tail -2 /mnt/ec2-fs/etc/rc.local
# Get your chosen keypair credentials
/usr/local/sbin/get-credentials.sh

ディスクイメージのアンマウント

[root@localhost ~]# umount /mnt/ec2-fs

AMI化するところは別途。

Sorry, the comment form is closed at this time.