• Blog
  • Get Help Now!
  • Customer Portal

BlueGecko Denmark

  • Why you need us
    • Why act now
    • Why are we unique
  • What we do
    • Products Supported 24/7
      • MySQL
      • Postgres
      • SQL Server
      • Open Source
      • OS & Storage
  • How we do it
    • Consulting
    • System Monitoring
    • Security
  • Support
    • Blog
      • Oracle
      • MySQL
      • News & Events
      • Oracle Applications
      • Amazon Web Services
      • Jeremiah Wilton’s Oradeblog
      • OurSQL Community Podcast
      • Remote DBA
    • Team viewer
    • Whitepapers
  • About Us
    • Philosophy
    • The Blue Gecko Teams
    • Employment Opportunities
    • Partners
    • News
    • Press
  • Contact Us

March 2, 2010 by rharwood

EC2 persistent boots with pivot root

Amazon recently allowed Elastic Block Store to boot persistent images. However, there are two concerns I have with the method.

* The EBS boot volumes must be EBS Snapshots, which cost more than regular EBS volumes. (http://aws.amazon.com/ec2/#pricing)
* The EBS boot volumes currently do not work within the Virtual Private Cloud (VPC) infrastructure. (http://aws.amazon.com/vpc/faqs/#45)

To work around these two issues, it is possible to “pivot” from a normal AMI’s local root volume (/dev/sda1) to an arbitrary EBS volume that contains a full OS installation. An additional benefit is that a very small AMI may be used to launch the EBS backed instance, so that the instance launches much faster than a large AMI.

The goal of this post is to provide instructions on how to build a small AMI that is capable of launching a full-blown persistent Linux installation that is backed on EBS storage. BusyBox, “The Swiss Army Knife of Embedded Systems”, provides a solid foundation for our small AMI. To build a BusyBox AMI and an instance backed by EBS, simply follow these directions:

1. Start an instance from an AMI that is running the desired kernel and software configuration. (You can use an existing public AMI or a custom AMI that you created. Personally, I prefer to create my own AMI’s, so I know what is in them.)

2. Log into the instance.

3. Download the latest version of BusyBox.

wget “http://busybox.net/downloads/busybox-1.15.3.tar.bz2”

4. Create a busyroot directory.

mkdir busyroot

5. Extract BusyBox.

bunzip2 busybox-1.15.3.tar.bz2
tar xvf busybox-1.15.3.tar

6. Configure BusyBox. (You can experiment here to reduce the image size, but the configuration listed below works.)

cd busybox-1.15.3
make config
Select “y” for the STATIC option and the default values for everything else.
Build BusyBox as a static binary (no shared libs) (STATIC) [N/y/?] y

7. Make and install BusyBox.

make CONFIG_PREFIX=$HOME/busyroot install
chmod 4755 $HOME/busyroot/bin/busybox

8. Create required directories.

cd $HOME/busyroot
mkdir dev sys etc proc mnt mnt/new-root

9. Create the necessary devices. (We will use /dev/sdj for the EBS volume, but this could be any block device not used by the normal AMI.)

MAKEDEV -d $HOME/busyroot/dev -x sdj
MAKEDEV -d $HOME/busyroot/dev -x console
MAKEDEV -d $HOME/busyroot/dev -x null
MAKEDEV -d $HOME/busyroot/dev -x zero

10. Create the init file.

mv $HOME/busyroot/sbin/init $HOME/busyroot/sbin/init.orig
cat <<‘EOL’ > $HOME/busyroot/sbin/init
#!/bin/busybox sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
NEWDEV=”/dev/sdj”
NEWTYP=”ext3″
NEWMNT=”/mnt/new-root”
OLDMNT=”/mnt/old-root”
OPTIONS=”noatime,ro”
SLEEP=10

echo “Remounting writable.”
mount -o remount,rw /
[ ! -d $NEWMNT ] && echo “Creating directory $NEWMNT.” && mkdir -p $NEWMNT

while true ; do
echo “sleeping…”
sleep $SLEEP
echo “Trying to mount $NEWDEV writable.”
mount -t $NEWTYP -o rw $NEWDEV $NEWMNT || continue
echo “Mounted.”
break;
done

[ ! -d $NEWMNT/$OLDMNT ] && echo “Creating directory $NEWMNT/$OLDMNT.” && mkdir -p $NEWMNT/$OLDMNT

echo “Remounting $NEWMNT $OPTIONS.”
mount -o remount,$OPTIONS $NEWMNT

echo “Trying to pivot.”
cd $NEWMNT
pivot_root . ./$OLDMNT

for dir in /dev /proc /sys; do
echo “Moving mounted file system ${OLDMNT}${dir} to $dir.”
mount –move ./${OLDMNT}${dir} ${dir}
done

echo “Trying to chroot.”
exec chroot . /bin/sh -c “umount ./$OLDMNT; exec /sbin/init $*” < /dev/console > /dev/console 2>&1
EOL

chmod 755 $HOME/busyroot/sbin/init

11. Create the fstab file.

cat <<‘EOL’ > $HOME/busyroot/etc/fstab
/dev/sda1 / ext3 defaults 1 1
none /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
EOL

12. Create a 4MB loopback file.

cd
dd if=/dev/zero of=busybox.fs bs=1M count=4
mkfs.ext3 busybox.fs

13. Mount the loopback file.

mkdir $HOME/busyimg
mount -o loop $HOME/busybox.fs $HOME/busyimg

14. Copy the staged files and directories to the image. (Technically, the BusyBox image could have been built directly in $HOME/busyimg, but we were not sure how big the image was going to be.)

cp -rp $HOME/busyroot/* $HOME/busyimg

15. Un-mount the image.

sync
umount -d $HOME/busyimg

16. Set environment variables.

export EC2_HOME=/opt/ec2-api-tools
export EC2_CERT=/path/to/your/cert.pem
export EC2_PRIVATE_KEY=/path/to/your/pk.pem
export AWS_ACCOUNT_NUMBER=”NNNN-NNNN-NNNN”
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export EC2_BUCKET=”your_bucket”
export JAVA_HOME=/usr/java/default
export ARCH=`uname -i`
export AKI=`curl -s http://169.254.169.254/latest/meta-data/kernel-id`
export ARI=`curl -s http://169.254.169.254/latest/meta-data/ramdisk-id`
export INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
export AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
export SEC_GROUP=`curl -s http://169.254.169.254/latest/meta-data/security-groups`
export PUB_KEY=`wget -q -O – “http://169.254.169.254/latest/meta-data/public-keys” | awk -F= ‘{print $2}’`

17. Bundle the image.

ec2-bundle-image -i $HOME/busybox.fs -d /tmp -k $EC2_PRIVATE_KEY -c $EC2_CERT -u $AWS_ACCOUNT_NUMBER -r $ARCH –kernel $AKI –ramdisk $ARI

18. Upload the image.

ec2-upload-bundle -b $EC2_BUCKET -m /tmp/busybox.fs.manifest.xml -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY

19. Register the AMI.

BUSYBOX_AMI=`ec2-register “$EC2_BUCKET/busybox.fs.manifest.xml” | awk ‘{print $2}’`
echo “BUSYBOX_AMI: $BUSYBOX_AMI”

20. Create an EBS volume of the desired size (10G or more) in the desired availability zone.

VOLUME_ID=`ec2-create-volume -s 10 -z $AVAIL_ZONE | awk ‘{print $2}’`
echo “VOLUME_ID: $VOLUME_ID”

21. Attach the volume to the current instance as /dev/sdj.

ec2-attach-volume $VOLUME_ID -i $INSTANCE_ID -d /dev/sdj

22. Create an EXT3 file system on /dev/sdj.

mkfs.ext3 /dev/sdj

22. Mount the EBS volume.

mkdir /mnt/ebs_boot
mount /dev/sdj /mnt/ebs_boot

23. Copy the current AMI to the EBS volume.

rsync -avHx / /mnt/ebs_boot

24. Fix the /etc/fstab file.

vi /mnt/ebs_boot/etc/fstab
Remove the local file systems.
/dev/sda1 / ext3 defaults 1 1
/dev/sdb /mnt ext3 defaults 1 2
/dev/sda3 swap swap defaults 0 0
Add the /dev/sdj file system.
/dev/sdj / ext3 defaults 1 1

25. Fix the /etc/inittab file. The cloud AMI’s are normally configured for runlevel 4.

vi /mnt/ebs_boot/etc/inittab
Edit the following line if necessary:
id:4:initdefault:

26. Un-mount the EBS volume.

sync
umount /mnt/ebs_boot

27. Detach the volume.

ec2-detach-volume $VOLUME_ID -i $INSTANCE_ID -d /dev/sdj

28. Create a new instance running the BusyBox AMI.

BUSYBOX_ID=`ec2-run-instances $BUSYBOX_AMI -z $AVAIL_ZONE -k $PUB_KEY -g $SEC_GROUP | awk ‘{print $6}’`

29. Wait until the instance is running…

ec2-describe-instances $BUSYBOX_ID

30. Attach the EBS volume to the BusyBox instance as /dev/sdj.

ec2-attach-volume $VOLUME_ID -i $BUSYBOX_ID -d /dev/sdj

31. Reboot the BusyBox instance to make sure it picks up the new device.

ec2-reboot-instances $BUSYBOX_ID

32. Check the BusyBox instance’s console output to make sure it came up as expected.

ec2-get-console-output $BUSYBOX_ID

33. Log into the new EBS backed instance.

That should be it. You now have a persistent instance that is backed by EBS storage!

Filed Under: Amazon Web Services Tagged With: busybox, busyroot, ebs volume, EC2, persistent boot, pivot root

Categories

  • Amazon Web Services
  • Configuration Management
  • downtime
  • Drizzle
  • ebs
  • Education
  • elastic block store
  • elastic compute cloud
  • hosting
  • hot backup
  • ignorance
  • Infrastructure
  • IOUG
  • Jeremiah Wilton's Oradeblog
  • misconception
  • misconceptions
  • Monocle
  • MySQL
  • MySQL Council
  • News
  • News & Events
  • Oracle
  • Oracle APEX
  • Oracle Applications
  • Oracle Data Guard
  • Oracle Database
  • Oracle Database Appliance
  • Oracle Linux
  • Our People
  • OurSQL Community Podcast
  • outage
  • parallel
  • performance
  • podcast
  • proof
  • Remote DBA
  • replication
  • S3
  • Security
  • SQL Server
  • System monitoring
  • Tomcat
  • Uncategorized

Contact Blue Gecko

  • This field is for validation purposes and should be left unchanged.

Get Our Newsletter

  • This field is for validation purposes and should be left unchanged.

The Fine Print

  • Privacy Policy
  • Terms of Use
  • When is remote DBA the right solution
  • What are remote DBA services
  • Get Help

Virtual runs

Blog Categories

  • 24/7 support
  • Blue Gecko 360° Services
  • Products Supported 24/7

Contact Blue Gecko

Blue Gecko A/S
Slotsgade 21
DK – 4200 Slagelse
Denmark
Phone: (DK) +45 70 60 51 20

Networks

  • Email
  • Twitter

© Blue Gecko Group