Debian VM on SmartOS hypervisor
This is a second post of the series on minimal Linux VMs deployments on SmartOS hypervisor. Same as in case of Gentoo I decided to go with systemd and btrfs for system & service management and main/only filesystem respectively.
Environment outline
I’m trying to keep things relatively tidy, especially on my production and semi-production boxes. Hence, I have two directories – one for storing ISOs and templates of VMs:
- /opt/iso
- /opt/templates
For installation purposes I’m going to use SystemRescueCD as I want to perform installation via debootstrap:
cd /opt/iso
curl -kLO http://downloads.sourceforge.net/project/systemrescuecd/sysresccd-x86/4.3.1/systemrescuecd-x86-4.3.1.iso
Feel free to use any other LiveCD that suits you. grml might be even better choice as it’s Debian-based.
And here’s json template for Debian box:
{
"autoboot": false,
"brand": "kvm",
"ram": "512",
"vcpus": "4",
"alias": "12-debian",
"resolvers": ["8.8.8.8", "8.8.4.4"],
"nics": [
{
"nic_tag": "dmz0",
"ip": "192.168.0.12",
"gateway": "192.168.0.1",
"netmask": "255.255.255.0",
"allow_ip_spoofing": "1",
"model": "virtio",
"primary": true
},
{
"nic_tag": "lan",
"ip": "10.0.0.12",
"netmask": "255.255.255.0",
"model": "virtio"
}
],
"disks": [
{
"boot": true,
"model": "virtio",
"size": 10240
}
]
}
You may want to read a bit more about certain parts of configuration provided above in my post about Gentoo.
Generating & booting VM
Once template is prepared, VM generating is fairly easy:
vmadm create < /opt/templates/debian.json
Successfully created VM b0a9eb23-2cae-4d25-bb04-5556825a86c1
Note down or export the UUID as it will come in handy later on:
debian=b0a9eb23-2cae-4d25-bb04-5556825a86c1
echo $debian
b0a9eb23-2cae-4d25-bb04-5556825a86c1
Copy ISO to the root of the newly generated VM:
cp /opt/iso/systemrescuecd-x86-4.3.1.iso /zones/$debian/root/debian.iso
Now it’s time to boot it up with CD as first booting device:
vmadm boot $debian order=cd,once=d cdrom=/debian.iso,ide
If, like me, you are using ipf
as firewall, remember to open VNC port for connection (cause even though SSH is enabled by default in SystemRescueCD, you still need to set password for root account), to open port for SSH for the virtual machine (2222 for example) and to set NAT on that port to point to VM.
Check VNC port vmadm info $debian vnc
:
{
"vnc": {
"host": "94.23.237.217",
"port": 61997,
"display": 56097
}
}
Now open SSH and VNC in /etc/ipf/ipf.conf
:
[...]
# Allow SSH access to Gentoo VM
pass in quick proto tcp from any to any port = 2222 flags S/FSRPAU keep state keep frags
[...]
# Allow VNC access to Gentoo VM
pass in quick proto tcp from any to any port = 52753 flags S/FSRPAU keep state keep frags
[...]
Set NAT in /etc/ipf/ipnat.conf
:
[...]
# SSH -> Gentoo VM
rdr e1000g0 0.0.0.0/0 port 2222 -> 192.168.0.12 port 22
Reload rules:
/usr/sbin/ipf -E -Fa -v -f /etc/ipf/ipf.conf
/usr/sbin/ipnat -FC -v -f /etc/ipf/ipnat.conf
Confirm new settings via:
ipfstat -io
ipnat -l
Launch VNC client, connect to the VM and installation shall begin (:
Debian installation
Remember to connect via VNC client in following manner: <hypervisor-ip>:<VNC port for VM>
(where VNC port is the one that was gathered via vmadm info
command earlier on). Once connected make sure that both network interfaces are up and running and that at least one can reach outside world.
If both prerequisites are met, it’s time to start SSH and to set password for the root account:
service sshd start
passwd
Cool, let’s carry on with installation through SSH:
ssh -p 2222 -l root <ip address of a hypervisor>
Keep in mind that 2222 is only an example and you need to set it accordingly in NAT (look up). You may also close the VNC connection and port (unless for any given reason you wish to keep it – it may come in handy when things will go south during SSH connection) right after establishing connectin via SSH.
Partitioning
Determine disk(s) name(s):
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 389.3M 0 rom /livemnt/boot
sr1 11:1 1 1024M 0 rom
vda 252:0 0 10G 0 disk
loop0 7:0 0 275.1M 1 loop /livemnt/squashfs
In my case, I have only one disk called /dev/vda that is 10G big.
parted -a optimal /dev/vda
mklabel gpt
unit mib
mkpart gpt_bios 1 3
set 1 bios_grub on
mkpart swap 3 2051
mkpart btrfs 2051 -1
q
Above I’m using parted to create gpt partition table. There’s part of the disk for gpt handling (gpt_bios that’s 2M big) with flag for bios_grub, swap partition (2G big) and rest is for btrfs to handle.
And confirm the layout:
parted /dev/vda p
Model: Virtio Block Device (virtblk)
Disk /dev/vda: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 3146kB 2097kB gpt_bios bios_grub
2 3146kB 2151MB 2147MB swap
3 2151MB 10.7GB 8586MB btrfs
OK, let’s create and activate swap partition on vda2 and create btrfs file system on vda3:
mkswap /dev/vda2
swapon /dev/vda2
mkfs.btrfs /dev/vda3
btrfs subvolumes
OK, swap and btrfs created. Now it’s time to configure subvolumes and mount them properly:
mkdir /mnt/{debian,target}
mount -t btrfs -o rw,noatime,nodiratime,space_cache /dev/vda3 /mnt/target
cd /mnt/target
btrfs subvolume create @
btrfs subvolume create @boot
btrfs subvolume create @home
btrfs subvolume create @var
btrfs subvolume create @varlog
mount -t btrfs -o rw,noatime,nodiratime,space_cache,subvol=@ /dev/vda3 /mnt/debian
mkdir -p /mnt/debian/{boot,home,var}
mount -t btrfs -o rw,noatime,nodiratime,space_cache,nodev,nosuid,subvol=@home /dev/vda3 /mnt/debian/home
mount -t btrfs -o rw,noatime,nodiratime,space_cache,nodev,nosuid,noexec,subvol=@boot /dev/vda3 /mnt/debian/boot
mount -t btrfs -o rw,noatime,nodiratime,space_cache,subvol=@var /dev/vda3 /mnt/debian/var
mkdir -p /mnt/debian/var/log
mount -t btrfs -o rw,noatime,nodiratime,nodev,nosuid,noexec,space_cache,subvol=@varlog /dev/vda3 /mnt/debian/var/log
Confirm that all subvolumes have properly set mountpoints:
mount | grep btrfs
/dev/vda3 on /mnt/target type btrfs (rw,noatime,nodiratime,space_cache)
/dev/vda3 on /mnt/debian type btrfs (rw,noatime,nodiratime,space_cache,subvol=@)
/dev/vda3 on /mnt/debian/home type btrfs (rw,noatime,nodiratime,nodev,nosuid,space_cache,subvol=@home)
/dev/vda3 on /mnt/debian/boot type btrfs (rw,noatime,nodiratime,nodev,nosuid,noexec,space_cache,subvol=@boot)
/dev/vda3 on /mnt/debian/var type btrfs (rw,noatime,nodiratime,space_cache,subvol=@var)
/dev/vda3 on /mnt/debian/var/log type btrfs (rw,noatime,nodiratime,nodev,nosuid,noexec,space_cache,subvol=@varlog)
Let’s clean it up:
cd
umount /mnt/target
rmdir /mnt/target
I took subvolume naming convention from Ubuntu and ever since I’m using it pretty much everywhere where I’m dealing with btrfs. Feel free to try any other or stick to this one if it appeals to you too.
Debootstrap deployment
Once disks & partitions are dealt with, it’s time for OS deployment:
debootstrap --arch amd64 testing /mnt/debian http://ftp.fr.debian.org/debian/
Right after it finish, environment is ready for configuration.
chroot
To avoid any unpleasant surprises, be sure to mount and bind proc
, /sys
and /dev
:
mount -t proc proc /mnt/debian/proc
mount --rbind /sys /mnt/debian/sys
mount --rbind /dev /mnt/debian/dev
LANG=C.UTF-8 chroot /mnt/debian /bin/bash
export TERM=xterm-color
OK, it’s time to configure APT – personally I dislike the default option forcing me to install everything from recommended section of the packge upon installation. Hence:
cat << EOF > /etc/apt/apt.conf.d/02recommends
APT::Install-Recommends "0";
EOF
It’s time to install some vital stuff:
apt-get update
apt-get install btrfs-tools dbus locales openssh-server vim-nox
Quick fix for df
/systemd
setting:
ln -sf /proc/self/mounts /etc/mtab
Set up locales and timezone:
dpkg-reconfigure locales tzdata
Install kernel:
apt-get install linux-image-amd64
There’s a known bug with 3.13+ kernels and btrfs being default filesystem on a root partition. Here’s a fix:
cat << EOF >> /etc/initramfs-tools/modules
libcrc32c
EOF
Be sure to update initrd:
update-initramfs -u -k all
GRUB installation
apt-get install grub2
And here’s quick config.
cat << EOF > /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet init=/lib/systemd/systemd"
GRUB_CMDLINE_LINUX=""
EOF
Note GRUB_CMDLINE_LINUX_DEFAULT having special init
parameter providing path to systemd.
Regenerate config:
update-grub
Deploy filesystem configuration to /etc/fstab
:
cat << EOF > /etc/fstab
/dev/vda3 / btrfs rw,noatime,nodiratime,space_cache,subvol=@ 0 1
/dev/vda3 /home btrfs rw,nodev,nosuid,noatime,nodiratime,space_cache,subvol=@home 0 1
/dev/vda3 /boot btrfs rw,nodev,nosuid,noexec,noatime,nodiratime,space_cache,subvol=@boot 0 1
/dev/vda3 /var btrfs rw,noatime,nodiratime,space_cache,subvol=@var 0 1
/dev/vda3 /var/log btrfs rw,nodev,nosuid,noexec,noatime,nodiratime,space_cache,subvol=@varlog 0 1
/dev/vda2 none swap sw 0 0
EOF
Setting up networking
I could use DHCP to handle networking for me, but that would require additional daemon which I don’t really need. That’s why I decided to stick with static configuration:
cat << EOF > /etc/network/interfaces
auto lo
iface lo inet loopback
allow-hotplug eth0
iface eth0 inet static
address 192.168.0.12
netmask 255.255.255.0
gateway 192.168.0.1
broadcast 192.168.0.255
allow-hotplug eth1
iface eth1 inet static
address 10.0.0.12
netmask 255.255.255.0
EOF
Finishing touches
Before reboot make sure to set password for root account. You may also want to turn on ssh
daemon:
passwd
systemctl enable ssh
This is it – exit, unmount & reboot:
exit
cd
umount -l /mnt/debian/dev{/shm,/pts,}
umount -l /mnt/debian{/boot,/proc,}
reboot
After reboot
Set hostname:
hostnamectl set-hostname debian
Summary
Once everything is done and you are able to connect to your VM, you should have fairly plain system as a starting point. OS is ready to serve its purpose and is ideal for further adjustments and enhancements. Enjoy! (:
Discussion