Saturday September 7 2019

Setting up Alpine Linux in Google Cloud Platform ( GCP )

Why?

Alpine Linux is very small, based off of busybox doesn’t use systemd, is rather popular–albeit as a base image for Docker containers. Not to mention that it has a decent support lifecycle of about 2 years

Overview

Google Makes it pretty easy to import custom images into their platform and have some good instructions on how to do it.

I’m going to show you how to setup a minimal Alpine Linux install to be deployed in GCP.

Requirements

Assumes you’re on a Linux workstation with qemu/kvm installed and intermediate knowledge as to how the command line operates.

If you’re on Ubuntu or so, installing qemu/kvm with a nice GUI it’s as simple as

$ apt install virt-manager libvirt-clients libvirt-daemon-system

Followed by running virt-manager.

Setup

From there download Alpine Linux from their website, you can use the virtualisation optimized image. I’ve chosen the latter.

Create a new virtual machine, I setup mine as follows:

Installation

Once the installer boots it should leave you with a login prompt, simply type in root and hit enter, there’s no password.

Now, we need to make a couple of adjustments to the environment in order for the installer to do the right thing for GCP’s requirements

export BOOTLOADER=grub
export ROOTFS=xfs # optional, but I recommend it
export DISKOPTS='-L -s 512 -m sys /dev/vda'

That last line might be a bit to unpack, it boils down to:

The next thing to do is to run the Alpine Linux setup script and follow the prompts

setup-alpine

When the installer asks about Available interfaces are:, simply setup eth0 and use DHCP, when asked do not setup any manual network configuration.

After that:

Once the installer finishes, simply type reboot

Setup for GCP

Reboot into your new virtual machine, we have a couple of settings that must be changed before we can load this into GCP

Grub Configuration

Edit /etc/default/grub and add the following line:

GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --word=8 --parity=no --speed 38400 --stop=1"

Now add console=ttyS0,38400n8d to the GRUB_CMDLINE_LINUX_DEFAULT variable

Your /etc/default/grub should now look something like this:

GRUB_DISTRIBUTOR="Alpine"
GRUB_TIMEOUT=2
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_RECOVERY=true
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --word=8 --parity=no --speed 38400 --stop=1"
GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0,38400n8d modules=sd-mod,usb-storage,xfs quiet rootfstype=xfs"

Now let’s make sure to update grub

grub-mkconfig -o  /boot/grub/grub.cfg

Getty Configuration

GCP offers an interactive serial console, to make the most of this edit the bottom line of the /etc/inittab and make it look something like this:

ttyS0::respawn:/sbin/getty -L ttyS0 38400 vt100

SSH Configuration

It’s a good idea to create a user to use for SSH logins, or just use SSH keys instead as follows:

umask 077
mkdir /root/.ssh
vi /root/.ssh/authorized_keys

Then set PasswordAuthentication no in the /etc/ssh/sshd_config file.

Remove SSH Host keys

rm -f /etc/ssh/ssh_host*

Fill the empty disk space with zeros

This is useful so you’re not uploading unallocated data, when a file is deleted the contents are still there, just the marker is gone. This ensures that the empty space on the disk image is indeed filled with zeros, and as such it will compress much better than if you had not done this.

I must also confess that an image built from scratch like this might not see much benefit, but any system that has had any sort of use these steps can save a lot of time, bandwidth and storage.

dd if=/dev/zero of=/fill bs=1M count="$(df -m /  | tail -n1 | awk '{print $3}')" ; rm /fill
swapoff -a ; dd if=/dev/zero of=/dev/mapper/vg0-lv_swap bs=1M ; mkswap -f /dev/mapper/vg0-lv_swap

Poweroff & Create the image

Power off the VM with poweroff or so from the command line, then as root on your host scoot on over to where the disk is stored ( usually /var/lib/libvirt/images ) and run the following:

mkdir alpine-gcp
cp alpine.img alpine-gcp/disk.raw
cd alpine-gcp
tar --format=oldgnu -Sczf alpine-gcp.tar.gz disk.raw

Where alpine.img is the disk image allocated to the VM we created earlier.

Uploading to Google Cloud Storage

You’ll need to have a Google Cloud Storage bucket to store the image, optionally the Google Cloud developer tools if you want to upload via the command line.

Uploading the image should be somewhat straightforward:

gsutil cp /var/lib/libvirt/alpine-gcp/alpine-gcp.tar.gz gs://my-gcs-bucket/alpine-gcp.tar.gz
gcloud compute images create alpine-gcp --source-uri gs://my-gcp-bucket/alpine-gcp.tar.gz

Where my-gcs-bucket is your Google Cloud Storage bucket.

Launching the instance

Is also somewhat straightforward from the command line

gcloud compute instances create \
	alpine-gcp \
	--machine-type f1-micro \
	--description="My Alpine Linux Image" \
	--no-boot-disk-auto-delete \
	--boot-disk-size="30G" \
	--boot-disk-type=pd-ssd \
	--zone us-central1-a \
	--image-project $my-project-name \
	--image alpine-gcp

Where $my-proejct-name is the relevant GCP project name.

Final thoughts

I hope this was somewhat helpful, and perhaps into a view of uses for Alpine Linux that do not involve Docker.