Running Linux on Linux - Virtual Servers
Posted by Steve on Wed 24 Nov 2004 at 21:41
Thanks to the existance of the user-mode-linux project it is possible to run a complete copy of the GNU/Linux operating system on top of your existing system. These virtual servers are ideal for testing software installations, or setting up mass hosting for customers.
This small introduction will show you how to run a copy of User-Mode-Linux on top of an existing Debian installation, and allow it to access the network.
This system can be used for experimentation, for testing new software, or for running particular services which will be completely isolated from your real machine.
User mode linux, as its name would suggest, runs entirely as a user process with on top of your existing system.
Because it boots up from a virtual filesystem it is possible to install Redhat, Gentoo, or Debian installations. Whatever version of Linux you like.
Here we're going to concentrate upon installing an installation of Debian Stable (woody) on a machine running Debian Unstable. (This is what I use when I'm testing Debian's security.
The guest installation of Woody will have access to the network, and will be able to treated as a complete virtual host.
First of all we need to install the software. As root run:
apt-get install user-mode-linux uml-utilities
This allows us to run a system.
For the system itself we need an operating system image. Much like when we installed Microsoft Windows on top of Debian we need a giant file which the system can treat as it's virtual hard drive.
To run a system you have the choice of creating the filesystem image from scratch yourself, or downloading a pre-made one. Here we are going to use one that Matt Zimmerman created already.
Create a directory to contain your image, and then download it. We will be running our virtual machine as a dedicated user, once we've set it up as root. So we'll create that user and do all the work in it's home directory:
useradd uml groupadd uml mkdir /home/uml cd /home/uml apt-get install wget bzip2 wget http://people.debian.org/~mdz/uml/Debian-3.0r2.ext2.bz2 bunzip2 Debian-3.0r2.ext2.bz2
This gives you a small preinstalled system containing a minimal installation of Debian.
As the image is fairly small (42Mb compressed) we need to resize it to contain some free space. This will allow us to actually have room to install software when it is being used!
Here I'm choosing to make the disk image 2Gb in size. This is plenty of room to install packages on and generally play about with.
dd if=/dev/zero of=Debian-3.0r2.ext2 bs=1 count=0 seek=2G e2fsck -f Debian-3.0r2.ext2 resize2fs -p Debian-3.0r2.ext2
In order for the guest installation to access the network you'll need to pick an access method. I've chosen to use the tun device, as that's the simplest to work with. For a detailed discussion of alternate methods of accessing the network there is some network documentation on the UML website.
The UML process can be run as any user with the caveat that the user must have permission to work with the network. We just need to add the relevent users to the uml-net group:
adduser uml uml-net
Finally you'll need to install the tun kernel module and cause it to be loaded on boot:
modprobe tun echo 'tun' >> /etc/modules
We're almost ready to make the system work now - we just need to make a coulpe of changes to the image file we've downloaded so that it can see the network.
We do this by mounting the image and editing the files within it. Mount the guest image:
mkdir /home/uml/tmp mount -o loop -t ext2 Debian-3.0r2.ext2 /home/uml/tmp
Now we need to setup some of the basic networking settings. We also need to disable the hardware clock as this doesn't work correctly under UML.
These next settings are specific to my home network, but you should be able to change them. What we want to do is give the machine an IP address on the network the host is connected to, with relevent DNS and gateway information.
The simple way to do this is as follows:
rm -f /home/uml/tmp/etc/init.d/hwclock* echo 'uml-240.my.flat' >> /home/uml/tmp/etc/hostname echo 'auto lo eth0' > /home/uml/tmp/etc/network/interfaces echo 'iface lo inet loopback' >> /home/uml/tmp/etc/network/interfaces echo 'iface eth0 inet static' >> /home/uml/tmp/etc/network/interfaces echo 'address 192.168.1.240' >> /home/uml/tmp/etc/network/interfaces echo 'netmask 255.255.255.0' >> /home/uml/tmp/etc/network/interfaces echo 'gateway 192.168.1.1' >> /home/uml/tmp/etc/network/interfaces echo '127.0.0.1 uml240 uml240.my.flat' > /home/uml/tmp/etc/hosts echo 'nameserver 192.168.1.1' > /home/uml/tmp/etc/resolv.conf
Finally we want to setup the machine so that APT will work:
echo 'deb http://http.us.debian.org/debian stable main contrib non-free' \
>/home/uml/tmp/etc//apt/sources.list
echo 'deb-src http://http.us.debian.org/debian stable main contrib non-free' \
>>/home/uml/tmp/etc//apt/sources.list
echo 'deb http://security.debian.org/ woody/updates main contrib non-free' \
>>/home/uml/tmp/etc//apt/sources.list
Once this is done we're almost complete - we just need to make sure that ssh is installed so that we can connect to the image.
Using chroot we can lock ourself into the image and install the openssh server, and setup a password for the root user:
chroot /home/uml/tmp apt-get update apt-get install ssh passwd root
That's our minimal setup complete. Everything else we can setup later, once we've installed the image as a real user mode linux process.
Exit the chroot and unmount the image by running the following commands. Notice that I've also changed the permissions on all the files so our lower privileged user can work with them:
exit umount /home/uml/tmp chown -R uml:uml /home/uml
Everything from here on can be run as the dedicated uml user, which we created earlier.
If you wish setup a password for that user and change to it - if not as root run:
su - uml
You should now be able to boot the virtual linux machine, causing a complete system to be executed as process, using the file Debian-3.0r2.ext2 as it's virtual disk drive. To do this run:
IPADDR=`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`
linux mem=64M ubd0=Debian-3.0r2.ext2 umid=240 con=null \
con0=fd:0,fd:1 con1=none eth0=tuntap,,,$IPADDR
The first line is supposed to find your current IP address, this is needed so that the system that you will be running can route through that to find its way onto the internet.
If you know what it is already you could use something simpler:
IPADDR=192.168.1.50 linux mem=64M ubd0=Debian-3.0r2.ext2 umid=240 con=null \ con0=fd:0,fd:1 con1=none eth0=tuntap,,,$IPADDR
You should now see your linux system boot up in the console in front of you.
You can now login remotely using the installed openssh server, and work with it as if it were a real machine far far away!
When you're finished with it make sure that you terminate it cleanly, when logged into it as root run:
/sbin/halt
Do not attempt to run /sbin/reboot as this will fail.
Once you're happy with the way it's working you can set it up to run in the background, via screen, or similar.
The way I do that is to run the following script, which I saved as /home/uml/start:
#!/bin/sh
IPADDR=`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`
screen -S uml-240 -d -m \
linux mem=64M ubd0=Debian-3.0r2.ext2 \
umid=240 con=null \
eth0=tuntap,,,$IPADDR
This runs a screen session called 'uml-240' in the background, you can attach to this by running:
screen -R uml-240
And detach again later with 'Ctrl-A d'.
Because we've installed the uml-utilities package we can also interface with our running system via the uml-mconsole program. This takes the ID of a running system as an argument, the ID corresponds to the umid parameter we used in our startup script.
So to connect to our example system we use:
uml_mconsole 240
Now you can type 'help' to get a list of commands.
That's the end of our introduction, but hopefully enough to get you up and running with a virtual server installation.
good article about uml, how about a follow up about xen?
Sincerely,
Jan.
[ Parent | Reply to this comment ]
Great incantation. When reading what dd manpage/infopage has to say, it does not become apparent that this command will change the size of the output file. How do you guys know this stuff? Does one have to have some Unix programming experience to use Unix to its fullest as a sysadmin?
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Well it certainly helps!
Steve
--
[ Parent | Reply to this comment ]
Folowing these instructions I encountered a problem with something spawning too fast. To fix this I changed the /etc/inittab file whilst the new file system was mounted. I changed the following section to read as thus:
0:1235:respawn:/sbin/getty 38400 console linux
#1:2345:respawn:/sbin/getty 38400 tty1
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6
[ Parent | Reply to this comment ]
Starting periodic command scheduler: cron.
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes
i really want to use UML to taste diff distros as i use only debian on my single 80 gb partition.
[ Parent | Reply to this comment ]
Pardon this silly question but how does this differ from 'qemu' per your article:
http://www.debian-administration.org/articles/40
In other words, can I do the same w/ "qemu"?
Thx Attila
[ Parent | Reply to this comment ]
You can achieve the same goal with both.
The advantage of UML (which is why I got to this article) is that it should make it easier to debug kernel code - just attach GDB to the UML process and off you go. Apart from that, Qemu might be faster (and it can run any OS, not just Linux) but I'm not even sure about the speed advantage after the reading some comparison I saw recently.
BTW - this article seems to be a bit out of date for Etch (e.g. the "groupadd" command is unnecessary, it's possible to setup an "image" using debootstrap instead of downloading the particular one suggested in the article)
[ Parent | Reply to this comment ]
[ Send Message ]
can one install it from unstable 'cleanly' (i.e. only via apt-get) or is that not advisable on a sarge-exclusive system?
[ Parent | Reply to this comment ]