1
1
freepoteries-doc/content/new_vm.rst
2021-09-13 22:57:03 +02:00

408 lines
14 KiB
ReStructuredText

new virtual machine
###################
:date: 2019-11-10 00:00
:modified: 2021-09-13 00:00
:tags: infra
:category: documentation
:slug: create_vm
:authors: Ms.Leave-A-Mix
:summary: How-To install a new virtual machine with libvirt
This is an how-to, and it's goal is not to explain how virtual machines with
Libvirt/KVM work. For more information, see wikipedia or libvirt_ website.
.. _libvirt: https://libvirt.org
-----------------
Create the domain
-----------------
First of all, we create an XML based file that will describe the attributes of
our new virtual machine. Important points are : name, number of virtual CPUs, maximum amount
of RAM dedicated to the machine, base filesystem, boot device and network.
Here is a template to fill : domain.xml_ (save as)
After everyhing is set up, define this domain using the "virsh" tool.
:code:`virsh define <my_domain.xml>`
.. _domain.xml: /static/domain-base.xml
-------------------------
Create the storage device
-------------------------
We'll use an LVM storage device for this virtual machine, this is the standard
way to do on Freepoteries' server. Choose wisely the name, and size of the
volume.
:code:`lvcreate --name rootfs-<my_domain> --size 5G vg0`
Then, refresh the *already defined* pool with virsh.
:code:`virsh pool-refresh vg0`
--------------------------
Use a new distribution iso
--------------------------
*This is an optional step, only if you need an distro's iso that is not already
stored on the server*
The iso's are all stored on the vg0/iso volume that is mounted on /mnt/iso. If
the ones that are available don't fit your needs, you may add a new one by
downloading it directly in that folder. When it's done, refresh the iso pool of
libvirt, with virsh.
:code:`virsh pool-refresh iso`
Be sure to change the "volume" attribute of the "source" node in the domain XML,
by specifying the name of your iso file. You can check that your iso has been
registered by libvirt by the following command.
:code:`virsh vol-list iso`
------------------------
Boot the virtual machine
------------------------
*If it's a new installation from an iso file, be sure to specify the boot device
as "cdrom" in the VM's xml. Check this with the following command*
:code:`virsh dumpxml <my_domain>|grep "<boot dev="`
If this command output looks like this : :code:`<boot dev='hd'/>`, you're not in
the right way. Edit the VM's definition with :code:`virsh edit <my_domain>`, and
change the *dev* attribute of the *boot* node to *cdrom*: :code:`<boot
dev='cdrom'/>`.
Now that everything is read, the start command can be invoked.
:code:`virsh start <my_domain>`
If this command outputs the following : :code:`Domain <my_domain> started`, your
domain is booting : smooth!
---------------------------------
Virtual machine's OS installation
---------------------------------
We now need a way to communicate with the VM, so we can setup the new system.
Rare are the distributions that gives us an SSH access as the iso is booted. We
then need to use another remote-control technology, that's handled by libvirt.
It's name is VNC_ : Virtual Network Computing. It works as a client-server
protocol, and here is how you can connect to it. You will need to act on the
server, by ssh, and on your own machine. To help you differ on which machine the
actions are done, I'll define 3 entities :
- local: your own machine's OS, that is physically in front of you
- server: the remote server's OS, on which you are usually connect via SSH
- vm: the remote virtual machine, that is running on the server
First of all, define on which port the VNC server for your VM is running :
:code:`(server)# virsh domdisplay <my_domain>`
If the output of this command is : :code:`vnc://127.0.0.1:37`, that means that
the VNC port is **5937** (not 37!!), you must now make something that
demonstrate the power of SSH. This is named `SSH Tunnelling`_! Locally, you can
create a tunnel with this simple command example :
:code:`(local)$ ssh <user>@<server.ip> -L <local_port>:127.0.0.1:<remote_port>`
This magic will simply redirect all your local calls on **<local_port>** to the
**<server.ip**> **<remote_port>**. You can try this with the following example :
.. code-block:: bash
(server)# nc -l -s 127.0.0.1 -p 4242 # open a netcat server on the 4242 port
# ONLY FOR local connections (127.0.0.1)
(local)$ ssh user@server -L 8000:127.0.0.1:4242 # create the tunnel by
# connecting to server, and redirect his 4242 port to your 8000 port
# Now open a new terminal, but keep the ssh connection open.
(local)$ echo 'Hello, world!' | nc 127.0.0.1 8000
# You will see your message appear on the server's side!
Ok then, when you've understood this principle, this should come clearly that,
for the VNC server that's running on 127.0.0.1:5934, we need the following
tunnel :
:code:`(local)$ ssh <user>@<server.ip> -L 5900:127.0.0.1:5934`
**5900** is the default port for VNC, but you can choose any other one if 5900
is busy on your machine, just change it in the previous command.
Now you can connect to the VNC server, by using the - now standard - tool
"TigerVNC_". Download it from your OS's repositories, or, for Windows, on their
website. Calling TigerVNC this way will directly open the connection :
:code:`(local)$ vncviewer 127.0.0.1:5900`
An X window pops out, and your connected. Then, the following instructions will
depend on the OS you choose to install, if it's a Devuan standard iso install
that you've put into the virtual cd-rom drive of your VM, just follow the steps
as usual, and go to the final step of this how-to.
.. _VNC: https://en.wikipedia.org/wiki/Virtual_Network_Computing
.. _SSH Tunnelling: https://www.ssh.com/ssh/tunneling/
.. _TigerVNC: https://tigervnc.org
---------------------------
Gentoo installation on a VM
---------------------------
With Gentoo, the bootable iso that is provided in the download section of their
website is not a "step by step install", it's just a live OS that contains just
what you need to make an installation. The advantage of this is that, after a
Gentoo install, you will be able to understand what are the different parts of
your OS, and you'll be capable of choosing what is the best for the needs of a
specific machine, even if you don't use Gentoo everytime.
To make the process fast and avoid re-building packages, we'll use a local
binary repository, that is already setup on Freepoteries' host server (that runs
gentoo). This will make us gain a lot of time during installation. If you have
no access to a binary repository, use the standard Gentoo installation handbook.
**Version of Gentoo : 17.1**
Boot
^^^^
When you :code:`virsh start <my_domain>`, the machine will boot on the CD-rom
iso that you defined. For Gentoo's one, there's no automatic boot, you'll then
have to press enter within 10 seconds after boot. To do so, open the VNC window
as fast as possible after the VM starts.
You will see :code:`boot:` prompt waiting for you to press enter, DO SO!
Then, after booting, you will be asked for the keymap to use, **16** is for
**fr**, enter the correct number for your keymap.
SSH
^^^
When the system has booted, check if it is connected to the local network. It
normally should (of course set the IP to the gateway of your local network):
:code:`(vnc)# ping -c 1 192.168.42.1`
If everything's ok, we can begin! If not, contact your local administrator to
see if there is not a networking problem (as no more available IPs in the local
network, or a DHCP server that is missing his duty).
Set a password for root. No, I'm not laughing. Gentoo scrambles the root's
password when booting, that IS security. You can choose an empty password BTW.
:code:`(vnc)# passwd`
It will be more convenient (and less bandwidth consuming) to be connected by
SSH. To do so (I do NOT force you!), just launch SSH, using the OpenRC command
(or **service** if you're an old-timer) :
:code:`(vnc)# rc-service sshd start`
Retrieve your local ip, using the **iproute2** command :
:code:`(vnc)# ip a s`
If you can read this, and that you can find your IP in all these informations,
I think you're ready to work with Gentoo. As a remember, an IPv4 is in the
standard format : a.b.c.d, each of the letters being a number between 0 and 255.
But this is theory, now let's close this VNC window that is consuming all our
networks bandwidth, and let's open a nice SSH connection.
Did I say to remember your IP before closing the VNC window?.
:code:`(server)# ssh root@<vm_ip>`
If **known_hosts** cries about dangerous behaviour, if
so, verifiy the IP and if it's correct, just remove the line of
**~/.ssh/known_hosts** that sets the fingerprint to your VM's IP, and retry the
command.
When you're connected with SSH to the VM, we can begin the real installation!
Hard Disk
'''''''''
Normally, you should have set the hard disk (the one you will use for the OS)
device name to the default one : **vda**. If not change this in the following
commands.
.. code-block:: bash
# let's create the partitions
(my-domain)# fdisk /dev/vda
# delete all existing partitions, if there are with the "d" command"
# now create the new one
n <enter>
p <enter>
1 <enter>
<enter>
<enter>
w <enter>
# create the filesystem
(my-domain)# mkfs.ext4 /dev/vda1
# mount the new "/" partition
(my-domain)# mount /dev/vda1 /mnt/gentoo
OS Installation
'''''''''''''''
.. code-block:: bash
# download the "stage3" archive (retrieve the download link
# on gentoo's download page https://www.gentoo.org/downloads)
wget -O stage3.tar.xz http://distfiles.gentoo.org/releases/amd64/autobuilds/20191106T214502Z/stage3-amd64-20191106T214502Z.tar.xz
# untar (source : https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Stage)
# DON'T FORGET THE "-C /mnt/gentoo" OPTION IF YOU'RE NOT IN THIS DIRECTORY
tar xpvf stage3.tar.xz -C /mnt/gentoo --xattrs-include='*.*' --numeric-owner
# mount the rest of the partitions so you are ready to chroot
(my-domain)# mount -t proc /proc /mnt/gentoo/proc
(my-domain)# mount --rbind /dev /mnt/gentoo/dev
(my-domain)# mount --make-rslave /mnt/gentoo/dev
(my-domain)# mount --rbind /sys /mnt/gentoo/sys
(my-domain)# mount --make-rslave /mnt/gentoo/sys
# chroot into the new system
(my-domain)# chroot /mnt/gentoo
# change portage's options, these are the current ones for Freepoteries, and
# this may change
(my-domain)# cat << EOF >> /etc/portage/make.conf
PORTAGE_BINHOST="http://repo.freepoteries.fr"
FEATURES="getbinpkg"
USE="mmx sse sse2 multilib dlz -X -gtk -sdl -qt -nptl -xpm -gpm -python_targets_python2_7"
ACCEPT_LICENSE="* -@EULA"
EOF
(my-domain)# echo "=sys-boot/grub-2.02-r4 -nls -themes -grub_platforms_efi-64
-efiemu -libzfs -mount -fonts -device-mapper" > /etc/package.use/grub
# emerge the gentoo's latests snapshot - may take time
(my-domain)# emerge-webrsync
# choose the right profile
(my-domain)# eselect profile list
# this should be the same as on the host : 17.1 multilib
(my-domain)# eselect profile set 16
# let's emerge the basic necessary packages (answer yes if everything goes
# well)
(my-domain)# emerge --ask --update --deep --newuse @world
(my-domain)# emerge -aG sys-kernel/gentoo-sources sys-kernel/genkernel sys-boot/grub
# generate the kernel (yes, and this is the most time-consuming)
(my-domain)# genkernel --virtio all
# grub installation
(my-domain)# dispatch-conf
(my-domain)# grub-install /dev/vda
(my-domain)# grub-mkconfig > /boot/grub/grub.cfg
System configuration
''''''''''''''''''''
.. code-block:: bash
# set a root password
(my-domain)# passwd
# fstab
(my-domain)# echo '/dev/vda1 / ext4 defaults,errors=remount-ro,relatime 0 1' > /etc/fstab
# set locale parameters (time and locale)
(my-domain)# echo 'Europe/Paris' > /etc/timezone
(my-domain)# emerge --config sys-libs/timezone-data
(my-domain)# echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
(my-domain)# locale-gen
(my-domain)# eselect locale list
# choose the right locale
(my-domain)# eselect locale 3
(my-domain)# env-update && source /etc/profile
# network
(my-domain)# echo 'hostname="my-domain" > /etc/conf.d/hostname'
(my-domain)# cat << EOF >> /etc/conf.d/net
config_eth0="dhcp"
EOF
(my-domain)# cd /etc/init.d
(my-domain)# ln -s net.lo net.eth0
(my-domain)# rc-update add net.eth0 default
# install a dhcp client
(my-domain)# emerge -G net-misc/dhcpcd
# go back to the live iso
(my-domain)# exit
# and switch it off
(my-domain)# poweroff
-----------------------
Finalization and checks
-----------------------
Now that you're back into the server's prompt, you can edit the VM's
configuration so it can boot on the hard disk. To do so, switch the boot device:
:code:`<boot dev='cdrom'/>`, to :code:`<boot dev='hd'/>`, and save the file.
If you want your machine to have a DHCP static lease, copy in the same time the MAC
address that is located under the **interface** node, at the **address**
attribute of the **mac** node.
:code:`(server)# virsh edit <my_domain>`
DHCP static leases should now execute the following script.
.. code-block:: bash
# this script adds a static lease for a virtual machine within libvirt
# it's advantage is that it do so without having to restart the libvirt
# network management
NAME=<my_domain>
MAC=<your_mac>
IP=<desired_ip>
virsh net-update default add ip-dhcp-host \
"<host mac='${MAC}' \
name='${NAME}' ip='${IP}' />" \
--live --config
# if you wish to use dnsmasq's dns service, execute also the following
virsh net-update default add dns-host \
"<host ip='${3}'> \
<hostname>${1}</hostname> \
</host>" \
--live --config
# you may have to reload the iptables rules if libvirt messes with them
# and if you don't want to restart the machine
cat /etc/network/iptables|iptables-restore
You can now re-start the machine.
:code:`(server)# virsh destroy <my_domain> && virsh start <my_domain>`
If you can ping it's IP (either the static on you choose, or the one the DHCP
server gave her), your machine is now up, and you may be able to log in it,
either via SSH, or as usual with the VNC server!