Creating your first VM

Step by step on how to create your first VM

Prerequisites

  1. You’ve installed the Anka Virtualization package
  2. You’ve got an active license
  3. The host you wish to use is using an Intel and not an Apple processor.

1. Obtain the macOS installer

Anka VM Templates support the following macOS versions:

  • 13.x (macOS Ventura)
  • 12.x (macOS Monterey)
  • 11.6.x (macOS Big Sur)
  • 10.15.x (macOS Catalina)
  • 10.14.x (macOS Mojave)
Monterey installation inside of the VM seems to be much longer than previous versions. Please be patient and DO NOT interfere with the installation manually. If you want to confirm it’s progressing you can launch the VM viewer with anka view.
Starting in Monterey, VMs require ablk as the disk driver.

There are multiple ways to obtain the installer .app file for Mac OSX that we’ll detail for you below:

The recommended approach is using softwareupdate in your terminal:

❯ softwareupdate --list-full-installers
Finding available software
Software Update found the following full installers:
* Title: macOS Monterey, Version: 12.2.1, Size: 12155426708K, Build: 21D62
* Title: macOS Monterey, Version: 12.2, Size: 12156325205K, Build: 21D49
* Title: macOS Monterey, Version: 12.1, Size: 12157035487K, Build: 21C52
* Title: macOS Monterey, Version: 12.0.1, Size: 12128428704K, Build: 21A559
* Title: macOS Big Sur, Version: 11.6.4, Size: 12439328867K, Build: 20G417
* Title: macOS Big Sur, Version: 11.6.3, Size: 12435122667K, Build: 20G415
* Title: macOS Big Sur, Version: 11.6.2, Size: 12433351292K, Build: 20G314
* Title: macOS Big Sur, Version: 11.6.1, Size: 12428472512K, Build: 20G224
* Title: macOS Big Sur, Version: 11.5.2, Size: 12440916552K, Build: 20G95
* Title: macOS Catalina, Version: 10.15.7, Size: 8248985973K, Build: 19H15
* Title: macOS Catalina, Version: 10.15.7, Size: 8248854894K, Build: 19H2
* Title: macOS Catalina, Version: 10.15.6, Size: 8248781171K, Build: 19G2021

❯ softwareupdate --fetch-full-installer --full-installer-version 12.2.1 
Scanning for 12.2.1 installer
Install finished successfully

❯ ls /Applications | grep Monterey 
Install macOS Monterey.app

Other options are:

  1. If you have a pending upgrade to the next minor or patch version of Mac OS:
    • Within Preferences -> Software Update -> Advanced, make sure Download new updates when available is checked but Install macOS updates is not. While you’re still within Software Update, click Update Now but do not install the next version (Restart) until after you’ve created the Anka VM or the Install .app under /Applications will be deleted.
    • You can also use the App Store to download the installer.
  2. Have your local IT department provide a network volume or download links.
  3. Use our Getting Started script, but run it with ./create-vm-template.bash --no-anka-create
  4. MIST - macOS Installer Super Tool

2. Create your VM

Before you begin

Be aware of the user you’re executing Anka CLI commands as. If you create VMs as root, they won’t be available to other users on the system and vice versa.
  • We recommend naming your initial VM after the version of macOS.
  • The VM creation should take around 40 minutes.
  • If you leave out --ram-size and --cpu-count, Anka will choose for you based on your total CPU and RAM. It will try to halve the total CPU and RAM values, but has a min of 2CPU/4GB and a max of 8CPU/8GB.
  • By default anka create creates a VM Template with the username anka and password admin. Environment variable are available to change these: ANKA_DEFAULT_USER and ANKA_DEFAULT_PASSWD (be sure to use sudo -E when issuing the create command).
  • SIP is DISABLED by default inside of Anka 2 VMs. This can be re-enabled with anka modify {vmNameOrUUID} set custom-variable sys.csr-active-config 0.
Suspending VMs can sometimes produce a VM which is frozen on start. Usually this is because the hardware & cpu type you created the VM and suspended it on is different from the one you’re trying to start it on. Be sure to suspend your VMs on the same hardware that will be running VMs. You can use ANKA_CREATE_SUSPEND=0 anka create . . . to produce a stopped VM.
  • Anka Develop license (default): While you can create as many VMs as you wish, the free Anka Develop license only allows you to run one VM at a time and will only function on laptops (Macbook, Macbook Pro, and Macbook Air). It only supports a stopped VM state.

  • Anka Build license: When determining how many vcpus and ram your VM needs, you can divide the number of VMs you plan on running simultaneously within a host by the total virtual cores (vcpus) it has. So, if I have 12vCPUs on my 6core Mac Mini, and I want to allow 2 running VMs at once and not cripple the host machine, I will set the VM Template/Tag to have 6vcpus (12 / 2). However, with RAM, you’ll need to allow ~2GB of memory for the Anka Software and host ((totalRAM / 2)-1). Build licenses support suspended and stopped VM states.

Using the Anka UI

  1. Click on Create new VM
  2. Choose the installer (will automatically search /Applications), or drop it into the window
  3. Click on Options and set any non-default values you want installer with pkg
  4. Please be patient while it’s creating. This process can take up to half an hour.

Once the VM template is created, you will see it on the sidebar.

ui with vm in the sidebar list

Using the Anka CLI

> sudo anka create --help
Usage: anka create [OPTIONS] VMNAME

  Creates a VM

Options:
  -m, --ram-size TEXT      Set the RAM size (including 'G' or 'M' on the end)
  -c, --cpu-count INTEGER  Set the number of vcpu cores
  -d, --disk-size TEXT     Set the disk size when creating a new disk (including 'G' or 'M' on the end)
  -a, --app PATH           Path to the macOS installer .app
  -p, --pkg PATH           Include additional packages to be installed
  -P, --profile PATH       Include a configuration profile(s) to install alongside the macOS installation (not
                           available for macOS >= 11.x/Big Sur)
  --help                   Display usage information
sudo anka create --ram-size 8G --cpu-count 4 --disk-size 80G \
--app /Applications/Install\ macOS\ Catalina.app 10.15.6

Listing available VMs in the CLI

❯ sudo anka list
+------------------------------------------------+--------------------------------------+--------------+------------------------+
| name                                           | uuid                                 | created      | status                 |
+================================================+======================================+==============+========================+
| 10.15.5 (base:port-forward-22:brew-git:gitlab) | c0847bc9-5d2d-4dbc-ba6a-240f7ff08032 | Jul 13 16:40 | suspended Sep 01 20:18 |
+------------------------------------------------+--------------------------------------+--------------+------------------------+
| 10.15.6                                        | 5bba6eea-202e-45ed-9567-d7f55090d049 | Sep 02 10:17 | stopped Sep 02 13:37   |
+------------------------------------------------+--------------------------------------+--------------+------------------------+
| 11.0.1                                         | 2bb1b152-9996-41d6-804a-a429973c13bc | Sep 01 18:45 | stopped Sep 02 14:28   |
+------------------------------------------------+--------------------------------------+--------------+------------------------+
| test                                           | 77f33f4a-75c3-47aa-b3f6-b99e7cdac001 | Sep 03 11:30 | running                |
+------------------------------------------------+--------------------------------------+--------------+------------------------+

Optimizing your VM

It’s recommended that you disable Spotlight and CoreDuetD inside of the VM to eliminate services that are known to need high CPU:

sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.coreduetd.osx.plist 
sudo defaults write ~/.Spotlight-V100/VolumeConfiguration.plist Exclusions -array "/Volumes"
sudo defaults write ~/.Spotlight-V100/VolumeConfiguration.plist Exclusions -array "/Network"
sudo killall mds || true
sleep 60
sudo mdutil -a -i off /
sudo mdutil -a -i off
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
sudo rm -rf /.Spotlight-V100/*

Deleting a VM

Using the Anka UI

edit menu delete

Using the Anka CLI

❯ anka delete test
are you sure you want to delete vm 77f33f4a-75c3-47aa-b3f6-b99e7cdac001 test [y/N]:

(Anka Build license + Cloud) Understanding VM Templates, Tags, and Disk Usage

This section mentions features (suspending, tagging, and registry push/pull) which are not available with a free Anka Develop license.

When using Anka to create a VM, it’s best to think of the result as a VM “Template”. A “template” should suggests to you that it is something you don’t directly use. This will make more sense later.

To create a VM Template, you’ll use the Anka CLI’s create command or Anka UI with any macOS installer .app file (Anka 2/Intel). After a VM Template is created, you’ll have a clean macOS installation inside of the VM with some small tweaks for Anka to function. You can use anka view and/or anka run commands to install dependencies and software you need inside of the VM.

An example bash script that shows how to use anka run to install dependencies.

Once the VM Template is configured how you want it, you have two options:

  1. Stop the VM Template: anka stop {templateName}
  2. Suspend the VM Template: anka suspend {templateName}

With option 1, you are issuing a full shutdown – similar to hitting the power button on your physical machine – and therefore have to wait the full boot time for the VM to start back up. This usually takes 20 to 30 seconds.

With option 2, you can save the state of the VM/memory to a file which can then be used to start the VM almost instantly. However, these files that contain the state are several GBs in size and shouldn’t be used if your hosts are limited on disk space. Stopped Big Sur VMs are ~19GB, but can be more than 30GBs depending on the amount of memory given to the VM.

It’s very important that when you suspend from a started state the VM has fully booted and logged into a user. If you don’t, the VM may be frozen or fail to boot. You can script this using anka run {VMTemplateName} sleep 60 or manually check with anka view to ensure it’s in a good state.

The VM Template is now ready to be used. You shouldn’t directly use it to run your jobs as this will cause the VM Template to become “dirty”. You will instead use anka clone {VMTemplateName} job-1-vm to create a new VM from the template. Any changes made inside of the cloned VM will not impact the original VM Template. You can then delete the clone once you’re done with it.

It’s important that you store this VM Template in a location that allows other hosts with Anka installed to pull it and use it. You can push the template to your Anka Build Cloud Registry using anka registry push and set a Tag. Or, use anka registry push -l {vmNameOrUUID} -t {tag} to only create the Tag locally (useful if you don’t have a registry yet and want to quickly switch between Tags/dependencies locally while testing).

Important: Each time you clone a VM you’re creating a new layer/file to store the file system changes inside of the VM. However, any data needed to run the VM from previous layers is not added to this new layer and it instead just references the existing layers/files on disk. This optimizes disk space (like if you have several clones from the same source, they all share as many underlying layers as possible). However, because the new layer/file for the VM stores all changes made inside of the VM post-clone, each new block written has no access to previous blocks, layers, etc. Even if it does have access because they are inside of the new layer, those blocks are not fully deleted from the layer. This causes long running VMs and also repetitive manual changes to the same VM Template to pile up and exhaust disk space on the host. Both of these problems should be considered carefully when designing your VM creation, cloning, and modification approach. We will recommend the best approach below.

Once a Template is created, and Tag assigned to it, you can now create other Templates/Tags from it. Fortunately, Anka allows you to build Templates on top of each other and share the underlying files between them, cutting down on the disk space requirements. This makes switching between dependencies/VM Templates easy and also saves on bandwidth if layers for the VM Template already exist on the host.

You have two options to create VM Templates from VM Templates:

  1. Use anka clone {sourceTemplate} {newTemplate} (recommended): The new cloned Template will have no Tags, but will link to the layers/contents from the previous Template and active Tag’s state. No new disk space will be used until you start and make changes.
  2. Use anka clone --copy {sourceTemplate} {newTemplate}: The new cloned Template will have no Tags, and will copy all of the parent Template’s layers into a single file (“flattening”). This doubles the amount of disk space used.

When creating a clone without --copy, deletion of the first Template will not delete the contents of the second cloned Template. Anka CLI will intelligently know that the layers are still in use by the new Template.

Here is a diagram of a common and recommended pattern for creating Templates/Tags:

11.1.0 (stopped)  | 
                  | -> clone -> xcode12.3 (stopped) |
                  |                                 | -> clone -> project1 (with fastlane-v1.X) (suspended)
                  |                                 | -> clone -> project2 (with fastlane-v2.X) (suspended)
                  |
                  | -> clone -> xcode11.7 (stopped) -> clone -> project3 (suspended)
Note the “stopped” state of the first two cloned VM Templates. Unless you plan on using the vanilla 11.1.0 or xcode VM Templates, the suspended state is a waste of space. However, you do typically want to suspend the final/cloned Templates/Tags that your CI/CD and developers will use.

You can also create multiple tags on top of a single VM Template. This is done by simply starting the VM, stopping/suspending once changes are made, and then pushing to the registry with a new Tag. However, this causes problems when trying to quickly switch between tags for different projects, as the Anka Build Cloud only allows a single Tag on a machine at once (not a problem if manually executing anka pull though). This means that switching would cause a download to happen, and depending on the size of the other tag, could slow down your CI/CD considerably. This is where cloned VM Templates shine. Multiple Templates for multiple projects can exist at once on a host, all sharing underlying layers and cutting down on disk space usage and time to start VMs for your CI/CD jobs.

If you’re interested in Infrastructure as Code to automate the creation of your Templates and Tags, you have several options:

  1. Write scripts that:
    • Sequentially parse and execute commands from a data serialization language like JSON or YAML inside of the VM.
    • Or execute commands inside of the VM from within the script itself (example).
  2. Use the Packer Builder: https://github.com/veertuinc/packer-builder-veertu-anka

Re-pushing an existing registry tag

On pushing to the registry, a tag is created. It will also be assigned a specific commit ID (not visible to users). Even if you modify the tag locally, such as adding port-forwarding, changes will not be pushed to the registry until you push with a different tag name.

Now, you can simply untag the VM locally and then push it with the same name (after deleting the VM template or reverting the tag):

Locally, this does not remove the current STATE of the tag from the VM. Your installed dependencies inside of the VM will remain as long as you don’t pull or switch to a different tag.

anka registry pull -t tag2 TemplateA
anka delete -t tag2 TemplateA
anka modify TemplateA add port-forwarding...
curl ... (delete or revert from registry)
anka registry push -t tag2 TemplateA

What’s next?