このエントリーをはてなブックマークに追加

yumによるOSイメージ作成

OpenStackで利用するCentOS6.4のOSイメージをyumで作成します。
最後まで行った際に作成されるイメージは、Githubにコミットしています。
cloud-init、ftp、telnet、EPELのリポジトリだけ追加しています。

パッケージのインストール

Ubuntuの場合とCentOSの場合で必要なパッケージが違います。

Ubuntuの場合

仮想イメージをインストールするためのvirtinstとRH系のパッケージ管理コマンドのyumをインストールします。

$ sudo apt-get install virtinst yum -y

CentOSの場合

仮想イメージをインストールするためのpython-virtinstをインストールします。

# yum install python-virtinst

OSイメージの作成

ディストリビューションで違いはありませんがrootで行う必要がありますのでUbuntuの場合はsudoを利用してください。(sudo -iなどとすればrootになれます。)

ディレクトリの作成

# mkdir -p /opt/virt/CentOS6.4
# mkdir /mnt/ec2-ami

仮想マシンのイメージを作成

10Gのrawイメージなので実際に10GByteのディスク領域が必要です。
5Gでも問題無いとは思いますがここでは10Gを指定しています。
# qemu-img create -f raw /opt/virt/CentOS6.4/CentOS6.4.img 10G

仮想マシンのファイルシステムを作成

EXT4でフォーマットしています。

# mke2fs -t ext4 -F -j /opt/virt/CentOS6.4/CentOS6.4.img

仮想マシンのマウント及びデバイスの作成

イメージをループバックマウントしてデバイスを作成します。
UbuntuとCentOSでデバイスを作成するコマンドが若干違います。
# mount -o loop /opt/virt/CentOS6.4/CentOS6.4.img /mnt/ec2-ami
# mkdir /mnt/ec2-ami/dev
# cd /mnt/ec2-ami/dev

Ubuntuの場合

# MAKEDEV consoleonly
# MAKEDEV null

CentOSの場合

# for i in console null zero ; do /sbin/MAKEDEV -d /mnt/ec2-fs/dev -x $i; done

マウント設定ファイルの作成

仮想マシン起動時にマウントするファイルシステムの設定を行います。

# mkdir /mnt/ec2-ami/etc
# cat << FSTAB_AMI | tee /mnt/ec2-ami/etc/fstab > /dev/null
LABEL=uec-rootfs / ext4 defaults 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sda2 /mnt ext3 defaults 0 0
/dev/sda3 swap swap defaults 0 0
FSTAB_AMI

yumの設定

CentOS6.4の場合のyumのコンフィグなのでこの箇所を変更すれば他のバージョンのCentOSもインストールできます。

# cd /mnt/ec2-ami/etc
# cat << YUM_AMI | tee /mnt/ec2-ami/etc/yum-ami.conf > /dev/null
[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
exclude=*-debuginfo
gpgcheck=0
obsoletes=1
reposdir=/dev/null

[base]
name=CentOS Linux - Base
baseurl=http://ftp.jaist.ac.jp/pub/Linux/CentOS/6.4/os/x86_64/
enabled=1
gpgcheck=0

[updates]
name=CentOS-6 - Updates
baseurl=http://ftp.jaist.ac.jp/pub/Linux/CentOS/6.4/updates/x86_64/
enabled=1
gpgcheck=0
YUM_AMI

パッケージのインストール

プロセスをマウントしてyumでパッケージをインストールします。
必要なパッケージがあればここでインストールしておいてもいいでしょう。
# mkdir /mnt/ec2-ami/proc
# mount -t proc none /mnt/ec2-ami/proc
# yum -c /mnt/ec2-ami/etc/yum-ami.conf --installroot=/mnt/ec2-ami -y groupinstall Core
# yum -c /mnt/ec2-ami/etc/yum-ami.conf --installroot=/mnt/ec2-ami -y groupinstall Base

ネットワークの設定

ネットワークの設定を行います。
DNSはGoogleを指定していますので適宜変更してください。
# cat << NIC_AMI | tee /mnt/ec2-ami/etc/sysconfig/network-scripts/ifcfg-eth0 > /dev/null
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
IPV6INIT=no
NIC_AMI

# cat << NETWORKING_AMI | tee /mnt/ec2-ami/etc/sysconfig/network > /dev/null
NETWORKING=yes
NETWORKING_AMI

# cat << DNS_AMI | tee /mnt/ec2-ami/etc/resolv.conf > /dev/null
nameserver 8.8.8.8
DNS_AMI

リポジトリの修正

環境によるのかもしれませんがうまく動作しないためリポジトリを若干修正します。
バージョン指定の部分がうまくいかないです。
# chroot /mnt/ec2-ami cp -p /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.org
# chroot /mnt/ec2-ami sed -i 's/^#baseurl/baseurl/g' /etc/yum.repos.d/CentOS-Base.repo
# chroot /mnt/ec2-ami sed -i 's/$releasever/6.4/g' /etc/yum.repos.d/CentOS-Base.repo

curlのインストール

SSHの鍵を取得するのに必要なためcurlをインストールします。

# chroot /mnt/ec2-ami yum install curl -y

起動スクリプトの作成

KVM用にモジュールを読み込むのと鍵取得用スクリプトの実行を行うように起動スクリプトを作成します。

# cat << RC_LOCAL_AMI | tee -a /mnt/ec2-ami/etc/rc.local > /dev/null
depmod -a
modprobe acpiphp
/usr/local/sbin/get-credentials.sh
RC_LOCAL_AMI

仮想マシンのOS設定

SELinuxの無効化、ファイアウォールの無効化、NTPの自動実行をONの設定をしています。
他にも必要な設定があれば行なっておきましょう。
# chroot /mnt/ec2-ami sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# chroot /mnt/ec2-ami chkconfig ip6tables off
# chroot /mnt/ec2-ami chkconfig iptables off
# chroot /mnt/ec2-ami chkconfig ntpd on

公開鍵取得スクリプトの作成

公開鍵を利用したパス無し認証ログインを行うために必要です。

# cat << CREDS_AMI | tee -a /mnt/ec2-ami/usr/local/sbin/get-credentials.sh > /dev/null
#!/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
CREDS_AMI

スクリプトの実行権限を付与しておきます。

# chmod 755 /mnt/ec2-ami/usr/local/sbin/get-credentials.sh

RAM及びカーネルイメージのコピー

コピーの場所は適宜変更してください。
OpenStackへ登録するためのイメージをコピーしておきます。
# cp /mnt/ec2-ami/boot/initramfs-*.x86_64.img /opt/virt/CentOS6.4
# cp /mnt/ec2-ami/boot/vmlinuz-*.x86_64 /opt/virt/CentOS6.4

イメージのアンマウント

仮想マシンのOSイメージをアンマウントします。

# umount /mnt/ec2-ami/proc
# umount /mnt/ec2-ami

ラベルの変更

OpenStackで利用するために仮想マシンのOSイメージのラベルを変更しておきます。

# tune2fs -L uec-rootfs /opt/virt/CentOS6.4/CentOS6.4.img
以上で仮想マシンのOSイメージ作成は終了です。

仮想マシンのOSイメージをOpenStackへ登録

RAM、KERNEL、OSイメージを3つともに登録して利用します。

RAMイメージをOpenStackへ登録

# cd /opt/virt/CentOS6.4
# glance add name="centos64_ramdisk" is_public=true container_format=ari disk_format=ari < $(ls | grep initram)
# glance image-create --name="centos64_ramdisk" --is-public=true --container-format=ari --disk-format=ari < $(ls | grep initram)

KERNELイメージをOpenStackへ登録

# glance image-create --name="centos64_kernel" --is-public=true --container-format=aki --disk-format=aki < $(ls | grep vmlinuz)

OSイメージをOpenStackへ登録

登録したRAMとKERNELのIDが必要です。
イメージは圧縮しておいたほうが容量削減にもなりますし、イメージ登録や仮想マシンの作成も速いです。
# RAMDISK_ID=$(glance image-list | grep centos64_ramdisk | awk -F"|" '{print $2}' | sed -e 's/^[ ]*//g')
# KERNEL_ID=$(glance image-list | grep centos64_kernel | awk -F"|" '{print $2}' | sed -e 's/^[ ]*//g')

RAWイメージのままでOSイメージを登録

# glance image-create --name="centos64_ami" --is-public=true --container-format=ami --disk-format=ami --property kernel_id=$KERNEL_ID --property ramdisk_id=$RAMDISK_ID < CentOS6.4.img

圧縮してOSイメージを登録

# qemu-img convert -O qcow2 -c CentOS6.4.img CentOS6.4.qcow2
# glance image-create --name="centos64_ami" --is-public=true --container-format=ami --disk-format=ami --property kernel_id=$KERNEL_ID --property ramdisk_id=$RAMDISK_ID < CentOS6.4.img
登録が終了したのでOpenStackから利用できるようになっています。
例えば以下のようにブートします。
$ nova boot --flavor 1 --image centos64_ami  centos64_001 --key_name mykey
但し、rootユーザのパスワードを設定などしていないため公開鍵認証でしかログインできませんので気をつけてください。
もしrootのパスワードを設定する場合は途中で設定しておけばよいでしょう。