Как известно, в облаке Amazon виртуальные инстансы запускаются на основе образов (так называемые AMI). Amazon предоставляет большое их количество, также можно использовать публичные образы, подготовленные сторонними организациями, за которые облачный провайдер, естественно, никакой ответственности не несёт. Но иногда нужен образ чистой системы с нужными параметрами, которого нет в списке образов. Тогда единственный выход — сделать свой AMI.
В официальной документации описан способ создания «instance store-backed AMI». Минус такого подхода заключается в том, что готовый образ нужно будет ещё и сконвертировать в «EBS-backed AMI»
О том, как создать свой EBS-backed AMI в облаке Amazon без промежуточных шагов, пойдёт речь в этой статье.
План действий:
- Подготовить окружение
- Установить чистую систему, сделать необходимые настройки
- Сделать snapshot (слепок) диска
- Зарегистрировать AMI
Подготовка окружения
Для наших целей подойдёт любой инстанс любого шейпа, хоть t1.micro. Запустить его можно через CLI:
aws ec2 run-instances --image-id ami-1624987f --max-count 1 --min-count 1 --key-name mel --instance-type t1.micro
Создадим ebs-volume, куда установим позднее нашу систему:
aws ec2 create-volume --availability-zone us-east-1a --size 10
Эта команда сделает для нас диск размером 10 Gb. Важно: диск должен быть в той же зоне, что и инстанс (в нашем случае это us-east-1a).
Далее диск нужно прикрепить к инстансу:
aws ec2 attach-volume --instance-id i-2bc0925b --volume-id vol-08ab3079 --device /dev/xvdf
Теперь залогинимся на инстанс по ssh, отформатируем диск и примонтируем его в директорию:
mkfs.ext3 /dev/xvdf
mkdir /mnt/centos-image
mount /dev/xvdf /mnt/centos-image
cd !$
Установка чистого Centos 5.9
Перед установкой системы нужно создать дерево каталогов, примонтировать proc и sysfs, создать минимальный набор устройств:
mkdir centos-image/{boot,tmp,dev,sys,proc,etc,var}
mount -t proc none /mnt/centos-image/proc/
mount -t sysfs none /mnt/centos-image/sys/
for i in console null zero ; do /sbin/MAKEDEV -d /mnt/centos-image/dev -x $i ; done
Устанавливать систему будем при помощи yum и следующего конфигурационного файла:
[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.9 - Base
mirrorlist=http://mirrorlist.centos.org/?release=5.9&arch=x86_64&repo=os
#baseurl=http://mirror.centos.org/centos/5.9/os/x86_64/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
[updates]
name=CentOS-5.9 - Updates
mirrorlist=http://mirrorlist.centos.org/?release=5.9&arch=x86_64&repo=updates
#baseurl=http://mirror.centos.org/centos/5.9/updates/x86_64/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
[extras]
name=CentOS-5.9 - Extras
mirrorlist=http://mirrorlist.centos.org/?release=5.9&arch=x86_64&repo=extras
#baseurl=http://mirror.centos.org/centos/5.9/extras/x86_64/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-5
[centosplus]
name=CentOS-5.9 - Plus
mirrorlist=http://mirrorlist.centos.org/?release=5.9&arch=x86_64&repo=centosplus
#baseurl=http://mirror.centos.org/centos/5.9/centosplus/x86_64/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-5
[contrib]
name=CentOS-5.9 - Contrib
mirrorlist=http://mirrorlist.centos.org/?release=5.9&arch=x86_64&repo=contrib
#baseurl=http://mirror.centos.org/centos/5.9/contrib/x86_64/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-5
yum -c ~/yum-centos.conf --installroot=/mnt/centos-image/ -y groupinstall Base
После завершения процесса установки, таким же образом, можно установить любые необходимые пакеты:
yum -c ~/yum-centos.conf --installroot=/mnt/centos-image/ install $packet_name
Отредактируем fstab:
vi /mnt/centos-image
/dev/xvda1 / ext3 defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
В CentOS 5.9 ещё нужно установить ядро с поддержкой xen:
yum -c ~/yum-centos.conf --installroot=/mnt/centos-image/ -y install kernel-xen
Установим Grub:
chroot /mnt/centos-image/ grub-install /dev/xvdf
и сгенерируем новый initrd:
chroot /mnt/centos-image/
cd boot/
mkinitrd --omit-scsi-modules --with=xennet --with=xenblk --fstab=/etc/fstab --preload=xenblk initrd-2.6.18-348.1.1.el5xen.img 2.6.18-348.1.1.el5xen
При этом очень важно указать все эти параметры и новый fstab, иначе система не загрузится.
Далее нужно создать файл menu.lst для grub:
default=0
timeout=5
hiddenmenu
title CentOS_5.9_(x86_64)
root (hd0)
kernel /boot/vmlinuz-2.6.18-348.1.1.el5xen ro root=/dev/xvda1
initrd /boot/initrd-2.6.18-348.1.1.el5xen.img
Настроим сеть и sshd:
vi etc/sysconfig/network-scripts/ifcfg-eth0
ONBOOT=yes
DEVICE=eth0
BOOTPROTO=dhcp
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
IPV6INIT=no
vi etc/sysconfig/network
NETWORKING=yes
chroot /mnt/centos5img/ chkconfig --level 2345 network on
vi /mnt/centos5img/etc/ssh/sshd_config
...
UseDNS no
PermitRootLogin without-password
Таким образом, мы получим работающую сеть и возможность логиниться на инстанс по ключам. Но, сам ключ нужно как-то прокинуть на инстанс. Это можно сделать при помощи скрипта, который будет забирать ключ и сохранять его на инстансе:
vi /mnt/centos5img/etc/init.d/ec2-get-ssh
# chkconfig: 2345 95 20
# processname: ec2-get-ssh
# description: Capture AWS public key credentials for EC2 user
# Source function library
. /etc/rc.d/init.d/functions
# Source networking configuration
[ -r /etc/sysconfig/network ] &&. /etc/sysconfig/network
# Replace the following environment variables for your system
export PATH=:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
# Check that networking is configured
if [ "${NETWORKING}" = «no» ]; then
echo «Networking is not configured.»
exit 1
fi
start() {
if [! -d /root/.ssh ]; then
mkdir -p /root/.ssh
chmod 700 /root/.ssh
fi
# Retrieve public key from metadata server using HTTP
curl -f 169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /tmp/my-public-key
if [ $? -eq 0 ]; then
echo «EC2: Retrieve public key from metadata server using HTTP.»
cat /tmp/my-public-key >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
rm /tmp/my-public-key
fi
}
stop() {
echo «Nothing to do here»
}
restart() {
stop
start
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $«Usage: $0 {start|stop|restart}»
exit 1
esac
exit $?
Сделаем его исполняемым и добавим в автозагрузку:
chmod +x /mnt/centos-image/etc/init.d/ec2-get-ssh
/usr/sbin/chroot /mnt/centos-image/ /sbin/chkconfig --level 34 ec2-get-ssh on
Ещё желательно отключить Selinux, либо правильно настроить его. Иначе, например, может не сохраниться ключ на инстансе.
На этом можно настройку системы прекратить. Мы уже имеем чистый CentOS, готовый к запуску в облаке. Осталось только отмонтировать ebs-диск с нашей системой и зарегистрировать ami.
umount /mnt/centos-image/proc/
umount /mnt/centos-image/sys/
umount /mnt/centos-image/
Регистрация AMI
Чтобы получить из ebs-диска ami, нужно сделать сначала снапшот диска:
aws ec2 create-snapshot --volume-id vol-0b4bd07a --description centos-snap
А зарегистрировать ami проще всего через AWS Management Console. Для этого нужно просто в сервисе EC2 перейти в раздел «Snapshots», выбрать нужный (в нашем случае это centos-snap), кликнуть на него правой кнопкой и выбрать «Create Image from Snapshot»
Затем, в открывшемся окне, нужно выбрать примерно следующие параметры:
Какой Kernel ID выбрать, можно узнать так:
aws ec2 describe-images --owner amazon --region us-east-1 --output text | grep "/pv-grub-hd0.*-x86_64" | awk '{print $7}' | grep aki
aki-88aa75e1
aki-b4aa75dd
На этом все. Теперь можно запускать инстансы.
Таким способом можно сделать образ, скорее всего, с любым Linux-дистрибутивом. По карйней мере, точно Debian- (используя debootstrap для установки чистой системы) и Rhel-семейства.
Автор: morkot