Install Alpine on Amazon EC2: Difference between revisions

From Alpine Linux
No edit summary
No edit summary
 
(20 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{Draft}}
{{Move| Alpine Install: from a image to a Amazon EC2 instance |This article need wikiformating consisten with setups procedure and naming formating.}}


The goal here is to have a "1GB" (the smallest possible) EBS 'virtual usb stick' that can boot and run Alpine Linux.
EC2 instances are available in a variety of [https://aws.amazon.com/ec2/instance-types/ different sizes] with different specifications but all of them currently run on one of two types of virtualization technology: [https://en.wikipedia.org/wiki/Paravirtualization paravirtualization] (PV) or [https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine hardware virtual machine] (HVM).


= Create a Virtual USB in EBS =
PV instances boot with a special boot loader called PV-GRUB, which starts the boot cycle and then chain loads the kernel specified in the menu.lst file on your image. Paravirtual guests can run on host hardware that does not have explicit support for virtualization, but they cannot take advantage of special hardware extensions such as enhanced networking or GPU processing.


{{Note|You need to do this process at least once in each availability region. EBS can't be shared between Ireland and California, for instance.}}
HVM instances are presented with a fully virtualized set of hardware and boot by executing the master boot record of the root block device of your image. This virtualization type provides the ability to run an operating system directly on top of a virtual machine without any modification, as if it were run on the bare-metal hardware. The Amazon EC2 host system emulates some or all of the underlying hardware that is presented to the guest. (from: [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/virtualization_types.html Linux AMI Virtualization Types]).


# Create an Amazon instance in the desired availabity region.  A micro instance is fine - we will need it only long enough to create our EBS usb stick.
Only older instance types support PV instances, all new instance types use an HVM hypervisor. For the purposes of setting up Alpine Linux on EC2 this mainly impacts the way the bootloader is configured.
# Create a new EBS volume


EC2 instances are created from templates called Amazon Machine Images (AMI). AMIs are built using existing running instances and then are turned into AMIs using a snapshot process. Note that an AMI is region specific so you must either follow this guide in each region you plan to deploy Alpine Linux instances or you must copy the AMI using either the console or the AWS command line client to each region you plan to use.


All instance types are 64-bit. 32-bit images will not work.


Just transcribing notes from the mailing list.
This guide will create the smallest possible (1GB) EBS-backed image which acts as a virtual USB stick that will boot and run Alpine Linux. 
= Initial Setup =
All AMI creation tasks follow the same set of setup steps which require a running Linux instance and an attached EBS volume. The Linux instance will only be used to set up the root filesystem for your Alpine Linux system so any distro works, Amazon Linux is the default so, where relevant, this guide will use that distro.


<pre>
# Create an EC2 instance, t2.micro running Amazon Linux should suffice
Date: Sun, 27 May 2012 09:00:47 -0700
# Create a 1GB EBS volume and attach it to the instance as {{Path|/dev/sdf}} (this will appear on an HVM instance as {{Path|/dev/xvdf}})
From: Nathan Angelacos <nangel@alpinelinux.org>
# Format the disk as ext4, there is no need to partition the drive: {{Cmd|mkfs.ext4 /dev/xvdf}}
Subject: [alpine-devel] Notes on Alpine 2.4.2 in Amazon EC2
# Mount the drive to the host: {{Cmd|mkdir /mnt/target && mount /dev/xvdf /mnt/target}}
# Fetch a copy of the latest virt release: {{Cmd|curl -o /tmp/alpine-release.iso https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-virt-3.7.0-x86_64.iso}}
# Mount the release iso: {{Cmd|mkdir /mnt/source && mount -o loop /tmp/alpine-release.iso /mnt/source}}
# Copy the files to the target {{Cmd|cp -av /mnt/source/boot /mnt/target}}


Just some notes on trying to get Alpine Linux running on an EC2 instance.
The sudo package is not included in the on-disk repository for the virt image which means that it will not be accessible for installation at system boot time; to enable this you will need a copy of the repository from the extended image. Download this image and copy the <tt>apks</tt> folder to the target.


As of 27 May 2012, The Amazon Linux AMI includes pv-grub, so trying an
# Fetch a copy of the latest extended release: {{Cmd|curl -o /tmp/alpine-extended-release.iso https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-extended-3.7.0-x86_64.iso}}
alternate kernel is fairly simple:
# Mount the release iso: {{Cmd|mkdir /mnt/source-extended && mount -o loop /tmp/alpine-extended-release.iso /mnt/source-extended}}
# Copy the files to the target {{Cmd|cp -av /mnt/source-extended/apks /mnt/target}}


* Start the instance (its some variant of redhat)
Because the packages on Amazon Linux are a little older than the ones that ship with Alpine and because you will be creating an apkovl file for initial system configuration, you will either need an existing Alpine Linux system or a copy of the minirootfs image into which you can chroot. To set up a chroot:
* wget the alpine iso and copy the /boot and /apk directories to the
EC2  instance /
* create a apkovl.tar.gz that includes the ssh public keys, starts
openssh, etc.; place the apkovl in /


# Fetch a copy of the latest minirootfs release: {{Cmd|curl -o /tmp/alpine-minirootfs.tar.gz https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-minirootfs-3.7.0-x86_64.tar.gz}}
# Unpack the root fs: {{Cmd|mkdir /tmp/alpine-chroot && tar -C /tmp/alpine-chroot -xvf /tmp/alpine-minirootfs.tar.gz}}
# Copy the system resolv.conf into the chroot so you will have internet access: {{Cmd|cp /etc/resolv.conf /tmp/alpine-chroot/etc}}


The /boot/grub/grub.conf looks like this:
= Create an Apkovl File =
The top level of the EBS volume will be scanned during boot for files named <tt>*.apkovl.tar.gz</tt> and the first one that is found will be unpacked and overlayed onto the file system. The goal of this archive is to configure the system so that you will be able to login after the system boots. At a minimum this means:


default=0
* Configure networking to use dhcp and start when the system boots
fallback=1
* Install an SSH daemon
timeout=3
* Configure a user with your SSH keys
hiddenmenu
* Enable sudo so that you can gain root access


title Alpine Linux
Set up the chroot and chroot into it, then add any desired packages. The <tt>busybox-initscripts</tt> package provides the required files for udhcpc which will allow DHCP to be enabled. The <tt>syslinux</tt> package is required to install the boot-loader but is not required on the final system.
root (hd0)
kernel /boot/grsec alpine_dev=xvda1:ext4
modules=loop,squashfs,sd-mod,ext4 console=hvc0
initrd /boot/grsec.gz


<pre>
mkdir /tmp/alpine-chroot/mnt/target
mount -o bind /mnt/target /tmp/alpine-chroot/mnt/target
mount -t proc none /tmp/alpine-chroot/proc
mount -t devtmpfs none /tmp/alpine-chroot/dev
mount -t sysfs none /tmp/alpine-chroot/sys


title Amazon Linux AMI (PV)
chroot /tmp/alpine-chroot sh
root (hd0)
kernel /boot/vmlinuz-3.2.12-3.2.4.amzn1.i686 root=LABEL=/ console=hvc0
initrd /boot/initramfs-3.2.12-3.2.4.amzn1.i686.img


apk update


----
#If using older version 3.7.x, use:
apk add alpine-conf sudo openssh busybox-initscripts syslinux


What doesn't work:
# If using Alpine 3.8+, the package "busybox-initscripts" is replaced by "busybox-mdev-openrc"
apk add alpine-conf sudo openssh busybox-mdev-openrc syslinux
</pre>


The Alpine init system will start up the core required services if the file {{Path|/etc/.default_boot_services}} exists, so create that.


* Booting the 32bit kernel reports:
<pre>
  ERROR: Invalid kernel: 'elf_xen_note_check: ERROR: Will only load
touch etc/.default_boot_services
images built for the generic loader or Linux images
</pre>
  xc_dom_oparse_image returned -I


Set up networking:


http://wiki.alpinelinux.org/wiki/Talk:Create_Alpine_Linux_PV_DomU says
<pre>
that's because the kernel uses PVOps and its running on 64 bit
cat > /etc/network/interfaces <<EOF
hardware.
auto lo
iface lo inet loopback


auto eth0
iface eth0 inet dhcp
EOF


ln -s /etc/init.d/networking /etc/runlevels/default/
ln -s /etc/init.d/sshd /etc/runlevels/default/
</pre>


* Booting the 64bit kernel reports:
Add a user, set an SSH key, and ensure that this user can sudo:
  can only boot x86 32 PAE kernels, not xen-3.0-x86_64
  Error 13: Invalid or unsupported executable format


<pre>
adduser -D -s /bin/sh alpine
addgroup alpine wheel


Date: Tue, 29 May 2012 17:09:56 +0200
mkdir /home/alpine/.ssh
From: Natanael Copa <ncopa@alpinelinux.org>
chmod 700 /home/alpine/.ssh
Subject: {SPAM 01.5} Re: [alpine-devel] Notes on Alpine 2.4.2 in Amazon EC2
chown alpine /home/alpine/.ssh
cat > /home/alpine/.ssh/authorized_keys <<EOF
... your ssh public key(s) ...
EOF
chmod 600 /home/alpine/.ssh/authorized_keys
chown alpine:alpine /home/alpine/.ssh/authorized_keys


On Sun, 27 May 2012 09:00:47 -0700
passwd -u alpine
Nathan Angelacos <nangel@alpinelinux.org> wrote:


> * Booting the 64bit kernel reports:
sed -i '/%wheel/s/^# //' /etc/sudoers
>    can only boot x86 32 PAE kernels, not xen-3.0-x86_64
</pre>
>    Error 13: Invalid or unsupported executable format
>


I built a kernel dedicated for virtual guests. One of the goals is to
Exclude backup files and any files that are going to exist in the unpacked image. Then create an apkovl bundle.
make it as small as possible. I have no idea if it even boots at this
point but feedback is welcome.


I'd like it to include drivers for qemu/kvm, xen, vmware, virtualbox
<pre>
and hyper-v guests.
lbu exclude \
    etc/group- etc/passwd- etc/shadow- \
    etc/apk/keys etc/apk/arch etc/apk/repositories \
    etc/os-release \
    etc/issue \
    etc/alpine-release
lbu include /home/alpine/.ssh
lbu package amazon.apkovl.tar.gz
</pre>


It is in edge/testing and is named linux-virt-grsec.
Verify that everything you expect to be in the apovl file is there and if not you can [[Manually_editing_a_existing_apkovl|modify the apkovl]].


Thanks!
Finally, copy the apkovl to {{Path|/mnt/target}}.


-nc
<pre>
cp amazon.apkovl.tar.gz /mnt/target
</pre>


= EBS Backed HVM AMI =
For HVM instances you will need to install a boot-loader. Any bootloader should do the trick but this guide will use syslinux because it's fast and small and you don't have to support any odd hardware or system layout.


> Can we see a bootable iso in edge/releases or a wiki help page on how
First you will need to ensure that the ext4 driver is loaded and may as well shorten the timeout to speed instance boot time.
> to create one. It would be great to have a lighter iso suited for
> virtual guests. I could test using kvm and install/test pmreader on
> it. (http://insteps.net/pr/a/pmwiki/Apps/PmReader-help-v1-1)


I built one for testing
{{Cmd|sed -i \
http://dev.alpinelinux.org/~ncopa/alpine/alpine-virt/
    -e '/usb-storage/s//usb-storage,ext4/' \
    -e '/^TIMEOUT/s/20/2/' \
    /mnt/target/boot/syslinux/syslinux.cfg}}


>
Finally, install the bootloader: {{Cmd|extlinux -i /mnt/target/boot}}
> Thanks.


I think kernel config might needs some tweaking still.
= EBS Backed PV AMI =
For PV AMIs PV-GRUB will attempt to read {{Path|/boot/grub/menu.lst}} to load the kernel. First create a {{Path|/boot/grub/grub.conf}}:


-nc
<pre>
mkdir -p /mnt/target/boot/grub


cat > target/boot/grub/grub.conf <<EOF
default=0
timeout=2
hiddenmenu


Date: Thu, 31 May 2012 18:56:29 -0700
title Alpine Linux
From: Nathan Angelacos <nangel@alpinelinux.org>
root (hd0)
Subject: Re: [alpine-devel] Notes on Alpine 2.4.2 in Amazon EC2
kernel /boot/vmlinuz-virthardened alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/vmlinuz-virthardened
initrd /boot/initramfs-virthardened
EOF


Thanks to all for the help - Alpine Linux is now live in the Amazon
ln -s /mnt/target/boot/grub/grub.conf /mnt/target/boot/grub/menu.lst
EC2 cloud. The following isn't pretty (no prepackaged AMI or
</pre>
anything) - more like duct-tape and fishing line - but its a start.


Pre setup:
= Create the AMI =
  * Set up a local box so that it does
The following will need to be done in the AWS console.
    * dhcp on eth0
    * starts sshd
    * put your public key in /root/.ssh/authorized_keys
    * set the root password
    * lbu include root/.ssh
    * You may wish to delete the /etc/ssh/*key* files, so that they
are created  on the new box
  * lbu package amazon.apkovl.tar.gz
    * IMPORTANT:  If you are building this on a 32bit box, delete
etc/apk/arch from the apkovl.tar.gz file


* Create an instance, use Amazon Linux, *64bit* version
# Detach the new volume (make note of the volume ID)
* Copy the amazon.apkovl.tar.gz to the instance
# Launch a new instance, use the defaults; you are going to cannibalize it in a moment
* Log in, sudo
# Once the instance starts, stop but do not terminate it
* Move the apkovl.tar.gz to /
# Under EBS, detach the existing volume, and attach the Alpine Linux volume as {{Path|/dev/xvda}} (for HVM) or {{Path|/dev/sda1}} (for PV)
* wget the latest alpinelinux *x86_64* iso. 32bit won't work
# Restart the instance
* Copy alpinelinux to the EBS harddrive
# Log in and make sure it works
  * mkdir x;
# Do any final cleanups necessary. Only make changes appropriate for an AMI, you are going to snapshot this instance and use it as the base for the AMI.
  * mount alpine*.iso x -o loop
# Stop but do not terminate the instance
  * cd x
# Right click the stopped instance and choose 'Create Image (EBS AMI)'
  * cp -av apks /
# Once the AMI creation finishes you can cleanup the instances and EBS volumes used
  * cp boot/* /boot
  * cd
* Edit the /boot/grub/grub.conf so that it looks something like this:
 
> default=0
> fallback=1
> timeout=3
> hiddenmenu
>
> title Alpine Linux
> root (hd0)
> kernel /boot/grsec alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/grsec
> initrd /boot/grsec.gz
>
>
> title Amazon Linux AMI (PV)
> root (hd0)
> kernel /boot/vmlinuz-3.2.12-3.2.4.amzn1.i686 root=LABEL=/ console=hvc0
> initrd /boot/initramfs-3.2.12-3.2.4.amzn1.i686.img
 
  * syslinux automatically adds the BOOT_IMAGE to the kernel command
line; grub does not.
 
* Reboot
</pre>


[[Category:Virtualization]]
[[Category:Virtualization]]

Latest revision as of 17:51, 24 September 2024

This page is proposed for moving ...

It should be renamed to [[ Alpine Install: from a image to a Amazon EC2 instance ]]. This article need wikiformating consisten with setups procedure and naming formating. (Discuss)

EC2 instances are available in a variety of different sizes with different specifications but all of them currently run on one of two types of virtualization technology: paravirtualization (PV) or hardware virtual machine (HVM).

PV instances boot with a special boot loader called PV-GRUB, which starts the boot cycle and then chain loads the kernel specified in the menu.lst file on your image. Paravirtual guests can run on host hardware that does not have explicit support for virtualization, but they cannot take advantage of special hardware extensions such as enhanced networking or GPU processing.

HVM instances are presented with a fully virtualized set of hardware and boot by executing the master boot record of the root block device of your image. This virtualization type provides the ability to run an operating system directly on top of a virtual machine without any modification, as if it were run on the bare-metal hardware. The Amazon EC2 host system emulates some or all of the underlying hardware that is presented to the guest. (from: Linux AMI Virtualization Types).

Only older instance types support PV instances, all new instance types use an HVM hypervisor. For the purposes of setting up Alpine Linux on EC2 this mainly impacts the way the bootloader is configured.

EC2 instances are created from templates called Amazon Machine Images (AMI). AMIs are built using existing running instances and then are turned into AMIs using a snapshot process. Note that an AMI is region specific so you must either follow this guide in each region you plan to deploy Alpine Linux instances or you must copy the AMI using either the console or the AWS command line client to each region you plan to use.

All instance types are 64-bit. 32-bit images will not work.

This guide will create the smallest possible (1GB) EBS-backed image which acts as a virtual USB stick that will boot and run Alpine Linux.

Initial Setup

All AMI creation tasks follow the same set of setup steps which require a running Linux instance and an attached EBS volume. The Linux instance will only be used to set up the root filesystem for your Alpine Linux system so any distro works, Amazon Linux is the default so, where relevant, this guide will use that distro.

  1. Create an EC2 instance, t2.micro running Amazon Linux should suffice
  2. Create a 1GB EBS volume and attach it to the instance as /dev/sdf (this will appear on an HVM instance as /dev/xvdf)
  3. Format the disk as ext4, there is no need to partition the drive:

    mkfs.ext4 /dev/xvdf

  4. Mount the drive to the host:

    mkdir /mnt/target && mount /dev/xvdf /mnt/target

  5. Fetch a copy of the latest virt release:

    curl -o /tmp/alpine-release.iso https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-virt-3.7.0-x86_64.iso

  6. Mount the release iso:

    mkdir /mnt/source && mount -o loop /tmp/alpine-release.iso /mnt/source

  7. Copy the files to the target

    cp -av /mnt/source/boot /mnt/target

The sudo package is not included in the on-disk repository for the virt image which means that it will not be accessible for installation at system boot time; to enable this you will need a copy of the repository from the extended image. Download this image and copy the apks folder to the target.

  1. Fetch a copy of the latest extended release:

    curl -o /tmp/alpine-extended-release.iso https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-extended-3.7.0-x86_64.iso

  2. Mount the release iso:

    mkdir /mnt/source-extended && mount -o loop /tmp/alpine-extended-release.iso /mnt/source-extended

  3. Copy the files to the target

    cp -av /mnt/source-extended/apks /mnt/target

Because the packages on Amazon Linux are a little older than the ones that ship with Alpine and because you will be creating an apkovl file for initial system configuration, you will either need an existing Alpine Linux system or a copy of the minirootfs image into which you can chroot. To set up a chroot:

  1. Fetch a copy of the latest minirootfs release:

    curl -o /tmp/alpine-minirootfs.tar.gz https://dl-4.alpinelinux.org/alpine/v3.7/releases/x86_64/alpine-minirootfs-3.7.0-x86_64.tar.gz

  2. Unpack the root fs:

    mkdir /tmp/alpine-chroot && tar -C /tmp/alpine-chroot -xvf /tmp/alpine-minirootfs.tar.gz

  3. Copy the system resolv.conf into the chroot so you will have internet access:

    cp /etc/resolv.conf /tmp/alpine-chroot/etc

Create an Apkovl File

The top level of the EBS volume will be scanned during boot for files named *.apkovl.tar.gz and the first one that is found will be unpacked and overlayed onto the file system. The goal of this archive is to configure the system so that you will be able to login after the system boots. At a minimum this means:

  • Configure networking to use dhcp and start when the system boots
  • Install an SSH daemon
  • Configure a user with your SSH keys
  • Enable sudo so that you can gain root access

Set up the chroot and chroot into it, then add any desired packages. The busybox-initscripts package provides the required files for udhcpc which will allow DHCP to be enabled. The syslinux package is required to install the boot-loader but is not required on the final system.

mkdir /tmp/alpine-chroot/mnt/target
mount -o bind /mnt/target /tmp/alpine-chroot/mnt/target
mount -t proc none /tmp/alpine-chroot/proc
mount -t devtmpfs none /tmp/alpine-chroot/dev
mount -t sysfs none /tmp/alpine-chroot/sys

chroot /tmp/alpine-chroot sh

apk update

#If using older version 3.7.x, use:
apk add alpine-conf sudo openssh busybox-initscripts syslinux

# If using Alpine 3.8+, the package "busybox-initscripts" is replaced by "busybox-mdev-openrc"
apk add alpine-conf sudo openssh busybox-mdev-openrc syslinux

The Alpine init system will start up the core required services if the file /etc/.default_boot_services exists, so create that.

touch etc/.default_boot_services

Set up networking:

cat > /etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

ln -s /etc/init.d/networking /etc/runlevels/default/
ln -s /etc/init.d/sshd /etc/runlevels/default/

Add a user, set an SSH key, and ensure that this user can sudo:

adduser -D -s /bin/sh alpine
addgroup alpine wheel

mkdir /home/alpine/.ssh
chmod 700 /home/alpine/.ssh
chown alpine /home/alpine/.ssh
cat > /home/alpine/.ssh/authorized_keys <<EOF
... your ssh public key(s) ...
EOF
chmod 600 /home/alpine/.ssh/authorized_keys
chown alpine:alpine /home/alpine/.ssh/authorized_keys

passwd -u alpine

sed -i '/%wheel/s/^# //' /etc/sudoers

Exclude backup files and any files that are going to exist in the unpacked image. Then create an apkovl bundle.

lbu exclude \
    etc/group- etc/passwd- etc/shadow- \
    etc/apk/keys etc/apk/arch etc/apk/repositories \
    etc/os-release \
    etc/issue \
    etc/alpine-release
lbu include /home/alpine/.ssh
lbu package amazon.apkovl.tar.gz

Verify that everything you expect to be in the apovl file is there and if not you can modify the apkovl.

Finally, copy the apkovl to /mnt/target.

cp amazon.apkovl.tar.gz /mnt/target

EBS Backed HVM AMI

For HVM instances you will need to install a boot-loader. Any bootloader should do the trick but this guide will use syslinux because it's fast and small and you don't have to support any odd hardware or system layout.

First you will need to ensure that the ext4 driver is loaded and may as well shorten the timeout to speed instance boot time.

sed -i \ -e '/usb-storage/s//usb-storage,ext4/' \ -e '/^TIMEOUT/s/20/2/' \ /mnt/target/boot/syslinux/syslinux.cfg

Finally, install the bootloader:

extlinux -i /mnt/target/boot

EBS Backed PV AMI

For PV AMIs PV-GRUB will attempt to read /boot/grub/menu.lst to load the kernel. First create a /boot/grub/grub.conf:

mkdir -p /mnt/target/boot/grub

cat > target/boot/grub/grub.conf <<EOF 
default=0
timeout=2
hiddenmenu

title Alpine Linux
root (hd0)
kernel /boot/vmlinuz-virthardened alpine_dev=xvda1:ext4 modules=loop,squashfs,sd-mod,ext4 console=hvc0 pax_nouderef BOOT_IMAGE=/boot/vmlinuz-virthardened
initrd /boot/initramfs-virthardened
EOF

ln -s /mnt/target/boot/grub/grub.conf  /mnt/target/boot/grub/menu.lst

Create the AMI

The following will need to be done in the AWS console.

  1. Detach the new volume (make note of the volume ID)
  2. Launch a new instance, use the defaults; you are going to cannibalize it in a moment
  3. Once the instance starts, stop but do not terminate it
  4. Under EBS, detach the existing volume, and attach the Alpine Linux volume as /dev/xvda (for HVM) or /dev/sda1 (for PV)
  5. Restart the instance
  6. Log in and make sure it works
  7. Do any final cleanups necessary. Only make changes appropriate for an AMI, you are going to snapshot this instance and use it as the base for the AMI.
  8. Stop but do not terminate the instance
  9. Right click the stopped instance and choose 'Create Image (EBS AMI)'
  10. Once the AMI creation finishes you can cleanup the instances and EBS volumes used