What follows is an article about how I recently rebuilt a single-purpose home NAS into a multi-purpose data services machine, all while keeping the data storage structures untouched and completely intact.
Plan for about 10 minutes to read this article.
Data storage is boring
A couple years ago I built a NAS for personal use. I wanted a place to store personal images, ripped DVDs, music, and other content without relying on various public cloud share services. The build was an enjoyable and rewarding endeavor that resulted in cramming a pair of 2TB NAS drives into a mini-ITX sized case with OpenIndiana as the operating platform. This opensolaris derivative seemed the obvious choice for a NAS as ZFS offered all the features I was used to in the enterprise: snapshots, ARC caching and intent logging to name a few. (I also wanted to keep my ZFS skills sharp as I transition away from hands-on roles in my career).
However, once the data pool was created and the NFS, SMB and CIFS services were running a functioning NAS is a pretty boring device. It wasn’t long before I started considering all the data services I could run with the data I was now storing: media servers, backup, and download services to name a few. The challenge was that few of these applications run native on OpenIndiana. The desired scope of my this home server was creeping outside its original design.
A more intelligent solution requires a smarter OS
Enter Joyent’s SmartOS: a modern hypervisor-like operating system, also derived from opensolaris, which promised the ability to run container-like VMs (or branded zones) on top of a familiar ZFS-enabled operating platform. That last part was key because it meant that I could swap out the operating system of the NAS and keep the ZFS pools that hold all my data intact. This backwards compatibility meant no dump and restore.
Installation and Migration
The first thing I learned about SmartOS is that the boot device resides permanently on an external USB while the root of the filesystem is stored locally. The benefits of this model are explained on the SmartOS Wiki. For me it meant my sleek black box now has a permanent dongle attachment and lacks in aesthetics.
SmartOS tried to make some assumptions about which disks should comprise it’s new root system, electing one of my data mirrors as a candidate. Instead, I cautiously took a manual approach of creating the zones ZFS myself to make absolutely certain my data pool remained untouched.
# zpool destroy rpool
# zpool create zones c0t0d0
The first command was the point of no return, resulting in the destruction of my OpenIndiana installation. The second command repurposed the single root disk for a pool called zones, which is what the SmartOS installation is expecting before proceeding. Once the installation was complete, I was relieved to see my data pool mounted with all the filesystems intact. What I was quick to notice was that there were new features available on these pools that weren’t present with OpenIndiana. Kudos to the SmartOS development community for their contribution to ZFS.
Virtual Machine Configuration
My immediate priorities were to create two VMs:
- a native SmartOS VM to run SMB services
- a Linux branded VM to run Plex Media Server.
Creating a VM involves combining two ingredients:
- An image, which is a preconfigured operating system in the form of a compressed ZFS dataset.
- A JSON configuration file: A file that defines the metadata for the VM: It’s name, it’s boot properties, it’s network interfaces and mounted filesystems.
First I downloaded the most up to date image each of these operating environments. Each image in the repository, whether it’s SmartOS native, Ubuntu Linux, CentOS or what have you, is represented by a unique UUID. The index of these UUIDs is available with the imgadm avail command.
# imgadm sources -a https://updates.joyent.com
# imgadm import 62f148f8-6e84-11e4-82c5-efca60348b9f
# imgadm import 818cc79e-ceb3-11e4-99ee-7bc8c674e754
Details on SmartOS image management can be found here.
Next I built JSON configuration files for each virtual machine I wanted to create. You can google-and-paste recipes for this, but it’s worth reading more on how virtual machines work before you build your first real one. Online examples don’t often make use of all the available options.
Notice that the JSON file defines the brand and image UUID used by the VM, as well as it’s network and storage configuration. Being able to use loopback filesystems inside the VMs obviates the need to run an NFS server in the hypervisor (or global zone). Simpler is better.
Once these template files are created, spinning up the VM is all that remains.
# vmadm validate create -f plex.json
# vmadm validate create -f smb.json
# vmadm create -f plex.json
# vmadm create -f smb.json
# vmadm list
UUID TYPE RAM STATE ALIAS
62f148f8-6e84-11e4-82c5-efca60348b9f OS 1024 running smb
818cc79e-ceb3-11e4-99ee-7bc8c674e754 OS 4096 running plex
From here, I still need to configure the services from within the VMs, but I’ve successfully created the virtual instances within which they will run.
Thanks to SmartOS, my NAS is no longer a boring storage device, but rather a multi-purpose data services machine. With the freedom to run a multitude of operating platforms, the possibilities are limited only by my imgination….well…and my available RAM.