Skip to content

Instantly share code, notes, and snippets.

@ThinGuy
Created January 30, 2025 16:08
Show Gist options
  • Save ThinGuy/cdb432627f0e4ab4138ce4502b7a558b to your computer and use it in GitHub Desktop.
Save ThinGuy/cdb432627f0e4ab4138ce4502b7a558b to your computer and use it in GitHub Desktop.
One Box Microcloud - Nesting a Microcloud under LXD
name: microcloud-base
description: MicroCloud Base VM Profile
config:
boot.autostart: "true"
linux.kernel_modules: br_netfilter
user.network-config: |
renderer: networkd
version: 2
ethernets:
enp5s0: {}
enp6s0: {}
enp7s0: {}
enp8s0: {}
bridges:
br0:
dhcp4: true
dhcp6: true
optional: false
interfaces: [enp5s0]
accept-ra: false
parameters:
priority: 0
stp: false
routes:
- to: default
via: 192.168.110.1
metric: 1
br1:
dhcp4: true
dhcp6: true
optional: false
interfaces: [enp6s0]
br2:
dhcp4: true
dhcp6: true
optional: false
interfaces: [enp7s0]
user.user-data: |
#cloud-config
final_message: |
Cloud-Init has finished configuring this MicroCloud node
Cloud-Init Version: $version
Completion Tmes: $timestamp
Cloud-Init Datasource: $datasource
System Uptime: $uptime
manage_etc_hosts: false
groups:
- ubuntu
users:
- name: ubuntu
uid: 1000
homedir: /home/ubuntu
gecos: default
groups: ubuntu, adm, audio, cdrom, dialout, dip, floppy, kvm, libvirt, libvirt-qemu, lxd, netdev, plugdev, render, sudo, tty, video
primary_group: ubuntu
lock_passwd: false
passwd: $6$rounds=4096$ox6T7Xv0j9sYJhd7$VIw3A8RVAHAP/vfZFJFNOupES3IqL4M64TjHTKYNmCAiNzZN0I3hdLGYGj7ppFYU0Nzc6Wn7EgkyKzK.afkBB0
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_import_id: ['lp:craig-bender', 'gh:ThinGuy']
timezone: 'America/Los_Angeles'
locale: 'en_US.UTF-8'
ssh_pwauth: true
apt:
conf: |
APT {
Get {
Assume-Yes "True";
Fix-Broken "True";
};
Acquire {
ForceIPv4 "True";
};
};
primary:
- arches: [amd64]
uri: http://us.archive.ubuntu.com/ubuntu
security:
- arches: [amd64]
uri: http://us.archive.ubuntu.com/ubuntu
sources_list: |
deb [arch=amd64] $PRIMARY $RELEASE main universe restricted multiverse
deb [arch=amd64] $PRIMARY $RELEASE-updates main universe restricted multiverse
deb [arch=amd64] $SECURITY $RELEASE-security main universe restricted multiverse
deb [arch=amd64] $PRIMARY $RELEASE-backports main universe restricted multiverse
deb [arch=amd64] $PRIMARY $RELEASE-proposed main universe restricted multiverse
snap:
commands:
00: ['refresh', 'lxd', '--channel', '5.21/stable' ,'--cohort="+"']
01: ['install', 'microcloud', '--channel=latest/stable', '--cohort="+"']
02: ['install', 'microceph', '--channel=quincy/stable', '--cohort="+"']
03: ['install', 'microovn', '--channel=22.03/stable', '--cohort="+"']
04: ['install', 'yq']
05: ['install', 'wormhole']
package_update: true
package_upgrade: true
packages: [build-essential, debconf-utils, dhcpdump, dnsutils, dpkg-dev, gnupg-agent, ipcalc, iputils-arping, jq, linux-image-virtual-hwe-22.04-edge, linux-image-extra-virtual-hwe-22.04-edge, prips, python3-pip, setserial, software-properties-common, unzip, wget, whois]
bootcmd:
- ['cloud-init-per', 'once', 'bc0', 'sh', '-c', 'echo "\e[0;1;38;2;255;255;255m╔════════════════════════╗\e[0m\n\e[0;1;38;2;255;255;255m║\e[0;1;38;2;255;255;255m\e[0;1;48;2;0;60;0m Starting BOOTCMDs \e[0;1;38;2;255;255;255m║\e[0m\n\e[0;1;38;2;255;255;255m╚════════════════════════╝\e[0m\n"']
# This command lets us know if our cloud-init data was parsed correctly
- ['cloud-init-per', 'once', 'bc1', 'cloud-init', 'schema', '--system']
- ['cloud-init-per', 'once', 'bc2', 'set', '-x']
- ['cloud-init-per', 'once', 'bc3', 'export', 'DEBIAN_FRONTEND=noninteractive']
# Fix hosts file
- ['cloud-init-per', 'once', 'bc4', 'sh', '-c', 'sed -r -i "/127.0.1.1/d;/127.0.0.1/a $(ip -o -4 a show dev $(ip -o route show default|grep -m1 -oP "(?<=dev )[^ ]+")|grep -m1 -oP "(?<=inet )[^/]+")\\x20\\x20$(hostname -s).microcloud.orangebox.me\x20$(hostname -s)" /etc/hosts']
- ['cloud-init-per', 'once', 'bc5', 'hostname', '-f']
# Insert configuration for for systemd-resolved (/etc/systemd/resolved.conf)
- ['cloud-init-per', 'once', 'bc6', 'sh', '-c', 'echo "W1Jlc29sdmVdCkROUz0xOTIuMTY4LjExMC4xCkZhbGxiYWNrRE5TPTEuMS4xLjEKRG9tYWlucz1taWNyb2Nsb3VkLm9yYW5nZWJveC5tZQpETlNTRUM9YWxsb3ctZG93bmdyYWRlCkROU092ZXJUTFM9b3Bwb3J0dW5pc3RpYwpNdWx0aWNhc3RETlM9eWVzCkxMTU5SPXllcwpDYWNoZT1uby1uZWdhdGl2ZQpDYWNoZUZyb21Mb2NhbGhvc3Q9eWVzCkROU1N0dWJMaXN0ZW5lcj15ZXMKI0ROU1N0dWJMaXN0ZW5lckV4dHJhPQpSZWFkRXRjSG9zdHM9eWVzClJlc29sdmVVbmljYXN0U2luZ2xlTGFiZWw9eWVzCg=="|base64 -d|tee 1>/dev/null /etc/systemd/resolved.conf']
# Remove deprecated resolv.conf and create correct symlink to systemd-resolved
- ['cloud-init-per', 'once', 'bc7', 'sh', '-c', 'rm -f /etc/resolv.conf']
- ['cloud-init-per', 'once', 'bc8', 'sh', '-c', 'ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf']
- ['cloud-init-per', 'once', 'bc9', 'sh', '-c', 'systemctl restart systemd-resolved.service']
- ['cloud-init-per', 'once', 'bc10', 'apt-get', 'install', '--auto-remove', '--purge', '-yf', '--option=Acquire::ForceIPv4=true']
- ['cloud-init-per', 'once', 'bc11', 'sh', '-c', 'echo "GRUB_DISABLE_OS_PROBER=false"|tee -a /etc/default/grub']
- ['cloud-init-per', 'once', 'bc12', 'set', '+x']
- ['cloud-init-per', 'once', 'bc13', 'sh', '-c', 'echo "\e[0;1;38;2;255;255;255m╔════════════════════════╗\e[0m\n\e[0;1;38;2;255;255;255m║\e[0;1;38;2;255;255;255m\e[0;1;48;2;0;60;0m Finished BOOTCMDs \e[0;1;38;2;255;255;255m║\e[0m\n\e[0;1;38;2;255;255;255m╚════════════════════════╝\e[0m\n"']
runcmd:
- set +x
- sh -c 'echo "\e[0;1;38;2;255;255;255m╔═══════════════════════╗\e[0m\n\e[0;1;38;2;255;255;255m║\e[0;1;38;2;255;255;255m\e[0;1;48;2;0;60;0m Starting RUNCMDs \e[0;1;38;2;255;255;255m║\e[0m\n\e[0;1;38;2;255;255;255m╚═══════════════════════╝\e[0m\n"';
- set -x
# Enable Grub's OS Prober
- echo GRUB_DISABLE_OS_PROBER=false|tee -a /etc/default/grub
# Set debconf/dpkg not to prompt/ask for information during runcmds
- export DEBIAN_FRONTEND=noninteractive
# Remove vim formatoption for adding a comment on every O/o
- install -o$(id -un 1000) -g$(id -gn 1000) -m0600 /dev/null /home/$(id -un 1000)/.vimrc
- echo 'au BufEnter * set fo-=c fo-=r fo-=o' > /home/$(id -un 1000)/.vimrc
# Get IP/CIDR
- export DEFAULT_IP=$(ip -o -4 a show dev $(ip -o route show default|grep -m1 -oP '(?<=dev )[^ ]+')|grep -m1 -oP '(?<=inet )[^/]+')
- export DEFAULT_CIDR=$(ip -o -4 a show dev $(ip -o route show default|grep -m1 -oP '(?<=dev )[^\s]+')|grep -m1 -oP '(?<=inet )[^\s]+')
# Prefer IPv4 for destinations and restart networking
- "echo 'precedence ::ffff:0:0/96 100'|tee -a /etc/gai.conf"
# Restart networking for IPv4 stack preference takes effect
- systemctl restart systemd-networkd
# Source OS Release information
- . /etc/lsb-release
# Set vim as default EDITOR system-wide
- echo 'EDITOR=/usr/bin/vim.basic'|tee 1>/dev/null -a /etc/environment
# Set vim.basic as primary editor in list of alternatives
- if [ -f /usr/bin/vim.basic ];then update-alternatives --set editor /usr/bin/vim.basic;fi
# Source the updated /etc/environment file
- . /etc/environment
# Allow non-root users to use/query fuse-based filesystems (mainly removes error when find searches a fuse filesystem)
- if $(test -f /etc/fuse.conf);then sed -i 's/^#user_allow/user_allow/g' /etc/fuse.conf;fi
# Configure ssh for X11 forwarding
- sed -r -i 's/^#?(AllowAgentForwarding|AllowTcpForwarding|X11Forwarding|PermitTTY|PasswordAuthentication|PubkeyAuthentication)[^$]*/\1 yes/g;s/^#?(X11UseLocalhost)[^$]*/\1 no/;s/^#(X11DisplayOffset)[^$]*/\1 100/;s/^#?(PermitRootLogin)[^$]*/\1 no/' /etc/ssh/sshd_config
- systemctl restart ssh
# Create SSH Keys for default user
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then true;else mkdir -p /home/$(id -un 1000)/.ssh/;fi'
- if [ -d /home/$(id -un 1000)/.ssh ];then chown -R $(id -un 1000):$(id -gn 1000) /home/$(id -un 1000)/.ssh;fi
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then ssh-keygen -t rsa -b 4096 -f /home/$(id -un 1000)/.ssh/id_rsa -P "";fi'
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then ssh-keygen -t ecdsa -b 521 -f /home/$(id -un 1000)/.ssh/id_ecdsa -P "";fi'
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then ssh-keygen -t dsa -b 1024 -f /home/$(id -un 1000)/.ssh/id_dsa -P "";fi'
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then ssh-keygen -t ed25519 -f /home/$(id -un 1000)/.ssh/id_ed25519 -P "";fi'
- su - $(id -un 1000) -c 'if [ -d /home/$(id -un 1000)/.ssh ];then cat /home/$(id -un 1000)/.ssh/*.pub|tee 1>/dev/null -a /home/$(id -un 1000)/.ssh/authorized_keys;fi'
- echo 0|tee /proc/sys/net/ipv6/conf/enp7s0/accept_ra
- echo 0|tee /proc/sys/net/ipv6/conf/enp8s0/accept_ra
- set +x
- sh -c 'echo "\e[0;1;38;2;255;255;255m╔═══════════════════════════════════╗\e[0m\n\e[0;1;38;2;255;255;255m\e[0;1;38;2;255;255;255m\e[0;1;48;2;0;60;0m IP Address = '$DEFAULT_IP' \e[0m\n\e[0;1;38;2;255;255;255m╚═══════════════════════════════════╝\e[0m\n"';
- sh -c 'echo "\e[0;1;38;2;255;255;255m╔═══════════════════════╗\e[0m\n\e[0;1;38;2;255;255;255m║\e[0;1;38;2;255;255;255m\e[0;1;48;2;0;60;0m Finished RUNCMDs \e[0;1;38;2;255;255;255m║\e[0m\n\e[0;1;38;2;255;255;255m╚═══════════════════════╝\e[0m\n"';
devices:
config:
source: cloud-init:config
type: disk
enp5s0:
name: enp5s0
nictype: bridged
parent: br0
type: nic
root:
path: /
pool: default
size: 30GiB
type: disk
vtpm:
path: /dev/tpm0
type: tpm
export LXD_LOCAL_POOL=default
export VM_CPUS=16
export VM_RAM=32GiB
export VM_AUTOSTART=true
export CEPH_VOL_SIZE=200GiB
mc-kill() {
export LXD_LOCAL_POOL=default
for NODE in {001..003};do
for VM in {1..3};do lxc 2>/dev/null delete microcloud-${NODE} -f;done;
for PROF in {1..3};do lxc 2>/dev/null profile delete microcloud-${NODE};done;
for VOL in {1..3};do lxc 2>/dev/null storage volume delete ${LXD_LOCAL_POOL} microceph_${NODE}_vol;done;
for NET in {1..3};do lxc 2>/dev/null network delete microbr${NET};done;
done;
};export -f mc-kill
mc-build() {
for SUBNET in 1 2;do
lxc network create microbr${SUBNET} \
dns.domain=ubuntupro.xzy \
dns.mode=dynamic \
ipv4.address=172.16.${SUBNET}.1/24 \
ipv4.nat=true \
ipv4.dhcp=true \
ipv4.dhcp.ranges=172.16.${SUBNET}.100-172.16.${SUBNET}.200 \
ipv4.dhcp.gateway=172.16.${SUBNET}.1 \
ipv6.address=fd42:00e9:5420:000${SUBNET}::1/64 \
ipv6.nat=true \
ipv6.dhcp=true \
ipv6.dhcp.ranges=fd42:00e9:5420:000${SUBNET}::64-fd42:00e9:5420:000${SUBNET}::c8 \
ipv6.dhcp.stateful=true
done;
for SUBNET in 3 ;do
lxc network create microbr${SUBNET} \
dns.domain=ubuntupro.xzy \
dns.mode=dynamic \
ipv4.address=172.16.${SUBNET}.1/24 \
ipv4.nat=false \
ipv4.dhcp=false \
ipv6.address=fd42:00e9:5420:000${SUBNET}::1/64 \
ipv6.nat=false \
ipv6.dhcp=false \
ipv6.dhcp.stateful=false
done;
for NODE in {001..003};do
lxc profile copy microcloud-base microcloud-${NODE};
lxc profile set microcloud-${NODE} limits.cpu=${VM_CPUS} limits.memory=${VM_RAM} boot.autostart=${VM_AUTOSTART} boot.autostart.priority="$((10#${NODE}))" boot.autostart.delay="$((10#${NODE}*5))"
[[ ${NODE} = 001 ]] && { lxc profile set microcloud-${NODE} boot.autostart.delay="0"; }
lxc storage volume create ${LXD_LOCAL_POOL} microceph_${NODE}_vol size=${CEPH_VOL_SIZE} --type=block
sudo modprobe br_netfilter;
for NIC in {1..3};do
[[ ${NIC} != 3 ]] && { lxc profile device add microcloud-${NODE} enp$((${NIC}+5))s0 nic network=microbr${NIC} name=enp$((${NIC}+5))s0 ipv4.address=172.16.${NIC}.$((10#${NODE}+10)) ipv6.address='fd42:00e9:5420:000'${NIC}':0000:0000:0000:'$(printf "%x" $((10#${NODE}+10)))''; }
[[ ${NIC} = 3 ]] && { lxc profile device add microcloud-${NODE} enp$((${NIC}+5))s0 nic network=microbr${NIC} name=enp$((${NIC}+5))s0; }
done
lxc profile device add microcloud-${NODE} microceph_${NODE}_vol disk pool=${LXD_LOCAL_POOL} source=microceph_${NODE}_vol
lxc launch j-vm microcloud-${NODE} --vm -p microcloud-${NODE}
done;
sleep 20;lxc console microcloud-${NODE};
};export -f mc-build
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment