Goodbye cloud VMs, hello laptop VMs

Local Launch

Advanced Tooling with Multipass

Multipass can use cloud-init to configure local VMs fully, as used in various public clouds. With this tool, you can prototype your public cloud launches locally, for free, and in a way that can not be accomplished with similar tools. The cloud-init tool initializes VM instances – fully configured machines out of the box – without the need for an external configuration tool. For example, I use this functionality to bring up fully configured single instances running many standard cloud components on my laptop, allowing quick experiment-verify-cleanup combinations of various stacks, sometimes a few dozen times a day, before the final public cloud push.

Listing 1 shows a cloud-init configuration in the cloud-config data format with its various required sections. I use this file with Multipass to bring up a fully configured instance running a Dockerized Apache Cassandra and its web user interface (UI) out of the box. The users section configures a user named ubuntu with sudo privileges, ready to use the desired SSH keypair for the SSH login.

Listing 1

cloud-config-cassandra.yaml

#cloud-config
users:
  - default
  - name: ubuntu
    gecos: Ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin
    shell: /bin/bash
    ssh_import_id: None
    lock_passwd: true
    ssh_authorized_keys:
      - PUBLICKEY
package_update: true
package_upgrade: true
packages:
  - avahi-daemon
write_files:
  - content: |
      version: "2.4"
      services:
        cassandra:
          image: cassandra:4.0
          container_name: cassandra
          hostname: cassandra
          mem_limit: 1.8g
          healthcheck:
            test: ["CMD", "cqlsh", "-e", "describe keyspaces"]
            interval: 5s
            timeout: 5s
            retries: 10
          network_mode: host
          volumes:
            - cassandra-data:/var/lib/cassandra
          restart: unless-stopped
          environment:
            CASSANDRA_CLUSTER_NAME: CassandraTest
            CASSANDRA_DC: CassandraTest
            CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
            CASSANDRA_NUM_TOKENS: 4
            CASSANDRA_RACK: CassandraTest
        cassandrawu:
          image: ipushc/cassandra-web
          container_name: cassandrawu
          hostname: cassandrawu
          mem_limit: 512m
          network_mode: host
          restart: unless-stopped
          environment:
            HOST_PORT: ":8080"
            CASSANDRA_HOST: localhost
          depends_on:
            cassandra:
              condition: service_healthy
      volumes:
        cassandra-data:
    path: /opt/docker/compose/cassandra.yml
    owner: ubuntu:ubuntu
    permissions: '0600'
runcmd:
  - wget "https://get.docker.com" -O get-docker.sh
  - sh get-docker.sh
  - rm -fv get-docker.sh
  - usermod -aG docker ubuntu
  - wget "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -O /usr/local/bin/docker-compose
  - chmod 0755 /usr/local/bin/docker-compose
  - mkdir -p /opt/docker/compose
  - docker-compose -f /opt/docker/compose/cassandra.yml up -d
output:
  init:
    output: "> /var/log/cloud-init.out"
    error: "> /var/log/cloud-init.err"
  config: "tee -a /var/log/cloud-config.log"
  final:
    - ">> /var/log/cloud-final.out"
    - "/var/log/cloud-final.err"

Note that PUBLICKEY is a placeholder, and you need to replace it with the public key content of the key pair. If you don't have an SSH key pair generated, use ssh-keygen and follow the prompts. The package_update section resynchronizes the package index files from their sources, and the package_upgrade section installs the newest versions of all packages currently installed on the system. The packages section takes a list of the packages that need to be installed on the system. The example configuration installs the avahi-daemon to resolve <hostname>.local to the instance address.

The write_files section generates files by combining content, path, owner, and permission for each file. The example configuration generates a docker-compose manifest to bring up Cassandra and its web UI stack. The runcmd section takes a list of the shell commands to run in the order given to complete the configuration of the instance. Finally, the output section generates various logs capturing stdout and stderr during various stages of cloud-init to debug in case the instance is not configured as per the cloud-config data provided. The cloud-init service and cloud-config script provide more functionality through many other sections. Please refer to the cloud-config examples [4] in the reference section to see those in action.

To bring up a fully configured cloud VM instance locally, just execute:

multipass launch -m 2G -n cassandra --cloud-init ./cloud-config-cassandra.yaml

Once the instance is up, try to access the Cassandra web UI by typing cassandra.local:8080 in your browser (Figures 4 and 5).

Figure 4: Cassandra host info.
Figure 5: Cassandra system local key

Log in to the Cassandra instance with command

ssh -oStrictHostKeyChecking=no ubuntu@cassandra.local

and execute the command

multipass delete cassandra && multipass purge && ssh-keygen -R cassandra.local

to clean up when you are done with the local cloud VM.

I've created a wrapper script [5] and various cloud configs to bring up fully configured local cloud VMs on Ubuntu 20.04 LTS running Cassandra, Consul, OpenSearch, Kafka, Nomad, Spark, and Vault with a single command. To get the wrapper, just download the sources with:

git clone https://github.com/richnusgeeks/devops.git
pushd CloudInABox/Multipass/scripts

You could use cd instead of pushd, but I prefer the latter for its intelligence. The wrapper script execution should display a help screen (Figure 6).

Figure 6: Wrapper help screen.

All the local VM instances brought up with the wrapper script are configured with monit, docker, and docker-compose, in addition to the chosen target role. For example, you can bring up a fully configued local cloud VM with Consul in development mode with:

./create_multipass_machines_stack.sh create consuldev

Once the local cloud VM instance is up, you can access the Monit (Figure 7) and Consul (Figure 8) web UIs on consuldev.localhost:2812 (credentials: guest /guest ) and consuldev.localhost:8500 , respectively. When done, you can get into the created instance and clean up everything with:

Figure 7: Monit web user interface.
Figure 8: Consul web user interface.
ssh -oStrictHostKeyChecking=no ubuntu@consuldev.local
./create_multipass_machines_stack.sh cleandelete

The tooling with the wrapper script around Multipass made bringing up and cleaning up the fully configured local cloud VMs easy.

Conclusion

Multipass is a must-have tool for modern cloud and infra/platform developers. Combined with cloud-config data, it is highly useful for bringing up almost fully configured Ubuntu public cloud instances locally. With Multipass, you can accelerate productivity while slashing your public cloud bill.

The Author

Ankur Kumar is a passionate free and open source hacker/researcher and seeker of mystical life knowledge. He explores cutting-edge technologies, ancient sciences, quantum spirituality, and various genres of music, mystical literature, and art. You can connect with Ankur at https://www.linkedin.com/in/richnusgeeks and explore his GitHub site (https://github.com/richnusgeeks) for other useful FOSS ideas.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus