Why OpenVZ and not XEN.
Disclaimer
Demonstration/Video
This demonstrations is a live screencast done with xvidcap on Linux, it shows how to create a new virtual machine through Proxmox OpenVZ web graphic interface, and then shows how to expose the newly created zone to the outside world with three different mechanisms: ***, port forwarding and reverse proxy. Demo run for about 25mn, its using video flash and hopefully runs smootly on any plateform.My ISP new OpenVZ architecture

Xen is rock solid, but ...
OpenVZ limited but light weight and simple.
- OpenVZ ram is taken from hypervisor global pool (RAM+Swap), when Xen takes RAM from hypervisor physical ram and handles its private swap by virtual machines. Direct result is that with OpenVZ you can allocate more RAM that you effectly have, on the other hand if one zone lack RAM your zone will not expend on swap. In fact OpenVZ refuses to allocate RAM to requesting process, which for most of them translates in a core dump :( As swaping is never a good idea, both methods could finaly look more or less equivalent, this being said the small advantage of OpenVZ strategy is that it is easier to share unused RAM in between differents zones, which may have some important for cheap hosting configuration where RAM is limited.
- OpenVZ zones and hyperviseur share the same kernel, as a result some functions fails (ex: changing system time) while this should not be an issue, it breaks more scripts than it should :(
- No boot console is a real bad point for OpenVZ. It makes template creation complex. In fact you have no idea of what happen until you can access to your system, which obvisouly never happen when boot fail :( The fact you can access any given zone logs directly from the hyperviseur through /vz/private/zone-id directory makes debug possible, but far less simple than with a full boot console as provided by Xen. Note that some distributions like Debian will write into your VM /var/log/init.log the trace of your boot sequence, unfortunatly this is not working on ever distribution, Ubuntu being one of them.
- A snoopable network interface, this is a very good point for OpenVZ. While Xen also allows to snoop your network interface with TCPdump or Wireshark, Solaris zones does not support it. Snooping network interfaces is a key feature for debugging any network infrastructure and almost mandatory to understand what happen when your hosting configuration is not working.
- A share filesystem, the main advantage is that you can access directly to any zone private disk from the hypervisor, the limit is that you cannot leverage a SAN interface directly from the zone as under xen with ISCSI. This being said for cheap hosting OpenVZ option is a better choice.
- Proxmox web GUI, while this is not OpenVZ as it, it is shipped standard and allows you to create/manage your virtual machines in a very nice and intuitive way.Further more Proxmox provide a list of appliances that you can download from ftp://pve.proxmox.com/appliances this allow you to install drupla, joomla as well as many other nice tool in a mater of seconds, nice isn't it ?
Fridu OpenVZ networking config
# Zones definition # ----------------- IP_ONE=91.121.173.80 IP_TWO=87.98.139.141 CreateZone NAME=zOne NIC=eth0 EXT=$IP_ONE BR=venet0 INT=10.10.101.0 MASK=255.255.255.0 CreateZone NAME=zTwo NIC=eth0 EXT=$IP_TWO BR=venet0 INT=10.10.102.0 MASK=255.255.255.0 |
- Port TCP/22 for SSH
- Port TCP/80 and 443 for HTTP/HTTPS
- Port 5900 is used by VNCterm to provide console thought VNC applet.
- Port UDP/44096 andTCP/453 for Open×××
# Application Port & Forwarding (default ACCEPT = none) # ------------------------------------------------------ CreateApp NAME=DOM0_SSH ZONE=none EXT=tcp:22 INT=eth0 ;# ssh Fridu.net goes to dom0 CreateApp NAME=DOM0_WWW ZONE=none EXT=tcp:80 INT=eth0 ;# https need for promox console CreateApp NAME=DOM0_SSL ZONE=none EXT=tcp:443 INT=eth0 ;# https need for promox console CreateApp NAME=DOM0_VNCt ZONE=none EXT=tcp:5900 INT=eth0 ;# Virtual Machine console through ×××c CreateApp NAME=DOM0_×××t ZONE=none EXT=tcp:563 INT=eth0 ;# Open××× in TCP CreateApp NAME=DOM0_×××u ZONE=none EXT=udp:44096 INT=eth0 ;# check User Custom Rules later |
# map external mail SMPT to Mail zone port 2525 to seperate from local traffic that arrive through ××× on port 25 CreateApp NAME=Mail_SMTP ZONE=zOne EXT=tcp:25 INT=10.10.101.1:2525 CreateApp NAME=Mail_IMAP ZONE=zOne EXT=tcp:993 INT=10.10.101.1:993 # Any traffic coming from IP-TWO/port 80 is redirected to 10.10.102.2 CreateApp NAME=Domi_WEB ZONE=zTwo EXT=tcp:80 INT=10.10.102.2:80 # Allow SSH and HTTP direct mapping for 10.10.101.5 CreateApp NAME=SSO_SSH ZONE=zOne EXT=tcp:2215 INT=10.10.101.5:22 CreateApp NAME=SSO_WWW ZONE=zOne EXT=tcp:8015 INT=10.10.101.5:80 CreateApp NAME=SSO_TOM ZONE=zOne EXT=tcp:8115 INT=10.10.101.5:8180 |
- FTP one is only required if you want FTP to work in passive mode, which is often the case.
- Second one is almost mandatory, (tun+/vnet+) allow ××× to reach any zone directly, while (vnet+/vnet+) allows zone to zone connection. If you run a share ××× you MUST have tun+/vnet+, while vnet+/vnet+ might only be needed if one zone runs a service shared by other, example LDAP, DNS, ...
- Last one is an hugely hack that allow my TCP *** on port 563 to be viewed as sitting on port 443 when targeting my IP-TWO. This allow me to have HTTPS/IP-ONE and ×××/IP-TWO when both share the same port and the same external interface (eth0)
# User Before/After Zone Custom Tables (before-input|output|forwarding, after-input|...) # ---------------------------------------------------------------------------------- if test "$ACTION" = "start" ; then # DoIt modprobe -s ip_conntrack_ftp # load FTP session tacking # we're not a bank make our life simple DoIt iptables -A after-forwarding -i venet+ -o venet+ -j ACCEPT # allow VM to talk together DoIt iptables -A after-input -i tun+ -j ACCEPT # allow ××× talk to dom0 DoIt iptables -A after-forwarding -i tun+ -o venet+ -j ACCEPT # allow ××× talk to zones DoIt iptables -A after-forwarding -i venet+ -o tun+ -j ACCEPT # allow Zones talk to ××× # Make SSL on IP-two to be redirected on port 563 DoIt iptables -A PREROUTING -t nat -i eth0 --destination 87.98.139.141 --proto tcp --dport 443 -j DNAT --to 91.121.173.80:563 fi |
Download Fridu firewall
My Reverse proxy configuration.
- 1st define a listen IP-ADDR/Port for your reverse proxy
- 2nd define your services, with as input your DNS name as known by external internet users, and as output your OpenVZ internal zone + port.
## redirect all requests on port 8080 ("ListenHTTP") to the local webserver (see "Service" below):
ListenHTTP Address 91.121.173.80 Port 80
# my services definition
Service
HeadRequire "Host:.*www.fridu.net.*" BackEnd Address vz-opensso Port 8180 End End Service HeadRequire "Host:.*zxid.fridu.net.*" BackEnd Address vz-opensso Port 81 End End End |
Dnsmaq a small domain named server.
root@ks362337:~# cat /etc/dnsmasq.conf # Configuration file for dnsmasq. # "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. # Domain anything you want but "local" or client will request mdns domain=*** expand-hosts # Never forward names without a dot or domain part bogus-priv # /etc/resolv.conf is static, no monitoring needed no-poll # Do not listen eth0 except-interface=eth0 |
root@vz-fulup:~# cat /etc/resolv.conf search ovh.net nameserver YOUR_HYPERVISOR-IP nameserver 127.0.0.1 |
Open×××
Proxmox web frontend console
ps -ef | grep vncterm
/usr/bin/vncterm -rfbport 5900 -passwdfile rm:/tmp/.vncpwfile.7355 -timeout 1 -c /usr/sbin/vzctl enter 101
|
Limitations, bugs and tips.
- No /dev/tty -> "vzctl exec MY-VIRTUAL-MACHINE-ID mknod /dev/tty c 5 0"
- No /dev/random -> "vzctl exec MY-VIRTUAL-MACHINE-ID mknod /dev/random c 1 8"
- No /dev/console
- When checking processes list on the hypervisor with "ps -ef" you see every processes, including the one running on VMs. As a result a "pkill -9 apache2" at hypervisor level will kill every single apache running on every VMs. Needs to be know
- If a VM restart fails (ex: you messed up network config, break some init script, not enough RAM, ....). While obviously you cannot log on your broken VM !!! You can still try to enter the VM from the hypervisor with "vzctl enter VM-ID" command. Example: your "syslogd" did not start, as this the1st process to be started by init-rc, it locks everything else and especially "sshd" which is usually the second one to be started. As you have no SSHD you cannot connect with SSH, obvious isn't it ? You can then use the "vzctl enter VM-ID" doing a "ps -ef" you should see a pocess like "/etc/init/rc 2" as init is not finished. You can then restart your syslogd with "/etc/init.d/sysklogd" or what ever is necessary to fix your problem.
- if you can reach a VM from the outside, but cannot reach internet from that VM, then you need to check your "CreateZone" rule. Double check that your network mask is compliant with your VM local IP adresse. Example (createZone ... EXT=IP1 INT=10.10.1.0 MASK=255.255.255.0) will map any VMs with local IP 10.10.1.xxx in IP1, when (createZone ... EXT=IP2 INT=10.10.1.2 MASK=255.255.255.255) will only map 10.10.1.2 inside IP2. Note network differences with MASK and INT with/without zero at the end. Zone network mask defines outgoing policies, and a wrong definition will not impact incoming requests, but will prevent outgoing requests to work.
- when learning how to handle multiple public IP addresses, to forward a dedicated intenet port from a specific pubic IP to an internal VM's IP/port, do not start with port "22" but with something less critical like 80 or 25. An error on port "22" may prevent SSH access to your hypervisor, forcing you to reboot your full server to gain back SSH access. The other good practice is to launch a batch that will stop your firewall automatically after 10mn "(sleep 600; Fridu-firewall.script stop)& Fridu-firewall.script start)" like than even if you kill your SSH access, it is only for 10mn