How to enjoy Fedora in Google Compute Engine
So, you too you’ve been disappointed to see there’s no prebuilt image of Fedora from Google in Google Compute Engine (GCE)? The good news is that, thanks to this missing image, you’ll build your own custom image and so learn an important aspect of Google Cloud Platform (GCP). This means extensive customization of your VMs if you want it.
Before to start, a brief thing you need to know. VMs are really much like computers, but you already know that, right? What you may not know is that, images, in GCE, are prebuilt OS that the virtual computer will have on its first start up. It’s much like when you buy a computer, you get it with (sadly) a preinstalled version of Windows installed on the hard disk. And when you boot up the first time, it’ll boot this preinstalled version that is the same for all computers of this model/manufacturer.
In Google Compute Engine, it’s all the same. When you create an instance, you need to start somewhere, so it will let pick you a preinstalled Linux to boot from, also called an “image”. Note that some VM users will say “In VMs, usually, we start booting via an ISO CD with a setup assistant”, but usually Google Compute Engine VMs are intended to run unattended, and a setup GUI would basically prevent that.
So in this article, we’re going to:
- Borrow the latest official Fedora Cloud image.
- Add some software on top of it so it is better compatible with Google Compute Engine.
- Package it as a GCP image.
- Create an instance using this image.
This all in Google Compute Engine.
Get Fedora Cloud image for customization
To start, you need to create a VM where we’re going to build and modify the official Fedora Cloud image. So, create an instance with the following options:
- Give it a name, choose the right zone, etc.
Please keep the zone in mind because we’ll need it later.
- In “Machine Type”, choose the “f1-micro”. This is more than enough for our needs.
- In “Boot Disk”, click “Change” and choose “CentOS 7”. This is the closest image to Fedora (Fedora is maintained by Red Hat, CentOS is RHEL without customer support) and using familiar tools will help to build the image.
- In “Identity and API access”, choose “Allow all access to Cloud APIs”. This is for simplicity, as we’ll need to use gcloud a lot and creating a service account is more cumbersome.
As it’s only a VM that’ll last few minutes, that’s not a problem. Don’t use that in production setup with automated builds of images, though.
- You might want to make the VM “Preemptible”, as Preemptible VMs costs much less. Note though that if you do, Google can shutdown your VM at anytime and you’ll have to restart the VM and resume where you left off.
- Click on the “Create” button. The most fun moment of cloud administration is this one, if you ask me.
Give it 2 minutes to start and then, SSH into the VM using the “SSH” button. It will open a window with SSH connected to your brand new CentOS 7 VM.
The first thing you need is to install wget. You can install curl if you prefer, but the article will use wget.
$ sudo yum install wget
Then, once installed, go to https://alt.fedoraproject.org/cloud/ and next to “Cloud Base compressed raw image”, right click on “Download” and copy the address link.
Get back to the VM, and do the following:
$ wget "{PASTE URL HERE}"
This will download the file. Fedora Servers, their mirrors and Google has a great infrastructure, so the download is going to last only few seconds. Probably my second favorite moment of cloud administration!
Once done, run this command:
$ xz --decompress --keep "Fedora-Cloud-Base-XX-X.X.x86_64.raw.xz"
Note that you have to adapt the filename depending of the version you download. This is going to extract a sparse file of ~3 GB that we can then loop-mount for second step. It is going to take one minute, so take a coffee break and come back when done.
Preparing Fedora for the Google Cloud Platform’s ride
OK, so what do we call preparation here? Roughly, it is loop mounting the raw disk, chroot inside it, add some software so it can use all GCP features and then finally clean up various temporary files.
OK, let’s mount it:
$ mkdir boot $ sudo mount -o loop,offset=1048576 "$PWD/Fedora-Cloud-Base-XX-X.X.x86_64.raw" "$PWD/boot"
Once again, adapt the file name.
Okay, I see that you don’t really understand this command line, so time for an explanation. This command says to Linux: Take a file from disk, act as if it was a disk partition and try to mount it. This is the principle of the loop mount. But you’ll also notice the “offset=1048576”. There’s an offset because this raw disk is a disk, not a partition. It comes partitioned, with a bootloader on it, so the VM knows what to do on startup. But we can’t mount, or chroot into a bootloader, right?
So by setting the offset, Linux is in fact, mounting the first partition of the raw disk stored in the file. It is an ext4 partition and to leave enough space to bootloaders, first partitions generally starts 1 MiB after the beginning of the disk. Hence the offset. Next:
$ cd boot $ sudo mount --bind /dev dev && sudo mount --bind /sys sys && sudo mount --bind /proc proc && sudo mount --bind /etc/resolv.conf etc/resolv.conf $ sudo chroot ./ /usr/bin/bash
And now, welcome to your Fedora loop-mounted raw chroot! So, why all of that? First, we mount anything needed for any decent application to work, /dev, /proc and /sys. Also, we mount bind resolv.conf because otherwise the chroot has no Internet access (!). Finally, we chroot into it. Note that we use /usr/bin/bash because /bin in Fedora is a symlink to /usr/bin.
Now, it’s time to install the Google Cloud Platform software to make it work well.
The first thing you might want to do is have an up-to-date image. It’s better, no? So:
# dnf upgrade --assumeyes --nogpgcheck "*"
Once again an occasion to take a sip of coffee, since it is going to take a while. The “–nogpgcheck” is because GPG check and chroot doesn’t act very well to each other. Then, do this:
# cat > "/etc/yum.repos.d/google-cloud.repo" <<"EOR" [google-cloud-compute] name=Google Cloud Compute baseurl=https://packages.cloud.google.com/yum/repos/google-cloud-compute-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOR
And do:
# dnf install --nogpgcheck --assumeyes google-compute-engine python-google-compute-engine
This is going to install all Google-related software in order to be best compatible with Google Compute Engine. For example, it will allow you to check/uncheck IP forwarding from Google Cloud Platform interface, or use SSH in browser instead of having to explicitly create a SSH key for the VM. Next:
# touch "/.autorelabel" # dnf clean all
As you know, one of the best things about Fedora, it is its security features and enterprise-level quality, and SELinux is a part of it. So in order to avoid headaches, it retriggers a relabel of the whole disk upon VM’s first start up.
It does so because the labels in SELinux are wrong in a chroot environment and forgetting this little step makes the VM unbootable and unreachable from the outside. The dnf upgrade above rewrites a lot of the core files that are unlabeled and then SELinux prevents these binaries from running. Note that it means the first VM startup can take a few minutes before it is ready.
dnf clean up allows to keep the image as small as possible. This saves you the cost of repeatedly storing things you don’t need.
Time to exit chroot:
# exit $ cd ../
Now you got out of the loop-mounted directory, you can unmount bind-mounted things:
$ sudo umount boot/dev boot/proc boot/sys boot/etc/resolv.conf
And then, let’s do this:
$ sudo fstrim --verbose boot
This helps you to keep the loop-mounted image even smaller. Basically, during the upgrade, the raw image will be quickly filled with zones of temporary files. Unlike real hard disks, when a file is deleted in a raw image, it is just deleted in filesystem metadata of the raw image and it still uses space on the hard disk hosting the raw image. fstrim allows you to make these unused zones “sparse” and so this space of deleted files is given back to the disk.
Unmount the loop-mounted device now:
$ sudo umount boot $ mv "Fedora-Cloud-Base-XX-X.X.x86_64.raw" "disk.raw" $ tar --create --auto-compress --file="Fedora-Cloud-Base-XX-X.X.x86_64.tar.gz" --sparse disk.raw
OK, cool, you have now your final image, pre-packaged! The size for me is around 350 MiB, tiny eh? Now, you remember when I said you had to take note of the zone? It is now you need it!
Head to Google Cloud Storage and create a bucket. I assume here you don’t have already a bucket in the right zone, otherwise it is perfectly fine to use a pre-existing one. So create a bucket with the following options:
- Give it a name.
- Choose “Regional” type. Since we only use the bucket here for images, which can be regenerated easily, regional allows to pay less by not having a geo-redundant backup of the file.
- Pick the region where the CentOS VM you created is located.
- Hit Create.
Wait for the bucket to be created, and once done, go in SSH window again and do:
$ gsutil cp "Fedora-Cloud-Base-XX-X.X.x86_64.tar.gz" "gs://[name of the bucket]/"
This copies the packaged image to Google Cloud Storage so we can say to GCP: Take that .tar.gz and make it an image.
Now, you can shutdown the instance at that point. Don’t delete it yet as we’ll test the Fedora instance before deleting this build VM.
Now in Google Compute Engine, get inside “Images”. Hit the “Create Image” button. Configure it like this:
- Name it “fedora-cloud-XX-YYYYMMDD” where XX is the version and YYYYMMDD is the today’s year, month and date.
- In “Family”, enter “fedora-cloud-XX”.
- In “Source”, choose “Cloud Storage file”.
- Click on the “Browse” button, get in your bucket, and select the .tar.gz file uploaded earlier.
- Create the image.
And that’s all folks!
Testing phase
OK but that wouldn’t be a real how-to guide if we did not test whether it works as expected. So to see if it worked great, get to “VM Instances” and then click on “Create Instance”.
Configure the instance this way:
- While Fedora Cloud can work on almost all VM shapes, I recommend you to choose the cheapest VM type, f1-micro, since we only use this VM for testing purposes.
- Below “Boot disk”, click on the “Change” button.
Go in the “Custom Image” tab and then pick the image you just created.
Don’t forget to set the boot disk size. It will be set to below 4 GB, way too small. The minimum size of Google Cloud Platform disks is 10 GB and the recommended minimum by Google is 200 GB.
- Once again, you might want to set the VM as Preemptible, especially if you’ll use it only for test purposes and not keep it.
- Click on the “Create” button.
Now, you’ve to wait 5 minutes, enough time to clean up your keyboard! And after these 5 minutes, now you can click the “SSH” button.
And now, hopefully, hooray, you’re logged in to your Fedora VM, run by Google Cloud! At that point, don’t forget to delete the test VM and the build VM.
I hope you enjoyed the tutorial, and it will work nicely for you. That’s all folks (for real this time), and see you in a Fedora VM!