Virtual DevLab v0.1

My main goal:

I want a local environment to develop and test in with the configuration of this environment to happen automatically.

This is to try to treat the lab more like “cattle” rather than a “pet”. In other words, when I mess something up, I can easily blow everything away and reset.

The initial script:

The creation of this script was in combination of two sources online:

Cloud Init Docs: ( Core tutorial with QEMU - cloud-init 23.1.1 documentation )

Someone’s Personal Blog: ( Joshua Powers )

The official cloud init docs used a local server to serve out the cloud-init configurations. However, I didn’t want to have a random http server running in the background on my host. But I came across an older blog post by a Canonical dev who made an image that they mounted to their VM.

The script below has some extra notes if a reader isn’t too familiar with some of the stuff going on. However, this being my first foray into local VMs I’m not exactly an expert either.

#####################################################################
# Get Ubuntu image
#####################################################################
# TODO: check for newer image and download; otherwise skip
# TODO: Resize image (qemu-img resize [...])
# TODO: Valdiate checksums
# The below line is commented out, but you'll want to run it the first time
#   that you run these commands all together

# wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img # uncomment this so that you get it one time. Then just `cp` it each time you need to adjust from it.
cp ./jammy-server-cloudimg-amd64.img ubuntu.img

#####################################################################
# Delete old key (if exists); Generate new
#####################################################################
# rm ~/.ssh/devEnv* 2&>/dev/null # uncomment to cleanup
ssh-keygen -N "" -t ed25519 -f ~/.ssh/devEnv

#####################################################################
# Create cloud-init config files
#####################################################################
# TODO: Ansible, not just shell ( https://cloudinit.readthedocs.io/en/latest/reference/modules.html#ansible )
# Putting 'User and Groups' things at the root level of the yaml will adjust the default user
# which for Ubuntu, the default user is "ubuntu"
cat << EOF > user-data
#cloud-config
# password: letmein # uncomment if you need to have a password set. Otherwise, we're just SSH'ing into the box and you have passwordless sudo by default
ssh_authorized_keys:
  - $(cat ~/.ssh/devEnv.pub)
chpasswd:
  expire: False
runcmd:
  - echo "Run any command we want!" > /home/ubuntu/test.txt
EOF
cat << EOF > meta-data
instance-id: someid/somehostname
local-hostname: jammy
EOF
# Create the image that will house that the cloud-init configurations
cloud-localds /mnt/speedy/images/seed.img user-data meta-data

#####################################################################
# Start the VM
#####################################################################
# TODO: Optimize settings to be used
# To exit the VM from the cli:
#   Press "Ctrl-a", release, then press "x"
qemu-system-x86_64                         \
-device virtio-net-pci,netdev=net0         \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-machine accel=kvm:tcg                     \
-cpu host                                  \
-m 4G                                      \
-nographic                                 \
-hda ubuntu.img                            \
-hdb seed.img

#####################################################################
# SSH! (open a different shell window)
#####################################################################
# TODO: Figure a way to not have to reset known_hosts constantly?
# rm ~/.ssh/known_hosts* # cleanup 
# ssh -i ~/.ssh/devEnv -p 2222 [email protected]

Outstanding Questions:

I’m quite new when it comes to using QEMU, and looking to both understand deeper in what it comes to virtualization and optimization. My use case going forward is eventually running rancher ( https://www.rancher.com/ ) to setup a k8s cluster. If it’s relevant here’s details about my laptop where i’ll be doing all of this on ( Pangolin (pang12) - System76 Technical Documentation ). Right now my mentality is “get things working first, then optimize”, but if there’s something obvious out there to read/learn from that somehow I didn’t find, please do share :slight_smile:

Next steps

Probably setting up cloud-init to utilize ansible or the current runcmd modules to setup Rancher and get a k8s cluster up and running. (Maybe also rewrite this script in a language a bit more robust than just bash).

Hopefully someone finds this neat and/or helpful.

1 Like

you can ssh-keygen -R $HOSTNAME to clean up a specific key.

1 Like