Bootstrapping Alpine Linux on Oracle Cloud servers
A friend of mine recently made me aware of Oracle Cloud's free tier, which allows you to get a limited amount of virtual servers, for free, forever.
And it's not even too bad spec-wise! They offer ARM servers (either one server up to 4 cores and 24GB RAM or four servers with 1/4 of that), and more traditional
x86 servers, based on previous-gen AMD CPUs (1 core, 1GB of RAM). I registered at their page, created an Instance (their in-house name for a VPS, which is still better than ""EC2"")
and was greeted with a.. limited selection of operating systems to choose from. You could either go with Canonical Ubuntu, CentOS, one of their Red Hat forks
(they call it "Oracle Linux", I call it an outdated
scam RedHat wannabe) or - for an additional fee - Windows Server.
Suffice to say, their offering wasn't satisfying. These days, my go-to server OS is Alpine, with Debian as a fallback; They didn't offer either of those, and I chose to change that.
Haruhi says..."This article presents practices that *may* violate their ToS, but has this ever stopped anyone? Yeah, right! ^^"
Poking around in the web console looking for a way to import a custom image revealed that they do support this kind of deployment scenario. After preparing a qcow2 Alpine image and uploading it to a bucket in their cloud storage (because they insist you *can't* import an image from any HTTP server, no, it needs to be *their bucket storage*), the only step left was to import it as a boot image. The whole process (upload and import) took over 30 minutes, but I finally could create a VM using the custom image... Or could I?
As it turns out, Oracle only supports UEFI boot on their free Ampere and AMD64 machines, and my alpine was installed w/ BIOS. This meant that the only machine that could be actually used
was their Intel offering, which didn't get included into the Free Tier. Bummer!
The image ended up working, but I wasn't satisfied. I came for the free stuffs, so it's not like I'm settling for the paid option! Additionally, the whole process took *way* too long from start to finish, so it didn't make much sense to develop an UEFI-based image.
I don't like poking around EFI on virtual machines. QEMU requires you to manually download TianoCore and hack your way through setting it all up, while with SeaBIOS, it can boot with just one parameter pointing at a boot image. This meant that I'd much prefer to develop and test the whole process directly on their VMs, as they're already set up. If we allow Oracle to install their default OS on an Ampere machine, we get a partition table that looks more or less like this:
- /dev/sda1 - 200MB, EFI
- /dev/sda2 - 8GB, SWAP
- /dev/sda3 - rest of the drive, XFS
The 2nd partition is great news, because we can use the 8GB of SWAP as a new root fs! After destroying the swap, making a new ext4 partition and unpacking the alpine minirootfs, I could chroot to the new OS without a problem. Technically, the alpine is already there, so we could *just* chroot every time.. but this is boooriiiing and proves to be difficult if you actually need to deploy any services. Instead, I chose to make Alpine a stand-alone OS, via booting from GRUB.
Debugging the boot process was hard at first (the machine kept booting back to RH), but I found a way to access the VM's screen through their cloud console. They offer two options for debugging OS issues - VNC or serial console, both proxied over SSH. It's worth noting that Ampere's VNC connection option is utterly broken - it proxies the screen just fine, but it doesn't catch any keyboard inputs. This can be mitigated by using the serial console, which is only slightly less broken - some special keys (del, esc, bckspc) are mismatched. (ORACLE PLS FIX)It works!
Finally, it boots... on Ampere, at least. As Oracle also offers free x86 servers, it wouldn't be fair if the script didn't support those, right? :3
Well, those beasts required a bit more hacking to get them to work. Those machines don't even boot with the default Alpine virt kernel, and I couldn't figure out why (Dear Reader, if you can, get in touch). As a workaround, I decided that copying stock kernel and modules to the Alpine partition would suffice. It may prove to be difficult to update in the future, but - for now - it works quite well!
Well, I condensed my efforts into an easy-to-use script. After setting up a VM, your course of action looks something like this:
curl https://f.sakamoto.pl/alpine-bootstrap.sh -O
chmod +x alpine-bootstrap.sh
This script handles everything from turning off the SWAP partition through making a new filesystem, ending on installing Alpine and making sure all default services will run on boot. Works both on ARM64 *and* on AMD64. Licensed under LGPLv3.
- After rebooting, you'll have Alpine on /dev/sda2 and your other OS on /dev/sda3. There's nothing stopping you from deleting the original OS and reclaiming the space - in fact, I recommend doing exactly that. You can use cfdisk and resize2fs for this task, they're preinstalled.
- You will need to delete old, conflicting SSH entries from your local ~/.ssh/known_hosts. By default, the login is root, and the password is what you set it to during the installation process.
- If possible, *disable* passworded root SSH login by commenting out the last line of /etc/ssh/sshd_config. Make sure to import some SSH keys or make an unpriviliged user first!
- By default, Oracle Cloud blocks everything except tcp/22 (that is, SSH), including ICMP (pings). This is not Alpine's fault, and you need to disable that behaviour through the Cloud Console (Networking -> Virtual Cloud Networks)
Overally, Oracle Cloud has a nice free offering, but it reassured me to stay with selfhosting my servers physically and/or rent VPSes from more experienced hosting companies. My biggest problem with Oracle Cloud (apart from not having the OS I wanted) was them being non-transparent about how much I may pay for what. This was seemingly copy-pasted from other cloud providers like AWS, which would rather provide a spendings calculator instead of a known, set price.